summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore8
-rw-r--r--linux/Documentation/dvb/get_dvb_firmware23
-rw-r--r--linux/Documentation/video4linux/CARDLIST.cx881
-rw-r--r--linux/Documentation/video4linux/CARDLIST.saa71343
-rw-r--r--linux/Documentation/video4linux/CARDLIST.tuner1
-rw-r--r--linux/drivers/media/common/saa7146_core.c6
-rw-r--r--linux/drivers/media/common/saa7146_fops.c18
-rw-r--r--linux/drivers/media/common/saa7146_i2c.c4
-rw-r--r--linux/drivers/media/common/saa7146_vbi.c2
-rw-r--r--linux/drivers/media/common/saa7146_video.c30
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-common.h11
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-i2c.c6
-rw-r--r--linux/drivers/media/dvb/bt8xx/bt878.c48
-rw-r--r--linux/drivers/media/dvb/bt8xx/bt878.h28
-rw-r--r--linux/drivers/media/dvb/bt8xx/dst.c14
-rw-r--r--linux/drivers/media/dvb/bt8xx/dst_ca.c6
-rw-r--r--linux/drivers/media/dvb/bt8xx/dst_common.h8
-rw-r--r--linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c19
-rw-r--r--linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h8
-rw-r--r--linux/drivers/media/dvb/cinergyT2/cinergyT2.c53
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.c86
-rw-r--r--linux/drivers/media/dvb/dvb-core/dmxdev.h13
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_demux.c104
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_demux.h9
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c13
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.c19
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Kconfig12
-rw-r--r--linux/drivers/media/dvb/dvb-usb/cxusb.c8
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dibusb-common.c4
-rw-r--r--linux/drivers/media/dvb/dvb-usb/digitv.c17
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c4
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-urb.c4
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb.h20
-rw-r--r--linux/drivers/media/dvb/dvb-usb/vp702x.c4
-rw-r--r--linux/drivers/media/dvb/dvb-usb/vp7045-fe.c6
-rw-r--r--linux/drivers/media/dvb/dvb-usb/vp7045.c4
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig12
-rw-r--r--linux/drivers/media/dvb/frontends/Makefile2
-rw-r--r--linux/drivers/media/dvb/frontends/bcm3510.c16
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.c18
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.c25
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.h3
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.c37
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110.h19
-rw-r--r--linux/drivers/media/dvb/ttpci/av7110_hw.c40
-rw-r--r--linux/drivers/media/dvb/ttpci/budget.h9
-rw-r--r--linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c36
-rw-r--r--linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c42
-rw-r--r--linux/drivers/media/video/Makefile2
-rw-r--r--linux/drivers/media/video/bttv-driver.c50
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.c50
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c39
-rw-r--r--linux/drivers/media/video/cx88/cx88-core.c2
-rw-r--r--linux/drivers/media/video/cx88/cx88-input.c1
-rw-r--r--linux/drivers/media/video/cx88/cx88-video.c26
-rw-r--r--linux/drivers/media/video/cx88/cx88.h11
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-cards.c18
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-core.c15
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-i2c.c9
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-video.c124
-rw-r--r--linux/drivers/media/video/em28xx/em28xx.h7
-rw-r--r--linux/drivers/media/video/saa6588.c10
-rw-r--r--linux/drivers/media/video/saa711x.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-alsa.c6
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c100
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c83
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-empress.c8
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-input.c5
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-oss.c40
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-video.c40
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h14
-rw-r--r--linux/drivers/media/video/tda8290.c8
-rw-r--r--linux/drivers/media/video/tda9887.c7
-rw-r--r--linux/drivers/media/video/tuner-core.c9
-rw-r--r--linux/drivers/media/video/tuner-types.c21
-rw-r--r--linux/drivers/media/video/tvp5150.c2
-rw-r--r--linux/drivers/media/video/video-buf-dvb.c10
-rw-r--r--linux/drivers/media/video/video-buf.c42
-rw-r--r--linux/drivers/media/video/videodev.c6
-rw-r--r--linux/drivers/media/video/xc3028.c236
-rw-r--r--linux/include/linux/videodev2.h12
-rw-r--r--linux/include/media/saa7146.h33
-rw-r--r--linux/include/media/tuner.h3
-rw-r--r--linux/include/media/video-buf-dvb.h4
-rw-r--r--linux/include/media/video-buf.h4
-rw-r--r--linux/sound/pci/bt87x.c4
-rw-r--r--v4l/Make.config4
-rw-r--r--v4l/Makefile19
-rw-r--r--v4l/compat.h1
-rwxr-xr-xv4l/scripts/makelinks.sh11
-rw-r--r--v4l_experimental/firesat/Kconfig11
-rw-r--r--v4l_experimental/firesat/Makefile11
-rw-r--r--v4l_experimental/firesat/avc_api.c953
-rw-r--r--v4l_experimental/firesat/avc_api.h435
-rw-r--r--v4l_experimental/firesat/cmp.c176
-rw-r--r--v4l_experimental/firesat/cmp.h9
-rw-r--r--v4l_experimental/firesat/firesat-ci.c124
-rw-r--r--v4l_experimental/firesat/firesat-ci.h9
-rw-r--r--v4l_experimental/firesat/firesat-rc.c83
-rw-r--r--v4l_experimental/firesat/firesat-rc.h9
-rw-r--r--v4l_experimental/firesat/firesat.c917
-rw-r--r--v4l_experimental/firesat/firesat.h72
-rw-r--r--v4l_experimental/xc3028/convert.c7
104 files changed, 4218 insertions, 581 deletions
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 000000000..2d7248488
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,8 @@
+v4l/.version
+v4l/.tmp_versions/.*
+v4l/[^/]*[.]c
+v4l/.*[.]o
+v4l/.*[.]ko
+.*[.]rej
+.*[.]orig
+.*[~]
diff --git a/linux/Documentation/dvb/get_dvb_firmware b/linux/Documentation/dvb/get_dvb_firmware
index 75c28a174..bb55f49f2 100644
--- a/linux/Documentation/dvb/get_dvb_firmware
+++ b/linux/Documentation/dvb/get_dvb_firmware
@@ -21,8 +21,9 @@
use File::Temp qw/ tempdir /;
use IO::Handle;
-@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
- "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
+@components = ( "sp8870", "sp887x", "tda10045", "tda10046",
+ "tda10046lifeview", "av7110", "dec2000t", "dec2540t",
+ "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb", "bluebird");
# Check args
@@ -126,6 +127,24 @@ sub tda10046 {
$outfile;
}
+sub tda10046lifeview {
+ my $sourcefile = "Drv_2.11.02.zip";
+ my $url = "http://www.lifeview.com.tw/drivers/pci_card/FlyDVB-T/$sourcefile";
+ my $hash = "1ea24dee4eea8fe971686981f34fd2e0";
+ my $outfile = "dvb-fe-tda10046.fw";
+ my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+ checkstandard();
+
+ wgetfile($sourcefile, $url);
+ unzip($sourcefile, $tmpdir);
+ extract("$tmpdir/LVHybrid.sys", 0x8b088, 24602, "$tmpdir/fwtmp");
+ verify("$tmpdir/fwtmp", $hash);
+ copy("$tmpdir/fwtmp", $outfile);
+
+ $outfile;
+}
+
sub av7110 {
my $sourcefile = "dvb-ttpci-01.fw-261d";
my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile";
diff --git a/linux/Documentation/video4linux/CARDLIST.cx88 b/linux/Documentation/video4linux/CARDLIST.cx88
index 8bea3fbd0..d852ad4f9 100644
--- a/linux/Documentation/video4linux/CARDLIST.cx88
+++ b/linux/Documentation/video4linux/CARDLIST.cx88
@@ -43,3 +43,4 @@
42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025]
43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1]
44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50,18ac:db54]
+ 45 -> KWorld HardwareMpegTV XPert [17de:0840]
diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134
index 636792e2e..c10cfd26d 100644
--- a/linux/Documentation/video4linux/CARDLIST.saa7134
+++ b/linux/Documentation/video4linux/CARDLIST.saa7134
@@ -84,3 +84,6 @@
83 -> Terratec Cinergy 250 PCI TV [153b:1160]
84 -> LifeView FlyDVB Trio [5168:0319]
85 -> AverTV DVB-T 777 [1461:2c05]
+ 86 -> LifeView FlyDVB-T [5168:0301]
+ 87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421]
+ 88 -> Tevion DVB-T 220RF [17de:7201]
diff --git a/linux/Documentation/video4linux/CARDLIST.tuner b/linux/Documentation/video4linux/CARDLIST.tuner
index f6d0cf7b7..de48438d5 100644
--- a/linux/Documentation/video4linux/CARDLIST.tuner
+++ b/linux/Documentation/video4linux/CARDLIST.tuner
@@ -69,3 +69,4 @@ tuner=67 - Philips TD1316 Hybrid Tuner
tuner=68 - Philips TUV1236D ATSC/NTSC dual in
tuner=69 - Tena TNF 5335 MF
tuner=70 - Samsung TCPN 2121P30A
+tuner=71 - Xceive xc3028
diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c
index 86d5acab3..71a5f1329 100644
--- a/linux/drivers/media/common/saa7146_core.c
+++ b/linux/drivers/media/common/saa7146_core.c
@@ -21,7 +21,7 @@
#include <media/saa7146.h>
LIST_HEAD(saa7146_devices);
-DECLARE_MUTEX(saa7146_devices_lock);
+DEFINE_MUTEX(saa7146_devices_lock);
static int saa7146_num;
@@ -402,11 +402,11 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
pci_set_drvdata(pci, dev);
- init_MUTEX(&dev->lock);
+ mutex_init(&dev->lock);
spin_lock_init(&dev->int_slock);
spin_lock_init(&dev->slock);
- init_MUTEX(&dev->i2c_lock);
+ mutex_init(&dev->i2c_lock);
dev->module = THIS_MODULE;
init_waitqueue_head(&dev->i2c_wq);
diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c
index 3396e399a..480a34a26 100644
--- a/linux/drivers/media/common/saa7146_fops.c
+++ b/linux/drivers/media/common/saa7146_fops.c
@@ -18,18 +18,18 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
}
/* is it free? */
- down(&dev->lock);
+ mutex_lock(&dev->lock);
if (vv->resources & bit) {
DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
/* no, someone else uses it */
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
vv->resources |= bit;
DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 1;
}
@@ -41,11 +41,11 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
if ((fh->resources & bits) != bits)
BUG();
- down(&dev->lock);
+ mutex_lock(&dev->lock);
fh->resources &= ~bits;
vv->resources &= ~bits;
DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
}
@@ -205,7 +205,7 @@ static int fops_open(struct inode *inode, struct file *file)
DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor));
- if (down_interruptible(&saa7146_devices_lock))
+ if (mutex_lock_interruptible(&saa7146_devices_lock))
return -ERESTARTSYS;
list_for_each(list,&saa7146_devices) {
@@ -277,7 +277,7 @@ out:
kfree(fh);
file->private_data = NULL;
}
- up(&saa7146_devices_lock);
+ mutex_unlock(&saa7146_devices_lock);
return result;
}
@@ -288,7 +288,7 @@ static int fops_release(struct inode *inode, struct file *file)
DEB_EE(("inode:%p, file:%p\n",inode,file));
- if (down_interruptible(&saa7146_devices_lock))
+ if (mutex_lock_interruptible(&saa7146_devices_lock))
return -ERESTARTSYS;
if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
@@ -304,7 +304,7 @@ static int fops_release(struct inode *inode, struct file *file)
file->private_data = NULL;
kfree(fh);
- up(&saa7146_devices_lock);
+ mutex_unlock(&saa7146_devices_lock);
return 0;
}
diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c
index cdc4a6efc..b87dfe8df 100644
--- a/linux/drivers/media/common/saa7146_i2c.c
+++ b/linux/drivers/media/common/saa7146_i2c.c
@@ -280,7 +280,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, in
int address_err = 0;
int short_delay = 0;
- if (down_interruptible (&dev->i2c_lock))
+ if (mutex_lock_interruptible(&dev->i2c_lock))
return -ERESTARTSYS;
for(i=0;i<num;i++) {
@@ -367,7 +367,7 @@ out:
}
}
- up(&dev->i2c_lock);
+ mutex_unlock(&dev->i2c_lock);
return err;
}
diff --git a/linux/drivers/media/common/saa7146_vbi.c b/linux/drivers/media/common/saa7146_vbi.c
index 821503fca..3d403a760 100644
--- a/linux/drivers/media/common/saa7146_vbi.c
+++ b/linux/drivers/media/common/saa7146_vbi.c
@@ -411,7 +411,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
sizeof(struct saa7146_buf),
file);
- init_MUTEX(&fh->vbi_q.lock);
+ mutex_init(&fh->vbi_q.lock);
init_timer(&fh->vbi_read_timeout);
fh->vbi_read_timeout.function = vbi_read_timeout;
diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c
index 68d777bdf..4f1ccaee7 100644
--- a/linux/drivers/media/common/saa7146_video.c
+++ b/linux/drivers/media/common/saa7146_video.c
@@ -379,20 +379,20 @@ static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
err = try_win(dev,&f->fmt.win);
if (0 != err)
return err;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
fh->ov.win = f->fmt.win;
fh->ov.nclips = f->fmt.win.clipcount;
if (fh->ov.nclips > 16)
fh->ov.nclips = 16;
if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return -EFAULT;
}
/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
fh->ov.fh = fh;
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
/* check if our current overlay is active */
if (IS_OVERLAY_ACTIVE(fh) != 0) {
@@ -517,7 +517,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
return -EINVAL;
}
- down(&dev->lock);
+ mutex_lock(&dev->lock);
switch (ctrl->type) {
case V4L2_CTRL_TYPE_BOOLEAN:
@@ -561,7 +561,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
/* fixme: we can support changing VFLIP and HFLIP here... */
if (IS_CAPTURE_ACTIVE(fh) != 0) {
DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return -EINVAL;
}
vv->hflip = c->value;
@@ -569,7 +569,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
case V4L2_CID_VFLIP:
if (IS_CAPTURE_ACTIVE(fh) != 0) {
DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return -EINVAL;
}
vv->vflip = c->value;
@@ -578,7 +578,7 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
return -EINVAL;
}
}
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
if (IS_OVERLAY_ACTIVE(fh) != 0) {
saa7146_stop_preview(fh);
@@ -940,7 +940,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
}
}
- down(&dev->lock);
+ mutex_lock(&dev->lock);
/* ok, accept it */
vv->ov_fb = *fb;
@@ -949,7 +949,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
vv->ov_fb.fmt.bytesperline =
vv->ov_fb.fmt.width*fmt->depth/8;
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -1087,7 +1087,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
}
}
- down(&dev->lock);
+ mutex_lock(&dev->lock);
for(i = 0; i < dev->ext_vv_data->num_stds; i++)
if (*id & dev->ext_vv_data->stds[i].id)
@@ -1099,7 +1099,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
found = 1;
}
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
if (vv->ov_suspend != NULL) {
saa7146_start_preview(vv->ov_suspend);
@@ -1202,11 +1202,11 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
DEB_D(("VIDIOCGMBUF \n"));
q = &fh->video_q;
- down(&q->lock);
+ mutex_lock(&q->lock);
err = videobuf_mmap_setup(q,gbuffers,gbufsize,
V4L2_MEMORY_MMAP);
if (err < 0) {
- up(&q->lock);
+ mutex_unlock(&q->lock);
return err;
}
memset(mbuf,0,sizeof(*mbuf));
@@ -1214,7 +1214,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
mbuf->size = gbuffers * gbufsize;
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
- up(&q->lock);
+ mutex_unlock(&q->lock);
return 0;
}
default:
@@ -1415,7 +1415,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
sizeof(struct saa7146_buf),
file);
- init_MUTEX(&fh->video_q.lock);
+ mutex_init(&fh->video_q.lock);
return 0;
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-common.h b/linux/drivers/media/dvb/b2c2/flexcop-common.h
index 7d7e1613c..6162c04bd 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/linux/drivers/media/dvb/b2c2/flexcop-common.h
@@ -10,6 +10,10 @@
#include <linux/config.h>
#include <linux/pci.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "flexcop-reg.h"
@@ -73,8 +77,11 @@ struct flexcop_device {
int (*fe_sleep) (struct dvb_frontend *);
struct i2c_adapter i2c_adap;
- struct semaphore i2c_sem;
-
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex i2c_mutex;
+#else
+ struct semaphore i2c_mutex;
+#endif
struct module *owner;
/* options and status */
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c
index 56495cb6c..e0bd2d8f0 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -135,7 +135,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
struct flexcop_device *fc = i2c_get_adapdata(i2c_adap);
int i, ret = 0;
- if (down_interruptible(&fc->i2c_sem))
+ if (mutex_lock_interruptible(&fc->i2c_mutex))
return -ERESTARTSYS;
/* reading */
@@ -161,7 +161,7 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
else
ret = num;
- up(&fc->i2c_sem);
+ mutex_unlock(&fc->i2c_mutex);
return ret;
}
@@ -180,7 +180,7 @@ int flexcop_i2c_init(struct flexcop_device *fc)
{
int ret;
- sema_init(&fc->i2c_sem,1);
+ mutex_init(&fc->i2c_mutex);
memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE);
diff --git a/linux/drivers/media/dvb/bt8xx/bt878.c b/linux/drivers/media/dvb/bt8xx/bt878.c
index a04bb61f2..d276ce6b3 100644
--- a/linux/drivers/media/dvb/bt8xx/bt878.c
+++ b/linux/drivers/media/dvb/bt8xx/bt878.c
@@ -344,7 +344,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
int retval;
retval = 0;
- if (down_interruptible (&bt->gpio_lock))
+ if (mutex_lock_interruptible(&bt->gpio_lock))
return -ERESTARTSYS;
/* special gpio signal */
switch (cmd) {
@@ -375,12 +375,29 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
retval = -EINVAL;
break;
}
- up(&bt->gpio_lock);
+ mutex_unlock(&bt->gpio_lock);
return retval;
}
EXPORT_SYMBOL(bt878_device_control);
+
+struct cards card_list[] __devinitdata = {
+
+ { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
+ { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
+ { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
+ { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
+ { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
+ { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
+ { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
+ { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
+ { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
+ { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
+ { 0, -1, NULL }
+};
+
+
/***********************/
/* PCI device handling */
/***********************/
@@ -388,18 +405,41 @@ EXPORT_SYMBOL(bt878_device_control);
static int __devinit bt878_probe(struct pci_dev *dev,
const struct pci_device_id *pci_id)
{
- int result;
+ int result = 0, has_dvb = 0, i;
unsigned char lat;
struct bt878 *bt;
#if defined(__powerpc__)
unsigned int cmd;
#endif
+ unsigned int cardid;
+ unsigned short id;
+ struct cards *dvb_cards;
printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
bt878_num);
if (pci_enable_device(dev))
return -EIO;
+ pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id);
+ cardid = id << 16;
+ pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id);
+ cardid |= id;
+
+ for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) {
+ if (cardid == dvb_cards->pci_id) {
+ printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n",
+ __func__, cardid, dvb_cards->name);
+ has_dvb = 1;
+ }
+ }
+
+ if (!has_dvb) {
+ printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid);
+ result = -EINVAL;
+
+ goto fail0;
+ }
+
bt = &bt878[bt878_num];
bt->dev = dev;
bt->nr = bt878_num;
@@ -416,6 +456,8 @@ static int __devinit bt878_probe(struct pci_dev *dev,
pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+
+
printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
bt878_num, bt->id, bt->revision, dev->bus->number,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
diff --git a/linux/drivers/media/dvb/bt8xx/bt878.h b/linux/drivers/media/dvb/bt8xx/bt878.h
index a73baf00c..af93f78ee 100644
--- a/linux/drivers/media/dvb/bt8xx/bt878.h
+++ b/linux/drivers/media/dvb/bt8xx/bt878.h
@@ -25,6 +25,11 @@
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
+
#include "bt848.h"
#include "bttv.h"
@@ -88,10 +93,31 @@
#define BT878_RISC_SYNC_MASK (1 << 15)
+
+#define BTTV_BOARD_UNKNOWN 0x00
+#define BTTV_BOARD_PINNACLESAT 0x5e
+#define BTTV_BOARD_NEBULA_DIGITV 0x68
+#define BTTV_BOARD_PC_HDTV 0x70
+#define BTTV_BOARD_TWINHAN_DST 0x71
+#define BTTV_BOARD_AVDVBT_771 0x7b
+#define BTTV_BOARD_AVDVBT_761 0x7c
+#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
+#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
+
+struct cards {
+ __u32 pci_id;
+ __u16 card_id;
+ char *name;
+};
+
extern int bt878_num;
struct bt878 {
- struct semaphore gpio_lock;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex gpio_lock;
+#else
+ struct semaphore gpio_lock;
+#endif
unsigned int nr;
unsigned int bttv_nr;
struct i2c_adapter *adapter;
diff --git a/linux/drivers/media/dvb/bt8xx/dst.c b/linux/drivers/media/dvb/bt8xx/dst.c
index 3a2ff1cc2..d800df121 100644
--- a/linux/drivers/media/dvb/bt8xx/dst.c
+++ b/linux/drivers/media/dvb/bt8xx/dst.c
@@ -910,7 +910,7 @@ static int dst_get_device_id(struct dst_state *state)
static int dst_probe(struct dst_state *state)
{
- sema_init(&state->dst_mutex, 1);
+ mutex_init(&state->dst_mutex);
if ((rdc_8820_reset(state)) < 0) {
dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
return -1;
@@ -962,7 +962,7 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
{
u8 reply;
- down(&state->dst_mutex);
+ mutex_lock(&state->dst_mutex);
if ((dst_comm_init(state)) < 0) {
dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
goto error;
@@ -1013,11 +1013,11 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
dprintk(verbose, DST_INFO, 1, "checksum failure");
goto error;
}
- up(&state->dst_mutex);
+ mutex_unlock(&state->dst_mutex);
return 0;
error:
- up(&state->dst_mutex);
+ mutex_unlock(&state->dst_mutex);
return -EIO;
}
@@ -1128,7 +1128,7 @@ static int dst_write_tuna(struct dvb_frontend *fe)
dst_set_voltage(fe, SEC_VOLTAGE_13);
}
state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
- down(&state->dst_mutex);
+ mutex_lock(&state->dst_mutex);
if ((dst_comm_init(state)) < 0) {
dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
goto error;
@@ -1160,11 +1160,11 @@ static int dst_write_tuna(struct dvb_frontend *fe)
state->diseq_flags |= ATTEMPT_TUNE;
retval = dst_get_tuna(state);
werr:
- up(&state->dst_mutex);
+ mutex_unlock(&state->dst_mutex);
return retval;
error:
- up(&state->dst_mutex);
+ mutex_unlock(&state->dst_mutex);
return -EIO;
}
diff --git a/linux/drivers/media/dvb/bt8xx/dst_ca.c b/linux/drivers/media/dvb/bt8xx/dst_ca.c
index ad3970505..fee27d58b 100644
--- a/linux/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/linux/drivers/media/dvb/bt8xx/dst_ca.c
@@ -81,7 +81,7 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
{
u8 reply;
- down(&state->dst_mutex);
+ mutex_lock(&state->dst_mutex);
dst_comm_init(state);
msleep(65);
@@ -110,11 +110,11 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
goto error;
}
}
- up(&state->dst_mutex);
+ mutex_unlock(&state->dst_mutex);
return 0;
error:
- up(&state->dst_mutex);
+ mutex_unlock(&state->dst_mutex);
return -EIO;
}
diff --git a/linux/drivers/media/dvb/bt8xx/dst_common.h b/linux/drivers/media/dvb/bt8xx/dst_common.h
index 81557f38f..251c172e4 100644
--- a/linux/drivers/media/dvb/bt8xx/dst_common.h
+++ b/linux/drivers/media/dvb/bt8xx/dst_common.h
@@ -25,6 +25,10 @@
#include <linux/smp_lock.h>
#include <linux/dvb/frontend.h>
#include <linux/device.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "bt878.h"
#include "dst_ca.h"
@@ -121,7 +125,11 @@ struct dst_state {
u8 vendor[8];
u8 board_info[8];
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex dst_mutex;
+#else
struct semaphore dst_mutex;
+#endif
};
struct dst_types {
diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 0183dc607..9db352157 100644
--- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -77,13 +77,13 @@ static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
if (!dvbdmx->dmx.frontend)
return -EINVAL;
- down(&card->lock);
+ mutex_lock(&card->lock);
card->nfeeds++;
rc = card->nfeeds;
if (card->nfeeds == 1)
bt878_start(card->bt, card->gpio_mode,
card->op_sync_orin, card->irq_err_ignore);
- up(&card->lock);
+ mutex_unlock(&card->lock);
return rc;
}
@@ -97,11 +97,11 @@ static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
if (!dvbdmx->dmx.frontend)
return -EINVAL;
- down(&card->lock);
+ mutex_lock(&card->lock);
card->nfeeds--;
if (card->nfeeds == 0)
bt878_stop(card->bt);
- up(&card->lock);
+ mutex_unlock(&card->lock);
return 0;
}
@@ -796,7 +796,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
return -ENOMEM;
- init_MUTEX(&card->lock);
+ mutex_init(&card->lock);
card->bttv_nr = sub->core->nr;
strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
card->i2c_adapter = &sub->core->i2c_adap;
@@ -889,7 +889,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
return -EFAULT;
}
- init_MUTEX(&card->bt->gpio_lock);
+ mutex_init(&card->bt->gpio_lock);
card->bt->bttv_nr = sub->core->nr;
if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
@@ -908,7 +908,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
static int dvb_bt8xx_remove(struct device *dev)
#else
-static int dvb_bt8xx_remove(struct bttv_sub_device *sub)
+static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
#endif
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
@@ -931,8 +931,9 @@ static int dvb_bt8xx_remove(struct bttv_sub_device *sub)
dvb_unregister_adapter(&card->dvb_adapter);
kfree(card);
-
- return 0;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15)
+ return (0);
+#endif
}
static struct bttv_sub_driver driver = {
diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index cf035a803..9992d1071 100644
--- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -26,6 +26,10 @@
#define DVB_BT8XX_H
#include <linux/i2c.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "dvbdev.h"
#include "dvb_net.h"
#include "bttv.h"
@@ -38,7 +42,11 @@
#include "lgdt330x.h"
struct dvb_bt8xx_card {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock;
+#else
struct semaphore lock;
+#endif
int nfeeds;
char card_name[32];
struct dvb_adapter dvb_adapter;
diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c
index ec1f39f1d..10ed8b8c0 100644
--- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -30,8 +30,11 @@
#include <linux/pci.h>
#include <linux/input.h>
#include <linux/dvb/frontend.h>
-
#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
+
#include "dmxdev.h"
#include "dvb_demux.h"
#include "dvb_net.h"
@@ -127,7 +130,11 @@ static struct dvb_frontend_info cinergyt2_fe_info = {
struct cinergyt2 {
struct dvb_demux demux;
struct usb_device *udev;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex sem;
+#else
struct semaphore sem;
+#endif
struct dvb_adapter adapter;
struct dvb_device *fedev;
struct dmxdev dmxdev;
@@ -356,14 +363,14 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
struct dvb_demux *demux = dvbdmxfeed->demux;
struct cinergyt2 *cinergyt2 = demux->priv;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
if (cinergyt2->streaming == 0)
cinergyt2_start_stream_xfer(cinergyt2);
cinergyt2->streaming++;
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return 0;
}
@@ -372,13 +379,13 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
struct dvb_demux *demux = dvbdmxfeed->demux;
struct cinergyt2 *cinergyt2 = demux->priv;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
if (--cinergyt2->streaming == 0)
cinergyt2_stop_stream_xfer(cinergyt2);
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return 0;
}
@@ -494,11 +501,11 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
struct cinergyt2 *cinergyt2 = dvbdev->priv;
int err = -ERESTARTSYS;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
if ((err = dvb_generic_open(inode, file))) {
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return err;
}
@@ -510,7 +517,7 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
atomic_inc(&cinergyt2->inuse);
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return 0;
}
@@ -528,7 +535,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct cinergyt2 *cinergyt2 = dvbdev->priv;
- if (down_interruptible(&cinergyt2->sem))
+ if (mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
@@ -537,7 +544,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
cinergyt2_sleep(cinergyt2, 1);
}
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) {
warn("delayed unregister in release");
@@ -552,12 +559,12 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
struct dvb_device *dvbdev = file->private_data;
struct cinergyt2 *cinergyt2 = dvbdev->priv;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
poll_wait(file, &cinergyt2->poll_wq, wait);
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return (POLLIN | POLLRDNORM | POLLPRI);
}
@@ -624,7 +631,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
if (copy_from_user(&p, (void __user*) arg, sizeof(p)))
return -EFAULT;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -640,7 +647,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
(char *) param, sizeof(*param),
NULL, 0);
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return (err < 0) ? err : 0;
}
@@ -735,7 +742,7 @@ static void cinergyt2_query_rc (void *data)
struct cinergyt2_rc_event rc_events[12];
int n, len, i;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return;
len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
@@ -795,7 +802,7 @@ out:
schedule_delayed_work(&cinergyt2->rc_query_work,
msecs_to_jiffies(RC_QUERY_INTERVAL));
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
}
static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
@@ -860,7 +867,7 @@ static void cinergyt2_query (void *data)
uint8_t lock_bits;
uint32_t unc;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return;
unc = s->uncorrected_block_count;
@@ -879,7 +886,7 @@ static void cinergyt2_query (void *data)
schedule_delayed_work(&cinergyt2->query_work,
msecs_to_jiffies(QUERY_INTERVAL));
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
}
static int cinergyt2_probe (struct usb_interface *intf,
@@ -896,7 +903,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
memset (cinergyt2, 0, sizeof (struct cinergyt2));
usb_set_intfdata (intf, (void *) cinergyt2);
- init_MUTEX(&cinergyt2->sem);
+ mutex_init(&cinergyt2->sem);
init_waitqueue_head (&cinergyt2->poll_wq);
INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2);
@@ -978,7 +985,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
{
struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
@@ -996,7 +1003,7 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
cinergyt2_sleep(cinergyt2, 1);
}
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return 0;
}
@@ -1005,7 +1012,7 @@ static int cinergyt2_resume (struct usb_interface *intf)
struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
struct dvbt_set_parameters_msg *param = &cinergyt2->param;
- if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
if (!cinergyt2->sleeping) {
@@ -1018,7 +1025,7 @@ static int cinergyt2_resume (struct usb_interface *intf)
cinergyt2_resume_rc(cinergyt2);
- up(&cinergyt2->sem);
+ mutex_unlock(&cinergyt2->sem);
return 0;
}
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c
index 7b8373ad1..ead5343d7 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c
@@ -175,12 +175,12 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
dprintk ("function : %s\n", __FUNCTION__);
- if (down_interruptible (&dmxdev->mutex))
+ if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
if ((file->f_flags&O_ACCMODE)==O_RDWR) {
if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) {
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return -EOPNOTSUPP;
}
}
@@ -190,7 +190,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE;
dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE);
if (!dmxdev->dvr_buffer.data) {
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return -ENOMEM;
}
}
@@ -199,20 +199,20 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
dmxdev->dvr_orig_fe=dmxdev->demux->frontend;
if (!dmxdev->demux->write) {
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return -EOPNOTSUPP;
}
front=get_fe(dmxdev->demux, DMX_MEMORY_FE);
if (!front) {
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return -EINVAL;
}
dmxdev->demux->disconnect_frontend(dmxdev->demux);
dmxdev->demux->connect_frontend(dmxdev->demux, front);
}
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return 0;
}
@@ -221,7 +221,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
- if (down_interruptible (&dmxdev->mutex))
+ if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
@@ -239,7 +239,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
vfree(mem);
}
}
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return 0;
}
@@ -254,10 +254,10 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
return -EOPNOTSUPP;
if ((file->f_flags&O_ACCMODE)!=O_WRONLY)
return -EINVAL;
- if (down_interruptible (&dmxdev->mutex))
+ if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
ret=dmxdev->demux->write(dmxdev->demux, buf, count);
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return ret;
}
@@ -268,11 +268,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
struct dmxdev *dmxdev = dvbdev->priv;
int ret;
- //down(&dmxdev->mutex);
+ //mutex_lock(&dmxdev->mutex);
ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
file->f_flags&O_NONBLOCK,
buf, count, ppos);
- //up(&dmxdev->mutex);
+ //mutex_unlock(&dmxdev->mutex);
return ret;
}
@@ -688,7 +688,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
if (!dmxdev->filter)
return -EINVAL;
- if (down_interruptible(&dmxdev->mutex))
+ if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
for (i=0; i<dmxdev->filternum; i++)
@@ -696,12 +696,12 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
break;
if (i==dmxdev->filternum) {
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return -EMFILE;
}
dmxdevfilter=&dmxdev->filter[i];
- sema_init(&dmxdevfilter->mutex, 1);
+ mutex_init(&dmxdevfilter->mutex);
dmxdevfilter->dvbdev=dmxdev->dvbdev;
file->private_data=dmxdevfilter;
@@ -711,18 +711,18 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dmxdevfilter->feed.ts=NULL;
init_timer(&dmxdevfilter->timer);
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return 0;
}
static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter)
{
- if (down_interruptible(&dmxdev->mutex))
+ if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
- if (down_interruptible(&dmxdevfilter->mutex)) {
- up(&dmxdev->mutex);
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
return -ERESTARTSYS;
}
@@ -740,8 +740,8 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *d
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
wake_up(&dmxdevfilter->buffer.queue);
- up(&dmxdevfilter->mutex);
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdev->mutex);
return 0;
}
@@ -841,7 +841,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
struct dmxdev_filter *dmxdevfilter= file->private_data;
int ret=0;
- if (down_interruptible(&dmxdevfilter->mutex))
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex))
return -ERESTARTSYS;
if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
@@ -851,7 +851,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
file->f_flags&O_NONBLOCK,
buf, count, ppos);
- up(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdevfilter->mutex);
return ret;
}
@@ -864,58 +864,58 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
unsigned long arg=(unsigned long) parg;
int ret=0;
- if (down_interruptible (&dmxdev->mutex))
+ if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
switch (cmd) {
case DMX_START:
- if (down_interruptible(&dmxdevfilter->mutex)) {
- up(&dmxdev->mutex);
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
return -ERESTARTSYS;
}
if (dmxdevfilter->state<DMXDEV_STATE_SET)
ret = -EINVAL;
else
ret = dvb_dmxdev_filter_start(dmxdevfilter);
- up(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdevfilter->mutex);
break;
case DMX_STOP:
- if (down_interruptible(&dmxdevfilter->mutex)) {
- up(&dmxdev->mutex);
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
return -ERESTARTSYS;
}
ret=dvb_dmxdev_filter_stop(dmxdevfilter);
- up(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdevfilter->mutex);
break;
case DMX_SET_FILTER:
- if (down_interruptible(&dmxdevfilter->mutex)) {
- up(&dmxdev->mutex);
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
return -ERESTARTSYS;
}
ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter,
(struct dmx_sct_filter_params *)parg);
- up(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdevfilter->mutex);
break;
case DMX_SET_PES_FILTER:
- if (down_interruptible(&dmxdevfilter->mutex)) {
- up(&dmxdev->mutex);
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
return -ERESTARTSYS;
}
ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter,
(struct dmx_pes_filter_params *)parg);
- up(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdevfilter->mutex);
break;
case DMX_SET_BUFFER_SIZE:
- if (down_interruptible(&dmxdevfilter->mutex)) {
- up(&dmxdev->mutex);
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
return -ERESTARTSYS;
}
ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
- up(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdevfilter->mutex);
break;
case DMX_GET_EVENT:
@@ -959,7 +959,7 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
default:
ret=-EINVAL;
}
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return ret;
}
@@ -1030,7 +1030,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
int ret=0;
- if (down_interruptible (&dmxdev->mutex))
+ if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
switch (cmd) {
@@ -1042,7 +1042,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
default:
ret=-EINVAL;
}
- up(&dmxdev->mutex);
+ mutex_unlock(&dmxdev->mutex);
return ret;
}
@@ -1113,7 +1113,7 @@ dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
return -ENOMEM;
}
- sema_init(&dmxdev->mutex, 1);
+ mutex_init(&dmxdev->mutex);
spin_lock_init(&dmxdev->lock);
for (i=0; i<dmxdev->filternum; i++) {
dmxdev->filter[i].dev=dmxdev;
diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.h b/linux/drivers/media/dvb/dvb-core/dmxdev.h
index fd72920c2..356172732 100644
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.h
@@ -30,7 +30,10 @@
#include <linux/wait.h>
#include <linux/fs.h>
#include <linux/string.h>
-#include <asm/semaphore.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include <linux/dvb/dmx.h>
@@ -83,7 +86,11 @@ struct dmxdev_filter {
struct dmxdev *dev;
struct dmxdev_buffer buffer;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex mutex;
+#else
struct semaphore mutex;
+#endif
/* only for sections */
struct timer_list timer;
@@ -117,7 +124,11 @@ struct dmxdev {
struct dmxdev_buffer dvr_buffer;
#define DVR_BUFFER_SIZE (10*188*1024)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex mutex;
+#else
struct semaphore mutex;
+#endif
spinlock_t lock;
};
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c
index b4c899b15..83ec5e06c 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -589,18 +589,18 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
if (pid > DMX_MAX_PID)
return -EINVAL;
- if (down_interruptible(&demux->mutex))
+ if (mutex_lock_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (ts_type & TS_DECODER) {
if (pes_type >= DMX_TS_PES_OTHER) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -EINVAL;
}
if (demux->pesfilter[pes_type] &&
demux->pesfilter[pes_type] != feed) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -EINVAL;
}
@@ -622,14 +622,14 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
#else
feed->buffer = vmalloc(feed->buffer_size);
if (!feed->buffer) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -ENOMEM;
}
#endif
}
feed->state = DMX_STATE_READY;
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return 0;
}
@@ -640,21 +640,21 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
struct dvb_demux *demux = feed->demux;
int ret;
- if (down_interruptible(&demux->mutex))
+ if (mutex_lock_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -EINVAL;
}
if (!demux->start_feed) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -ENODEV;
}
if ((ret = demux->start_feed(feed)) < 0) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return ret;
}
@@ -662,7 +662,7 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
ts_feed->is_filtering = 1;
feed->state = DMX_STATE_GO;
spin_unlock_irq(&demux->lock);
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return 0;
}
@@ -673,16 +673,16 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
struct dvb_demux *demux = feed->demux;
int ret;
- if (down_interruptible(&demux->mutex))
+ if (mutex_lock_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state < DMX_STATE_GO) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -EINVAL;
}
if (!demux->stop_feed) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -ENODEV;
}
@@ -692,7 +692,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
ts_feed->is_filtering = 0;
feed->state = DMX_STATE_ALLOCATED;
spin_unlock_irq(&demux->lock);
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return ret;
}
@@ -704,11 +704,11 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
struct dvb_demux *demux = (struct dvb_demux *)dmx;
struct dvb_demux_feed *feed;
- if (down_interruptible(&demux->mutex))
+ if (mutex_lock_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (!(feed = dvb_dmx_feed_alloc(demux))) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -EBUSY;
}
@@ -729,7 +729,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
feed->state = DMX_STATE_FREE;
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -EBUSY;
}
@@ -737,7 +737,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
feed->filter->feed = feed;
feed->filter->state = DMX_STATE_READY;
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return 0;
}
@@ -748,11 +748,11 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
struct dvb_demux *demux = (struct dvb_demux *)dmx;
struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
- if (down_interruptible(&demux->mutex))
+ if (mutex_lock_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state == DMX_STATE_FREE) {
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return -EINVAL;
}
#ifndef NOBUFS
@@ -770,7 +770,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
demux->pesfilter[feed->pes_type] = NULL;
- up(&demux->mutex);
+ mutex_unlock(&demux->mutex);
return 0;
}
@@ -785,12 +785,12 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
struct dvb_demux_filter *dvbdmxfilter;
- if (down_interruptible(&dvbdemux->mutex))
+ if (mutex_lock_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
if (!dvbdmxfilter) {
- up(&dvbdemux->mutex);
+ mutex_unlock(&dvbdemux->mutex);
return -EBUSY;
}
@@ -805,7 +805,7 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
dvbdmxfeed->filter = dvbdmxfilter;
spin_unlock_irq(&dvbdemux->lock);
- up(&dvbdemux->mutex);
+ mutex_unlock(&dvbdemux->mutex);
return 0;
}
@@ -819,7 +819,7 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed,
if (pid > 0x1fff)
return -EINVAL;
- if (down_interruptible(&dvbdmx->mutex))
+ if (mutex_lock_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
dvb_demux_feed_add(dvbdmxfeed);
@@ -833,13 +833,13 @@ static int dmx_section_feed_set(struct dmx_section_feed *feed,
#else
dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
if (!dvbdmxfeed->buffer) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -ENOMEM;
}
#endif
dvbdmxfeed->state = DMX_STATE_READY;
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return 0;
}
@@ -871,16 +871,16 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
int ret;
- if (down_interruptible(&dvbdmx->mutex))
+ if (mutex_lock_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (feed->is_filtering) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -EBUSY;
}
if (!dvbdmxfeed->filter) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -EINVAL;
}
@@ -890,14 +890,14 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
dvbdmxfeed->feed.sec.seclen = 0;
if (!dvbdmx->start_feed) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -ENODEV;
}
prepare_secfilters(dvbdmxfeed);
if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return ret;
}
@@ -906,7 +906,7 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
dvbdmxfeed->state = DMX_STATE_GO;
spin_unlock_irq(&dvbdmx->lock);
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return 0;
}
@@ -916,11 +916,11 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
int ret;
- if (down_interruptible(&dvbdmx->mutex))
+ if (mutex_lock_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (!dvbdmx->stop_feed) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -ENODEV;
}
@@ -931,7 +931,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
feed->is_filtering = 0;
spin_unlock_irq(&dvbdmx->lock);
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return ret;
}
@@ -942,11 +942,11 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- if (down_interruptible(&dvbdmx->mutex))
+ if (mutex_lock_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (dvbdmxfilter->feed != dvbdmxfeed) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -EINVAL;
}
@@ -966,7 +966,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
dvbdmxfilter->state = DMX_STATE_FREE;
spin_unlock_irq(&dvbdmx->lock);
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return 0;
}
@@ -977,11 +977,11 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
struct dvb_demux_feed *dvbdmxfeed;
- if (down_interruptible(&dvbdmx->mutex))
+ if (mutex_lock_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -EBUSY;
}
@@ -1006,7 +1006,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
(*feed)->stop_filtering = dmx_section_feed_stop_filtering;
(*feed)->release_filter = dmx_section_feed_release_filter;
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return 0;
}
@@ -1016,11 +1016,11 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
- if (down_interruptible(&dvbdmx->mutex))
+ if (mutex_lock_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (dvbdmxfeed->state == DMX_STATE_FREE) {
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return -EINVAL;
}
#ifndef NOBUFS
@@ -1033,7 +1033,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
dvbdmxfeed->pid = 0xffff;
- up(&dvbdmx->mutex);
+ mutex_unlock(&dvbdmx->mutex);
return 0;
}
@@ -1071,10 +1071,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
return -EINVAL;
- if (down_interruptible(&dvbdemux->mutex))
+ if (mutex_lock_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
dvb_dmx_swfilter(dvbdemux, buf, count);
- up(&dvbdemux->mutex);
+ mutex_unlock(&dvbdemux->mutex);
if (signal_pending(current))
return -EINTR;
@@ -1126,11 +1126,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux,
if (demux->frontend)
return -EINVAL;
- if (down_interruptible(&dvbdemux->mutex))
+ if (mutex_lock_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
demux->frontend = frontend;
- up(&dvbdemux->mutex);
+ mutex_unlock(&dvbdemux->mutex);
return 0;
}
@@ -1138,11 +1138,11 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
{
struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
- if (down_interruptible(&dvbdemux->mutex))
+ if (mutex_lock_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
demux->frontend = NULL;
- up(&dvbdemux->mutex);
+ mutex_unlock(&dvbdemux->mutex);
return 0;
}
@@ -1215,7 +1215,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
dmx->disconnect_frontend = dvbdmx_disconnect_frontend;
dmx->get_pes_pids = dvbdmx_get_pes_pids;
- sema_init(&dvbdemux->mutex, 1);
+ mutex_init(&dvbdemux->mutex);
spin_lock_init(&dvbdemux->lock);
return 0;
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.h b/linux/drivers/media/dvb/dvb-core/dvb_demux.h
index 0cc888339..099b149e5 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -26,7 +26,10 @@
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
-#include <asm/semaphore.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "demux.h"
@@ -125,7 +128,11 @@ struct dvb_demux {
u8 tsbuf[204];
int tsbufp;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex mutex;
+#else
struct semaphore mutex;
+#endif
spinlock_t lock;
};
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index bc5949acf..7e9e78e60 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -37,7 +37,6 @@
#include <linux/suspend.h>
#include <linux/jiffies.h>
#include <asm/processor.h>
-#include <asm/semaphore.h>
#include "dvb_frontend.h"
#include "dvbdev.h"
@@ -88,7 +87,7 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola
* FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
*/
-static DECLARE_MUTEX(frontend_mutex);
+static DEFINE_MUTEX(frontend_mutex);
struct dvb_frontend_private {
@@ -1027,12 +1026,12 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
dprintk ("%s\n", __FUNCTION__);
- if (down_interruptible (&frontend_mutex))
+ if (mutex_lock_interruptible(&frontend_mutex))
return -ERESTARTSYS;
fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
if (fe->frontend_priv == NULL) {
- up(&frontend_mutex);
+ mutex_unlock(&frontend_mutex);
return -ENOMEM;
}
fepriv = fe->frontend_priv;
@@ -1051,7 +1050,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
fe, DVB_DEVICE_FRONTEND);
- up (&frontend_mutex);
+ mutex_unlock(&frontend_mutex);
return 0;
}
EXPORT_SYMBOL(dvb_register_frontend);
@@ -1061,7 +1060,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
dprintk ("%s\n", __FUNCTION__);
- down (&frontend_mutex);
+ mutex_lock(&frontend_mutex);
dvb_unregister_device (fepriv->dvbdev);
dvb_frontend_stop (fe);
if (fe->ops->release)
@@ -1070,7 +1069,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name);
/* fe is invalid now */
kfree(fepriv);
- up (&frontend_mutex);
+ mutex_unlock(&frontend_mutex);
return 0;
}
EXPORT_SYMBOL(dvb_unregister_frontend);
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c
index 79779a282..5f3c9b71f 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c
@@ -62,6 +62,10 @@
#include <linux/uio.h>
#include <asm/uaccess.h>
#include <linux/crc32.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "dvb_demux.h"
#include "dvb_net.h"
@@ -151,8 +155,11 @@ struct dvb_net_priv {
unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */
int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */
unsigned long ts_count; /* Current ts cell counter. */
-
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex mutex;
+#else
struct semaphore mutex;
+#endif
};
@@ -889,7 +896,7 @@ static int dvb_net_feed_start(struct net_device *dev)
unsigned char *mac = (unsigned char *) dev->dev_addr;
dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
- down(&priv->mutex);
+ mutex_lock(&priv->mutex);
if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
@@ -974,7 +981,7 @@ static int dvb_net_feed_start(struct net_device *dev)
ret = -EINVAL;
error:
- up(&priv->mutex);
+ mutex_unlock(&priv->mutex);
return ret;
}
@@ -984,7 +991,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
int i, ret = 0;
dprintk("%s\n", __FUNCTION__);
- down(&priv->mutex);
+ mutex_lock(&priv->mutex);
if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
if (priv->secfeed) {
if (priv->secfeed->is_filtering) {
@@ -1026,7 +1033,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
printk("%s: no ts feed to stop\n", dev->name);
} else
ret = -EINVAL;
- up(&priv->mutex);
+ mutex_unlock(&priv->mutex);
return ret;
}
@@ -1208,7 +1215,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
- init_MUTEX(&priv->mutex);
+ mutex_init(&priv->mutex);
net->base_addr = pid;
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig
index 90a69d343..d3df12039 100644
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig
@@ -83,12 +83,18 @@ config DVB_USB_UMT_010
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
config DVB_USB_CXUSB
- tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
+ tristate "Conexant USB2.0 hybrid reference design support"
depends on DVB_USB
select DVB_CX22702
+ select DVB_LGDT330X
+ select DVB_MT352
help
- Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
- only the DVB-T part is supported.
+ Say Y here to support the Conexant USB2.0 hybrid reference design.
+ Currently, only DVB and ATSC modes are supported, analog mode
+ shall be added in the future. Devices that require this module:
+
+ Medion MD95700 hybrid USB2.0 device.
+ DViCO FusionHDTV (Bluebird) USB2.0 devices
config DVB_USB_DIGITV
tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
diff --git a/linux/drivers/media/dvb/dvb-usb/cxusb.c b/linux/drivers/media/dvb/dvb-usb/cxusb.c
index bcd91eee7..28e2e5b45 100644
--- a/linux/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c
@@ -77,7 +77,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i;
- if (down_interruptible(&d->i2c_sem) < 0)
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (num > 2)
@@ -126,7 +126,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
}
}
- up(&d->i2c_sem);
+ mutex_unlock(&d->i2c_mutex);
return i;
}
@@ -234,7 +234,7 @@ static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
{
- static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
+ static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
static u8 reset [] = { RESET, 0x80 };
static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
@@ -255,7 +255,7 @@ static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
{ /* used in both lgz201 and th7579 */
- static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
+ static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
static u8 reset [] = { RESET, 0x80 };
static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-common.c b/linux/drivers/media/dvb/dvb-usb/dibusb-common.c
index 269d899da..2d52b7667 100644
--- a/linux/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/linux/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -128,7 +128,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i;
- if (down_interruptible(&d->i2c_sem) < 0)
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (num > 2)
@@ -146,7 +146,7 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
break;
}
- up(&d->i2c_sem);
+ mutex_unlock(&d->i2c_mutex);
return i;
}
diff --git a/linux/drivers/media/dvb/dvb-usb/digitv.c b/linux/drivers/media/dvb/dvb-usb/digitv.c
index 38639b3c8..c2950c6e9 100644
--- a/linux/drivers/media/dvb/dvb-usb/digitv.c
+++ b/linux/drivers/media/dvb/dvb-usb/digitv.c
@@ -48,7 +48,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i;
- if (down_interruptible(&d->i2c_sem) < 0)
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (num > 2)
@@ -67,7 +67,7 @@ static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
break;
}
- up(&d->i2c_sem);
+ mutex_unlock(&d->i2c_mutex);
return i;
}
@@ -175,11 +175,13 @@ static int digitv_probe(struct usb_interface *intf,
if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
u8 b[4] = { 0 };
- b[0] = 1;
- digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
+ if (d != NULL) { /* do that only when the firmware is loaded */
+ b[0] = 1;
+ digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
- b[0] = 0;
- digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+ b[0] = 0;
+ digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+ }
}
return ret;
}
@@ -194,7 +196,7 @@ static struct dvb_usb_properties digitv_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = CYPRESS_FX2,
- .firmware = "dvb-usb-digitv-01.fw",
+ .firmware = "dvb-usb-digitv-02.fw",
.size_of_priv = 0,
@@ -229,6 +231,7 @@ static struct dvb_usb_properties digitv_properties = {
{ &digitv_table[0], NULL },
{ NULL },
},
+ { NULL },
}
};
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 716f8bf52..4258a995d 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -42,8 +42,8 @@ static int dvb_usb_init(struct dvb_usb_device *d)
{
int ret = 0;
- sema_init(&d->usb_sem, 1);
- sema_init(&d->i2c_sem, 1);
+ mutex_init(&d->usb_mutex);
+ mutex_init(&d->i2c_mutex);
d->state = DVB_USB_STATE_INIT;
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index ee821974d..9002f35aa 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -21,7 +21,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
if (wbuf == NULL || wlen == 0)
return -EINVAL;
- if ((ret = down_interruptible(&d->usb_sem)))
+ if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
return ret;
deb_xfer(">>> ");
@@ -53,7 +53,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
}
}
- up(&d->usb_sem);
+ mutex_unlock(&d->usb_mutex);
return ret;
}
EXPORT_SYMBOL(dvb_usb_generic_rw);
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
index 5e5d21ad9..bdf596c42 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -12,6 +12,10 @@
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/firmware.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "dvb_frontend.h"
#include "dvb_demux.h"
@@ -227,8 +231,8 @@ struct dvb_usb_properties {
* @feedcount: number of reqested feeds (used for streaming-activation)
* @pid_filtering: is hardware pid_filtering used or not.
*
- * @usb_sem: semaphore of USB control messages (reading needs two messages)
- * @i2c_sem: semaphore for i2c-transfers
+ * @usb_mutex: semaphore of USB control messages (reading needs two messages)
+ * @i2c_mutex: semaphore for i2c-transfers
*
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
* @pll_addr: I2C address of the tuner for programming
@@ -283,10 +287,18 @@ struct dvb_usb_device {
int pid_filtering;
/* locking */
- struct semaphore usb_sem;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex usb_mutex;
+#else
+ struct semaphore usb_mutex;
+#endif
/* i2c */
- struct semaphore i2c_sem;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex i2c_mutex;
+#else
+ struct semaphore i2c_mutex;
+#endif
struct i2c_adapter i2c_adap;
/* tuner programming information */
diff --git a/linux/drivers/media/dvb/dvb-usb/vp702x.c b/linux/drivers/media/dvb/dvb-usb/vp702x.c
index bd7ff39be..3658a66f7 100644
--- a/linux/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/linux/drivers/media/dvb/dvb-usb/vp702x.c
@@ -75,7 +75,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
{
int ret;
- if ((ret = down_interruptible(&d->usb_sem)))
+ if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
return ret;
if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
@@ -84,7 +84,7 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
unlock:
- up(&d->usb_sem);
+ mutex_unlock(&d->usb_mutex);
return ret;
}
diff --git a/linux/drivers/media/dvb/dvb-usb/vp7045-fe.c b/linux/drivers/media/dvb/dvb-usb/vp7045-fe.c
index 5242cca5d..9999336ae 100644
--- a/linux/drivers/media/dvb/dvb-usb/vp7045-fe.c
+++ b/linux/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -23,10 +23,11 @@
struct vp7045_fe_state {
struct dvb_frontend fe;
+ struct dvb_frontend_ops ops;
+
struct dvb_usb_device *d;
};
-
static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
{
struct vp7045_fe_state *state = fe->demodulator_priv;
@@ -150,7 +151,8 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
goto error;
s->d = d;
- s->fe.ops = &vp7045_fe_ops;
+ memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
+ s->fe.ops = &s->ops;
s->fe.demodulator_priv = s;
goto success;
diff --git a/linux/drivers/media/dvb/dvb-usb/vp7045.c b/linux/drivers/media/dvb/dvb-usb/vp7045.c
index 812d4d5fb..16aa00ec4 100644
--- a/linux/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/linux/drivers/media/dvb/dvb-usb/vp7045.c
@@ -38,7 +38,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
deb_xfer("out buffer: ");
debug_dump(outbuf,outlen+1,deb_xfer);
- if ((ret = down_interruptible(&d->usb_sem)))
+ if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
return ret;
if (usb_control_msg(d->udev,
@@ -68,7 +68,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
memcpy(in,&inbuf[1],inlen);
unlock:
- up(&d->usb_sem);
+ mutex_unlock(&d->usb_mutex);
return ret;
}
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index f09e3da66..76b6a2aef 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -28,12 +28,6 @@ config DVB_TDA8083
help
A DVB-S tuner module. Say Y when you want to support this frontend.
-config DVB_TDA80XX
- tristate "Philips TDA8044 or TDA8083 based"
- depends on DVB_CORE
- help
- A DVB-S tuner module. Say Y when you want to support this frontend.
-
config DVB_MT312
tristate "Zarlink MT312 based"
depends on DVB_CORE
@@ -139,12 +133,6 @@ config DVB_DIB3000MC
comment "DVB-C (cable) frontends"
depends on DVB_CORE
-config DVB_ATMEL_AT76C651
- tristate "Atmel AT76C651 based"
- depends on DVB_CORE
- help
- A DVB-C tuner module. Say Y when you want to support this frontend.
-
config DVB_VES1820
tristate "VLSI VES1820 based"
depends on DVB_CORE
diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile
index 8f3014685..1af769cd9 100644
--- a/linux/drivers/media/dvb/frontends/Makefile
+++ b/linux/drivers/media/dvb/frontends/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_DVB_CORE) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
obj-$(CONFIG_DVB_SP8870) += sp8870.o
obj-$(CONFIG_DVB_CX22700) += cx22700.o
-obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
obj-$(CONFIG_DVB_CX24110) += cx24110.o
obj-$(CONFIG_DVB_TDA8083) += tda8083.o
obj-$(CONFIG_DVB_L64781) += l64781.o
@@ -22,7 +21,6 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o
obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
-obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
diff --git a/linux/drivers/media/dvb/frontends/bcm3510.c b/linux/drivers/media/dvb/frontends/bcm3510.c
index e50d598a8..ee154299f 100644
--- a/linux/drivers/media/dvb/frontends/bcm3510.c
+++ b/linux/drivers/media/dvb/frontends/bcm3510.c
@@ -39,6 +39,10 @@
#include <linux/jiffies.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "dvb_frontend.h"
#include "bcm3510.h"
@@ -52,7 +56,11 @@ struct bcm3510_state {
struct dvb_frontend frontend;
/* demodulator private data */
- struct semaphore hab_sem;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex hab_mutex;
+#else
+ struct semaphore hab_mutex;
+#endif
u8 firmware_loaded:1;
unsigned long next_status_check;
@@ -213,7 +221,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
dbufout(ob,olen+2,deb_hab);
deb_hab("\n");
- if (down_interruptible(&st->hab_sem) < 0)
+ if (mutex_lock_interruptible(&st->hab_mutex) < 0)
return -EAGAIN;
if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
@@ -226,7 +234,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
memcpy(ibuf,&ib[2],ilen);
error:
- up(&st->hab_sem);
+ mutex_unlock(&st->hab_mutex);
return ret;
}
@@ -796,7 +804,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
state->frontend.ops = &state->ops;
state->frontend.demodulator_priv = state;
- sema_init(&state->hab_sem, 1);
+ mutex_init(&state->hab_mutex);
if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
goto error;
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c
index 2cab96e1c..4f682534d 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.c
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.c
@@ -391,15 +391,15 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = {
.setbw = td1316_bw,
.count = 9,
.entries = {
- { 130000000, 36166000, 166666, 0xca, 0x60},
- { 160000000, 36166000, 166666, 0xca, 0xa0},
- { 200000000, 36166000, 166666, 0xca, 0xc0},
- { 290000000, 36166000, 166666, 0xca, 0x60},
- { 420000000, 36166000, 166666, 0xca, 0xa0},
- { 480000000, 36166000, 166666, 0xca, 0xc0},
- { 620000000, 36166000, 166666, 0xca, 0x60},
- { 830000000, 36166000, 166666, 0xca, 0xa0},
- { 895000000, 36166000, 166666, 0xca, 0xe0},
+ { 93834000, 36166000, 166666, 0xca, 0x60},
+ { 123834000, 36166000, 166666, 0xca, 0xa0},
+ { 163834000, 36166000, 166666, 0xca, 0xc0},
+ { 253834000, 36166000, 166666, 0xca, 0x60},
+ { 383834000, 36166000, 166666, 0xca, 0xa0},
+ { 443834000, 36166000, 166666, 0xca, 0xc0},
+ { 583834000, 36166000, 166666, 0xca, 0x60},
+ { 793834000, 36166000, 166666, 0xca, 0xa0},
+ { 858834000, 36166000, 166666, 0xca, 0xe0},
},
};
EXPORT_SYMBOL(dvb_pll_philips_td1316);
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c
index c63e9a508..8e8df7b4c 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.c
+++ b/linux/drivers/media/dvb/frontends/tda1004x.c
@@ -229,7 +229,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
dprintk("%s\n", __FUNCTION__);
result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
- msleep(1);
+ msleep(20);
return result;
}
@@ -502,7 +502,12 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
const struct firmware *fw;
/* reset + wake up chip */
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+ if (state->config->xtal_freq == TDA10046_XTAL_4M) {
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+ } else {
+ dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__);
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+ }
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
/* let the clocks recover from sleep */
msleep(5);
@@ -651,7 +656,7 @@ static int tda10046_init(struct dvb_frontend* fe)
// tda setup
tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
- tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
+ tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88); // enable pulse killer
switch (state->config->agc_config) {
case TDA10046_AGC_DEFAULT:
@@ -672,6 +677,12 @@ static int tda10046_init(struct dvb_frontend* fe)
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
break;
+ case TDA10046_AGC_TDA827X_GPL:
+ tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
+ tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
+ tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
+ tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+ break;
}
tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
@@ -683,6 +694,7 @@ static int tda10046_init(struct dvb_frontend* fe)
tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
+ // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
state->initialised = 1;
@@ -1027,6 +1039,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
if (status == -1)
return -EIO;
cber |= (status << 8);
+ // The address 0x20 should be read to cope with a TDA10046 bug
tda1004x_read_byte(state, TDA1004X_CBER_RESET);
if (cber != 65535)
@@ -1047,7 +1060,8 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
if (status == -1)
return -EIO;
- vber |= ((status << 16) & 0x0f);
+ vber |= (status & 0x0f) << 16;
+ // The CVBER_LUT should be read to cope with TDA10046 hardware bug
tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
// if RS has passed some valid TS packets, then we must be
@@ -1161,6 +1175,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
if (tmp < 0)
return -EIO;
*ber |= (tmp << 9);
+ // The address 0x20 should be read to cope with a TDA10046 bug
tda1004x_read_byte(state, TDA1004X_CBER_RESET);
dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
@@ -1187,6 +1202,8 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
tda1004x_disable_tuner_i2c(state);
}
}
+ /* set outputs to tristate */
+ tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
break;
}
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.h b/linux/drivers/media/dvb/frontends/tda1004x.h
index 8659c5264..cc0c4af64 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.h
+++ b/linux/drivers/media/dvb/frontends/tda1004x.h
@@ -35,7 +35,8 @@ enum tda10046_agc {
TDA10046_AGC_DEFAULT, /* original configuration */
TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
- TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
+ TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
+ TDA10046_AGC_TDA827X_GPL, /* same as above, but GPIOs 0 */
};
enum tda10046_if {
diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c
index b3a1e367a..4cda49a63 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.c
+++ b/linux/drivers/media/dvb/ttpci/av7110.c
@@ -54,7 +54,6 @@
#include <linux/i2c.h>
#include <asm/system.h>
-#include <asm/semaphore.h>
#include <linux/dvb/frontend.h>
@@ -242,10 +241,10 @@ static int arm_thread(void *data)
if (!av7110->arm_ready)
continue;
- if (down_interruptible(&av7110->dcomlock))
+ if (mutex_lock_interruptible(&av7110->dcomlock))
break;
newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
@@ -253,10 +252,10 @@ static int arm_thread(void *data)
recover_arm(av7110);
- if (down_interruptible(&av7110->dcomlock))
+ if (mutex_lock_interruptible(&av7110->dcomlock))
break;
newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
}
av7110->arm_loops = newloops;
av7110->arm_errors = 0;
@@ -741,7 +740,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
int ret = 0;
dprintk(4, "%p\n", av7110);
- if (down_interruptible(&av7110->pid_mutex))
+ if (mutex_lock_interruptible(&av7110->pid_mutex))
return -ERESTARTSYS;
if (!(vpid & 0x8000))
@@ -760,7 +759,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
}
- up(&av7110->pid_mutex);
+ mutex_unlock(&av7110->pid_mutex);
return ret;
}
@@ -2096,7 +2095,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
if (av7110->playing)
return 0;
- if (down_interruptible(&av7110->pid_mutex))
+ if (mutex_lock_interruptible(&av7110->pid_mutex))
return -ERESTARTSYS;
if (synced) {
@@ -2118,7 +2117,7 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
if (!ret)
av7110->fe_synced = synced;
- up(&av7110->pid_mutex);
+ mutex_unlock(&av7110->pid_mutex);
return ret;
}
@@ -2329,6 +2328,17 @@ static int frontend_init(struct av7110 *av7110)
av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
break;
+ case 0x0004: // Galaxis DVB-S rev1.3
+ /* ALPS BSRV2 */
+ av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+ if (av7110->fe) {
+ av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+ av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
+ av7110->fe->ops->set_tone = av7110_set_tone;
+ av7110->recover = dvb_s_recover;
+ }
+ break;
+
case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
/* Grundig 29504-451 */
av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
@@ -2702,16 +2712,16 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
- sema_init(&av7110->pid_mutex, 1);
+ mutex_init(&av7110->pid_mutex);
/* locks for data transfers from/to AV7110 */
spin_lock_init(&av7110->debilock);
- sema_init(&av7110->dcomlock, 1);
+ mutex_init(&av7110->dcomlock);
av7110->debitype = -1;
/* default OSD window */
av7110->osdwin = 1;
- sema_init(&av7110->osd_sema, 1);
+ mutex_init(&av7110->osd_mutex);
/* ARM "watchdog" */
init_waitqueue_head(&av7110->arm_wait);
@@ -2930,6 +2940,7 @@ MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
+MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3");
static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
@@ -2937,13 +2948,13 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
+ MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004),
MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h
index fafd25fab..51e8c3eca 100644
--- a/linux/drivers/media/dvb/ttpci/av7110.h
+++ b/linux/drivers/media/dvb/ttpci/av7110.h
@@ -16,6 +16,10 @@
#include <linux/dvb/ca.h>
#include <linux/dvb/osd.h>
#include <linux/dvb/net.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "dvbdev.h"
#include "demux.h"
@@ -32,6 +36,7 @@
#include "sp8870.h"
#include "stv0297.h"
#include "l64781.h"
+#include "compat.h"
#include <media/saa7146_vv.h>
@@ -127,7 +132,11 @@ struct av7110 {
/* DEBI and polled command interface */
spinlock_t debilock;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex dcomlock;
+#else
struct semaphore dcomlock;
+#endif
volatile int debitype;
volatile int debilen;
@@ -146,7 +155,11 @@ struct av7110 {
int osdwin; /* currently active window */
u16 osdbpp[8];
- struct semaphore osd_sema;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex osd_mutex;
+#else
+ struct semaphore osd_mutex;
+#endif
/* CA */
@@ -172,7 +185,11 @@ struct av7110 {
struct tasklet_struct vpe_tasklet;
int fe_synced;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex pid_mutex;
+#else
struct semaphore pid_mutex;
+#endif
int video_blank;
struct video_status videostate;
diff --git a/linux/drivers/media/dvb/ttpci/av7110_hw.c b/linux/drivers/media/dvb/ttpci/av7110_hw.c
index e8846b94c..68153d967 100644
--- a/linux/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/linux/drivers/media/dvb/ttpci/av7110_hw.c
@@ -324,10 +324,10 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
start = jiffies;
for (;;) {
err = time_after(jiffies, start + ARM_WAIT_FREE);
- if (down_interruptible(&av7110->dcomlock))
+ if (mutex_lock_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
if ((stat & flags) == 0)
break;
if (err) {
@@ -484,11 +484,11 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
dprintk(1, "arm not ready.\n");
return -1;
}
- if (down_interruptible(&av7110->dcomlock))
+ if (mutex_lock_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
ret = __av7110_send_fw_cmd(av7110, buf, length);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
if (ret && ret!=-ERESTARTSYS)
printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
__FUNCTION__, ret);
@@ -560,11 +560,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
return -1;
}
- if (down_interruptible(&av7110->dcomlock))
+ if (mutex_lock_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
return err;
}
@@ -576,7 +576,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
break;
if (err) {
printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
#ifdef _NOHANDSHAKE
@@ -592,7 +592,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
break;
if (err) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
@@ -603,12 +603,12 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
if (stat & GPMQOver) {
printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return -1;
}
else if (stat & OSDQOver) {
printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return -1;
}
#endif
@@ -616,7 +616,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
for (i = 0; i < reply_buf_len; i++)
reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return 0;
}
@@ -732,7 +732,7 @@ static int FlushText(struct av7110 *av7110)
unsigned long start;
int err;
- if (down_interruptible(&av7110->dcomlock))
+ if (mutex_lock_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
start = jiffies;
while (1) {
@@ -742,12 +742,12 @@ static int FlushText(struct av7110 *av7110)
if (err) {
printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
}
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return 0;
}
@@ -758,7 +758,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
int length = strlen(buf) + 1;
u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
- if (down_interruptible(&av7110->dcomlock))
+ if (mutex_lock_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
start = jiffies;
@@ -769,7 +769,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
if (ret) {
printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
@@ -783,7 +783,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
if (ret) {
printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
__FUNCTION__);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
@@ -795,7 +795,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
if (length & 1)
wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
- up(&av7110->dcomlock);
+ mutex_unlock(&av7110->dcomlock);
if (ret && ret!=-ERESTARTSYS)
printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
return ret;
@@ -1059,7 +1059,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
{
int ret;
- if (down_interruptible(&av7110->osd_sema))
+ if (mutex_lock_interruptible(&av7110->osd_mutex))
return -ERESTARTSYS;
switch (dc->cmd) {
@@ -1195,7 +1195,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
break;
}
- up(&av7110->osd_sema);
+ mutex_unlock(&av7110->osd_mutex);
if (ret==-ERESTARTSYS)
dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
else if (ret)
diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h
index d8805eba1..30f74b416 100644
--- a/linux/drivers/media/dvb/ttpci/budget.h
+++ b/linux/drivers/media/dvb/ttpci/budget.h
@@ -10,6 +10,11 @@
#include "dvb_net.h"
#include <linux/module.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
+
#include <media/saa7146.h>
extern int budget_debug;
@@ -56,7 +61,11 @@ struct budget {
struct dmx_frontend mem_frontend;
int fe_synced;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex pid_mutex;
+#else
struct semaphore pid_mutex;
+#endif
int ci_present;
int video_port;
diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 589e6e0e7..245db934f 100644
--- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -19,7 +19,10 @@
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/jiffies.h>
-#include <asm/semaphore.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include "dvb_frontend.h"
#include "dmxdev.h"
@@ -35,7 +38,6 @@
#include <linux/dvb/dmx.h>
#include <linux/pci.h>
-
/*
TTUSB_HWSECTIONS:
the DSP supports filtering in hardware, however, since the "muxstream"
@@ -83,8 +85,13 @@ struct ttusb {
struct dvb_net dvbnet;
/* and one for USB access. */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex semi2c;
+ struct mutex semusb;
+#else
struct semaphore semi2c;
struct semaphore semusb;
+#endif
struct dvb_adapter adapter;
struct usb_device *dev;
@@ -150,7 +157,7 @@ static int ttusb_cmd(struct ttusb *ttusb,
printk("\n");
#endif
- if (down_interruptible(&ttusb->semusb) < 0)
+ if (mutex_lock_interruptible(&ttusb->semusb) < 0)
return -EAGAIN;
err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
@@ -158,13 +165,13 @@ static int ttusb_cmd(struct ttusb *ttusb,
if (err != 0) {
dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
__FUNCTION__, err);
- up(&ttusb->semusb);
+ mutex_unlock(&ttusb->semusb);
return err;
}
if (actual_len != len) {
dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
actual_len, len);
- up(&ttusb->semusb);
+ mutex_unlock(&ttusb->semusb);
return -1;
}
@@ -174,7 +181,7 @@ static int ttusb_cmd(struct ttusb *ttusb,
if (err != 0) {
printk("%s: failed, receive error %d\n", __FUNCTION__,
err);
- up(&ttusb->semusb);
+ mutex_unlock(&ttusb->semusb);
return err;
}
#if DEBUG >= 3
@@ -185,14 +192,14 @@ static int ttusb_cmd(struct ttusb *ttusb,
printk("\n");
#endif
if (!needresult)
- up(&ttusb->semusb);
+ mutex_unlock(&ttusb->semusb);
return 0;
}
static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
{
memcpy(data, ttusb->last_result, len);
- up(&ttusb->semusb);
+ mutex_unlock(&ttusb->semusb);
return 0;
}
@@ -250,7 +257,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num
int i = 0;
int inc;
- if (down_interruptible(&ttusb->semi2c) < 0)
+ if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
return -EAGAIN;
while (i < num) {
@@ -284,7 +291,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num
i += inc;
}
- up(&ttusb->semi2c);
+ mutex_unlock(&ttusb->semi2c);
return i;
}
@@ -1495,8 +1502,11 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
ttusb->dev = udev;
ttusb->c = 0;
ttusb->mux_state = 0;
- sema_init(&ttusb->semi2c, 0);
- sema_init(&ttusb->semusb, 1);
+ mutex_init(&ttusb->semi2c);
+
+ mutex_lock(&ttusb->semi2c);
+
+ mutex_init(&ttusb->semusb);
ttusb_setup_interfaces(ttusb);
@@ -1504,7 +1514,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
if (ttusb_init_controller(ttusb))
printk("ttusb_init_controller: error\n");
- up(&ttusb->semi2c);
+ mutex_unlock(&ttusb->semi2c);
dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
ttusb->adapter.priv = ttusb;
diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index df831171e..50741a8df 100644
--- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -20,7 +20,11 @@
*
*/
-#include <asm/semaphore.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
+
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -115,7 +119,11 @@ struct ttusb_dec {
unsigned int out_pipe;
unsigned int irq_pipe;
enum ttusb_dec_interface interface;
- struct semaphore usb_sem;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex usb_mutex;
+#else
+ struct semaphore usb_mutex;
+#endif
void *irq_buffer;
struct urb *irq_urb;
@@ -124,7 +132,11 @@ struct ttusb_dec {
dma_addr_t iso_dma_handle;
struct urb *iso_urb[ISO_BUF_COUNT];
int iso_stream_count;
- struct semaphore iso_sem;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex iso_mutex;
+#else
+ struct semaphore iso_mutex;
+#endif
u8 packet[MAX_PVA_LENGTH + 4];
enum ttusb_dec_packet_type packet_type;
@@ -273,9 +285,9 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
if (!b)
return -ENOMEM;
- if ((result = down_interruptible(&dec->usb_sem))) {
+ if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
kfree(b);
- printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
+ printk("%s: Failed to lock usb mutex.\n", __FUNCTION__);
return result;
}
@@ -300,7 +312,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
if (result) {
printk("%s: command bulk message failed: error %d\n",
__FUNCTION__, result);
- up(&dec->usb_sem);
+ mutex_unlock(&dec->usb_mutex);
kfree(b);
return result;
}
@@ -311,7 +323,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
if (result) {
printk("%s: result bulk message failed: error %d\n",
__FUNCTION__, result);
- up(&dec->usb_sem);
+ mutex_unlock(&dec->usb_mutex);
kfree(b);
return result;
} else {
@@ -327,7 +339,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
if (cmd_result && b[3] > 0)
memcpy(cmd_result, &b[4], b[3]);
- up(&dec->usb_sem);
+ mutex_unlock(&dec->usb_mutex);
kfree(b);
return 0;
@@ -835,7 +847,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
dprintk("%s\n", __FUNCTION__);
- if (down_interruptible(&dec->iso_sem))
+ if (mutex_lock_interruptible(&dec->iso_mutex))
return;
dec->iso_stream_count--;
@@ -845,7 +857,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
usb_kill_urb(dec->iso_urb[i]);
}
- up(&dec->iso_sem);
+ mutex_unlock(&dec->iso_mutex);
}
/* Setting the interface of the DEC tends to take down the USB communications
@@ -890,7 +902,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
dprintk("%s\n", __FUNCTION__);
- if (down_interruptible(&dec->iso_sem))
+ if (mutex_lock_interruptible(&dec->iso_mutex))
return -EAGAIN;
if (!dec->iso_stream_count) {
@@ -911,7 +923,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
i--;
}
- up(&dec->iso_sem);
+ mutex_unlock(&dec->iso_mutex);
return result;
}
}
@@ -919,7 +931,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
dec->iso_stream_count++;
- up(&dec->iso_sem);
+ mutex_unlock(&dec->iso_mutex);
return 0;
}
@@ -1229,8 +1241,8 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
{
dprintk("%s\n", __FUNCTION__);
- sema_init(&dec->usb_sem, 1);
- sema_init(&dec->iso_sem, 1);
+ mutex_init(&dec->usb_mutex);
+ mutex_init(&dec->iso_mutex);
dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile
index faf728366..60e9c6e3f 100644
--- a/linux/drivers/media/video/Makefile
+++ b/linux/drivers/media/video/Makefile
@@ -9,7 +9,7 @@ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
zr36067-objs := zoran_procfs.o zoran_device.o \
zoran_driver.o zoran_card.o
tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \
- mt20xx.o tda8290.o tea5767.o
+ mt20xx.o tda8290.o tea5767.o xc3028.o
msp3400-objs := msp3400-driver.o msp3400-kthreads.o
diff --git a/linux/drivers/media/video/bttv-driver.c b/linux/drivers/media/video/bttv-driver.c
index ed8fa210f..46aec8404 100644
--- a/linux/drivers/media/video/bttv-driver.c
+++ b/linux/drivers/media/video/bttv-driver.c
@@ -228,7 +228,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
we can capture, of the first and second field. */
.vbistart = { 7,320 },
},{
- .v4l2_id = V4L2_STD_NTSC_M,
+ .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
.name = "NTSC",
.Fsc = 28636363,
.swidth = 768,
@@ -1991,7 +1991,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
BUG();
}
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
kfree(fh->ov.clips);
fh->ov.clips = clips;
fh->ov.nclips = n;
@@ -2012,7 +2012,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
retval = bttv_switch_overlay(btv,fh,new);
}
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return retval;
}
@@ -2192,7 +2192,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
/* update our state informations */
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
fh->fmt = fmt;
fh->cap.field = f->fmt.pix.field;
fh->cap.last = V4L2_FIELD_NONE;
@@ -2201,7 +2201,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
btv->init.fmt = fmt;
btv->init.width = f->fmt.pix.width;
btv->init.height = f->fmt.pix.height;
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return 0;
}
@@ -2308,7 +2308,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
fmt = format_by_palette(pic->palette);
if (NULL == fmt)
return -EINVAL;
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
if (fmt->depth != pic->depth) {
retval = -EINVAL;
goto fh_unlock_and_return;
@@ -2339,7 +2339,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
bt848_contrast(btv,pic->contrast);
bt848_hue(btv,pic->hue);
bt848_sat(btv,pic->colour);
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return 0;
}
@@ -2405,7 +2405,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
return -EPERM;
end = (unsigned long)fbuf->base +
fbuf->height * fbuf->bytesperline;
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
retval = -EINVAL;
switch (fbuf->depth) {
@@ -2443,7 +2443,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
btv->fbuf.fmt.bytesperline = fbuf->bytesperline;
else
btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8;
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return 0;
}
@@ -2466,7 +2466,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
return -EBUSY;
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
if (*on) {
fh->ov.tvnorm = btv->tvnorm;
new = videobuf_alloc(sizeof(*new));
@@ -2477,7 +2477,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
/* switch over */
retval = bttv_switch_overlay(btv,fh,new);
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return retval;
}
@@ -2486,7 +2486,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
struct video_mbuf *mbuf = arg;
unsigned int i;
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize,
V4L2_MEMORY_MMAP);
if (retval < 0)
@@ -2496,7 +2496,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
mbuf->size = gbuffers * gbufsize;
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return 0;
}
case VIDIOCMCAPTURE:
@@ -2508,7 +2508,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
if (vm->frame >= VIDEO_MAX_FRAME)
return -EINVAL;
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
retval = -EINVAL;
buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
if (NULL == buf)
@@ -2530,7 +2530,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
spin_lock_irqsave(&btv->s_lock,flags);
buffer_queue(&fh->cap,&buf->vb);
spin_unlock_irqrestore(&btv->s_lock,flags);
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return 0;
}
case VIDIOCSYNC:
@@ -2541,7 +2541,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
if (*frame >= VIDEO_MAX_FRAME)
return -EINVAL;
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
retval = -EINVAL;
buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
if (NULL == buf)
@@ -2561,7 +2561,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
retval = -EINVAL;
break;
}
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return retval;
}
@@ -2745,7 +2745,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
return -EINVAL;
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
retval = -EINVAL;
if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
@@ -2785,7 +2785,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
retval = bttv_switch_overlay(btv,fh,new);
}
}
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return retval;
}
@@ -2916,7 +2916,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
return 0;
fh_unlock_and_return:
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return retval;
}
@@ -2983,16 +2983,16 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
} else {
/* read() capture */
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
if (NULL == fh->cap.read_buf) {
/* need to capture a new frame */
if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return POLLERR;
}
fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
if (NULL == fh->cap.read_buf) {
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return POLLERR;
}
fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
@@ -3000,13 +3000,13 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
kfree (fh->cap.read_buf);
fh->cap.read_buf = NULL;
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return POLLERR;
}
fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
fh->cap.read_off = 0;
}
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
buf = (struct bttv_buffer*)fh->cap.read_buf;
}
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c
index e86af6fc3..c5c419f34 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.c
+++ b/linux/drivers/media/video/cx25840/cx25840-core.c
@@ -231,33 +231,23 @@ static void input_change(struct i2c_client *client)
cx25840_write(client, 0x808, 0xff);
cx25840_write(client, 0x80b, 0x10);
} else if (std & V4L2_STD_NTSC) {
- /* NTSC */
- if (state->pvr150_workaround) {
- /* Certain Hauppauge PVR150 models have a hardware bug
- that causes audio to drop out. For these models the
- audio standard must be set explicitly.
- To be precise: it affects cards with tuner models
- 85, 99 and 112 (model numbers from tveeprom). */
- if (std == V4L2_STD_NTSC_M_JP) {
- /* Japan uses EIAJ audio standard */
- cx25840_write(client, 0x808, 0x2f);
- } else {
- /* Others use the BTSC audio standard */
- cx25840_write(client, 0x808, 0x1f);
- }
- /* South Korea uses the A2-M (aka Zweiton M) audio
- standard, and should set 0x808 to 0x3f, but I don't
- know how to detect this. */
- } else if (std == V4L2_STD_NTSC_M_JP) {
+ /* Certain Hauppauge PVR150 models have a hardware bug
+ that causes audio to drop out. For these models the
+ audio standard must be set explicitly.
+ To be precise: it affects cards with tuner models
+ 85, 99 and 112 (model numbers from tveeprom). */
+ int hw_fix = state->pvr150_workaround;
+
+ if (std == V4L2_STD_NTSC_M_JP) {
/* Japan uses EIAJ audio standard */
- cx25840_write(client, 0x808, 0xf7);
+ cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
+ } else if (std == V4L2_STD_NTSC_M_KR) {
+ /* South Korea uses A2 audio standard */
+ cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
} else {
/* Others use the BTSC audio standard */
- cx25840_write(client, 0x808, 0xf6);
+ cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
}
- /* South Korea uses the A2-M (aka Zweiton M) audio standard,
- and should set 0x808 to 0xf8, but I don't know how to
- detect this. */
cx25840_write(client, 0x80b, 0x00);
}
@@ -341,17 +331,17 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
u8 fmt=0; /* zero is autodetect */
/* First tests should be against specific std */
- if (std & V4L2_STD_NTSC_M_JP) {
+ if (std == V4L2_STD_NTSC_M_JP) {
fmt=0x2;
- } else if (std & V4L2_STD_NTSC_443) {
+ } else if (std == V4L2_STD_NTSC_443) {
fmt=0x3;
- } else if (std & V4L2_STD_PAL_M) {
+ } else if (std == V4L2_STD_PAL_M) {
fmt=0x5;
- } else if (std & V4L2_STD_PAL_N) {
+ } else if (std == V4L2_STD_PAL_N) {
fmt=0x6;
- } else if (std & V4L2_STD_PAL_Nc) {
+ } else if (std == V4L2_STD_PAL_Nc) {
fmt=0x7;
- } else if (std & V4L2_STD_PAL_60) {
+ } else if (std == V4L2_STD_PAL_60) {
fmt=0x8;
} else {
/* Then, test against generic ones */
@@ -380,7 +370,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
}
switch (fmt) {
- case 0x1: return V4L2_STD_NTSC_M;
+ case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR;
case 0x2: return V4L2_STD_NTSC_M_JP;
case 0x3: return V4L2_STD_NTSC_443;
case 0x4: return V4L2_STD_PAL;
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index 572a8464f..6bed1c717 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-cards.c,v 1.121 2006/01/21 17:18:51 mkrufky Exp $
+ * $Id: cx88-cards.c,v 1.122 2006/01/29 20:28:54 mkrufky Exp $
*
* device driver for Conexant 2388x based TV cards
* card-specific stuff.
@@ -1050,6 +1050,39 @@ struct cx88_board cx88_boards[] = {
}},
.dvb = 1,
},
+ [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = {
+ /* FIXME: This card is shipped without a windows tv app,
+ * so I haven't been able to use regspy to figure out the GPIO
+ * settings. Standard video using the cx88 broadcast decoder is
+ * working, but blackbird isn't working yet, audio is only
+ * working correctly for television mode. S-Video and Composite
+ * are working for video-only, so I have them disabled for now.
+ */
+ .name = "KWorld HardwareMpegTV XPert",
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x07fa,
+#if 0
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+#endif
+ }},
+#if 0
+ .radio = {
+ .type = CX88_RADIO,
+ },
+ .blackbird = 1,
+#endif
+ },
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -1256,6 +1289,10 @@ struct cx88_subid cx88_subids[] = {
.subdevice = 0xdb11,
.card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
/* Re-branded DViCO: UltraView DVB-T Plus */
+ },{
+ .subvendor = 0x17de,
+ .subdevice = 0x0840,
+ .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT,
},
};
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c
index f4dfcae15..d3f993b6a 100644
--- a/linux/drivers/media/video/cx88/cx88-core.c
+++ b/linux/drivers/media/video/cx88/cx88-core.c
@@ -1108,7 +1108,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
core->pci_bus = pci->bus->number;
core->pci_slot = PCI_SLOT(pci->devfn);
core->pci_irqmask = 0x00fc00;
- init_MUTEX(&core->lock);
+ mutex_init(&core->lock);
core->nr = cx88_devcount++;
sprintf(core->name,"cx88[%d]",core->nr);
diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c
index 5dd0acaa9..94b9ab35f 100644
--- a/linux/drivers/media/video/cx88/cx88-input.c
+++ b/linux/drivers/media/video/cx88/cx88-input.c
@@ -153,6 +153,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
switch (core->board) {
case CX88_BOARD_DNTV_LIVE_DVB_T:
case CX88_BOARD_KWORLD_DVB_T:
+ case CX88_BOARD_KWORLD_DVB_T_CX22702:
ir_codes = ir_codes_dntv_live_dvb_t;
ir->gpio_addr = MO_GP1_IO;
ir->mask_keycode = 0x1f;
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c
index a31fee5df..cd661b079 100644
--- a/linux/drivers/media/video/cx88/cx88-video.c
+++ b/linux/drivers/media/video/cx88/cx88-video.c
@@ -362,17 +362,17 @@ static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bi
return 1;
/* is it free? */
- down(&core->lock);
+ mutex_lock(&core->lock);
if (dev->resources & bit) {
/* no, someone else uses it */
- up(&core->lock);
+ mutex_unlock(&core->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
dev->resources |= bit;
dprintk(1,"res: get %d\n",bit);
- up(&core->lock);
+ mutex_unlock(&core->lock);
return 1;
}
@@ -395,11 +395,11 @@ void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
if ((fh->resources & bits) != bits)
BUG();
- down(&core->lock);
+ mutex_lock(&core->lock);
fh->resources &= ~bits;
dev->resources &= ~bits;
dprintk(1,"res: put %d\n",bits);
- up(&core->lock);
+ mutex_unlock(&core->lock);
}
/* ------------------------------------------------------------------ */
@@ -1552,9 +1552,9 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
if (i == ARRAY_SIZE(tvnorms))
return -EINVAL;
- down(&core->lock);
+ mutex_lock(&core->lock);
cx88_set_tvnorm(core,&tvnorms[i]);
- up(&core->lock);
+ mutex_unlock(&core->lock);
return 0;
}
@@ -1604,10 +1604,10 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
if (*i >= 4)
return -EINVAL;
- down(&core->lock);
+ mutex_lock(&core->lock);
cx88_newstation(core);
video_mux(core,*i);
- up(&core->lock);
+ mutex_unlock(&core->lock);
return 0;
}
@@ -1729,7 +1729,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
return -EINVAL;
if (1 == radio && f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- down(&core->lock);
+ mutex_lock(&core->lock);
core->freq = f->frequency;
cx88_newstation(core);
cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
@@ -1738,7 +1738,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
msleep (10);
cx88_set_tvaudio(core);
- up(&core->lock);
+ mutex_unlock(&core->lock);
return 0;
}
@@ -2220,11 +2220,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
pci_set_drvdata(pci_dev,dev);
/* initial device configuration */
- down(&core->lock);
+ mutex_lock(&core->lock);
cx88_set_tvnorm(core,tvnorms);
init_controls(core);
video_mux(core,0);
- up(&core->lock);
+ mutex_unlock(&core->lock);
/* start tvaudio thread */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h
index 982cbe6c7..7a7219377 100644
--- a/linux/drivers/media/video/cx88/cx88.h
+++ b/linux/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,5 @@
/*
- * $Id: cx88.h,v 1.98 2006/01/08 03:39:03 pascoe Exp $
+ * $Id: cx88.h,v 1.99 2006/01/29 20:28:54 mkrufky Exp $
*
* v4l2 device driver for cx2388x based TV cards
*
@@ -39,6 +39,9 @@
#include "cx88-reg.h"
#include <linux/version.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
#ifndef TRUE
@@ -194,6 +197,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42
#define CX88_BOARD_KWORLD_DVB_T_CX22702 43
#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
+#define CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT 45
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -318,8 +322,11 @@ struct cx88_core {
/* IR remote control state */
struct cx88_IR *ir;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock;
+#else
struct semaphore lock;
-
+#endif
/* various v4l controls */
u32 freq;
diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c
index 7a15cff10..3e84ec7c0 100644
--- a/linux/drivers/media/video/em28xx/em28xx-cards.c
+++ b/linux/drivers/media/video/em28xx/em28xx-cards.c
@@ -102,7 +102,7 @@ struct em28xx_board em28xx_boards[] = {
.input = {{
.type = EM28XX_VMUX_TELEVISION,
.vmux = 2,
- .amux = 0,
+ .amux = 1,
},{
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = 0,
@@ -159,18 +159,18 @@ struct em28xx_board em28xx_boards[] = {
.name = "Hauppauge WinTV HVR 900",
.vchannels = 3,
.norm = VIDEO_MODE_PAL,
- .has_tuner = 0,
.tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_XCEIVE_XC3028,
.has_tuner = 1,
.decoder = EM28XX_TVP5150,
.input = {{
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = 2,
- .amux = 0,
+ .amux = 1,
},{
.type = EM28XX_VMUX_TELEVISION,
.vmux = 0,
- .amux = 1,
+ .amux = 0,
},{
.type = EM28XX_VMUX_SVIDEO,
.vmux = 9,
@@ -181,17 +181,17 @@ struct em28xx_board em28xx_boards[] = {
.name = "Terratec Hybrid XS",
.vchannels = 3,
.norm = VIDEO_MODE_PAL,
- .has_tuner = 0,
.tda9887_conf = TDA9887_PRESENT,
.has_tuner = 1,
+ .tuner_type = TUNER_XCEIVE_XC3028,
.decoder = EM28XX_TVP5150,
.input = {{
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = 2,
- .amux = 0,
- },{
.type = EM28XX_VMUX_TELEVISION,
.vmux = 0,
+ .amux = 0,
+ },{
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 2,
.amux = 1,
},{
.type = EM28XX_VMUX_SVIDEO,
diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c
index b78449f2a..febf1188e 100644
--- a/linux/drivers/media/video/em28xx/em28xx-core.c
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c
@@ -189,6 +189,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
{
int ret, byte;
+ if (dev->state & DEV_DISCONNECTED)
+ return(-ENODEV);
+
em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -215,6 +218,9 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
u8 val;
int ret;
+ if (dev->state & DEV_DISCONNECTED)
+ return(-ENODEV);
+
em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -245,7 +251,12 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
int ret;
/*usb_control_msg seems to expect a kmalloced buffer */
- unsigned char *bufs = kmalloc(len, GFP_KERNEL);
+ unsigned char *bufs;
+
+ if (dev->state & DEV_DISCONNECTED)
+ return(-ENODEV);
+
+ bufs = kmalloc(len, GFP_KERNEL);
em28xx_regdbg("req=%02x reg=%02x:", req, reg);
@@ -262,7 +273,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0000, reg, bufs, len, HZ);
- mdelay(5); /* FIXME: magic number */
+ msleep(5); /* FIXME: magic number */
kfree(bufs);
return ret;
}
diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c
index 75f36e371..b531f2839 100644
--- a/linux/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c
@@ -78,7 +78,7 @@ static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
ret = dev->em28xx_read_reg(dev, 0x05);
if (ret == 0x80 + len - 1)
return len;
- mdelay(5);
+ msleep(5);
}
em28xx_warn("i2c write timed out\n");
return -EIO;
@@ -138,7 +138,7 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
return -ENODEV;
else if (msg == 0x84)
return 0;
- mdelay(5);
+ msleep(5);
}
return -ENODEV;
}
@@ -278,9 +278,9 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
msgs[i].buf,
msgs[i].len,
i == num - 1);
- if (rc < 0)
- goto err;
}
+ if (rc < 0)
+ goto err;
if (i2c_debug>=2)
printk("\n");
}
@@ -420,7 +420,6 @@ static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
tun_setup.type = dev->tuner_type;
tun_setup.addr = dev->tuner_addr;
-
em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
}
diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c
index 30121f0ad..1dea158e7 100644
--- a/linux/drivers/media/video/em28xx/em28xx-video.c
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c
@@ -255,8 +255,8 @@ static int em28xx_config(struct em28xx *dev)
#if 1
/* enable vbi capturing */
- em28xx_write_regs_req(dev,0x00,0x0e,"\xC0",1);
- em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1);
+/* em28xx_write_regs_req(dev,0x00,0x0e,"\xC0",1); audio register */
+/* em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1); clk register */
em28xx_write_regs_req(dev,0x00,0x11,"\x51",1);
#endif
@@ -383,11 +383,11 @@ static void video_mux(struct em28xx *dev, int index)
em28xx_audio_source(dev, ainput);
} else {
switch (dev->ctl_ainput) {
- case 0:
- ainput = EM28XX_AUDIO_SRC_TUNER;
- break;
- default:
- ainput = EM28XX_AUDIO_SRC_LINE;
+ case 0:
+ ainput = EM28XX_AUDIO_SRC_TUNER;
+ break;
+ default:
+ ainput = EM28XX_AUDIO_SRC_LINE;
}
em28xx_audio_source(dev, ainput);
}
@@ -432,12 +432,12 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
return -EBUSY;
}
- init_MUTEX(&dev->fileop_lock); /* to 1 == available */
+ mutex_init(&dev->fileop_lock); /* to 1 == available */
spin_lock_init(&dev->queue_lock);
init_waitqueue_head(&dev->wait_frame);
init_waitqueue_head(&dev->wait_stream);
- down(&dev->lock);
+ mutex_lock(&dev->lock);
if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
em28xx_set_alternate(dev);
@@ -453,12 +453,14 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
em28xx_capture_start(dev, 1);
em28xx_resolution_set(dev);
+ /* device needs to be initialized before isoc transfer */
+ video_mux(dev, 0);
+
/* start the transfer */
errCode = em28xx_init_isoc(dev);
if (errCode)
goto err;
- video_mux(dev, 0);
}
dev->users++;
@@ -472,8 +474,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
dev->state |= DEV_INITIALIZED;
- err:
- up(&dev->lock);
+err:
+ mutex_unlock(&dev->lock);
up_read(&em28xx_disconnect);
return errCode;
}
@@ -519,7 +521,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
em28xx_videodbg("users=%d\n", dev->users);
- down(&dev->lock);
+ mutex_lock(&dev->lock);
em28xx_uninit_isoc(dev);
@@ -528,7 +530,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
/* the device is already disconnect, free the remaining resources */
if (dev->state & DEV_DISCONNECTED) {
em28xx_release_resources(dev);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
kfree(dev);
return 0;
}
@@ -544,7 +546,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
dev->users--;
wake_up_interruptible_nr(&dev->open, 1);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -568,7 +570,7 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n");
em28xx_videodbg("not supported yet! ...\n");
if (copy_to_user(buf, "", 1)) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EFAULT;
}
return (1);
@@ -577,38 +579,38 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n");
em28xx_videodbg("not supported yet! ...\n");
if (copy_to_user(buf, "", 1)) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EFAULT;
}
return (1);
}
- if (down_interruptible(&dev->fileop_lock))
+ if (mutex_lock_interruptible(&dev->fileop_lock))
return -ERESTARTSYS;
if (dev->state & DEV_DISCONNECTED) {
em28xx_videodbg("device not present\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -ENODEV;
}
if (dev->state & DEV_MISCONFIGURED) {
em28xx_videodbg("device misconfigured; close and open it again\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EIO;
}
if (dev->io == IO_MMAP) {
em28xx_videodbg ("IO method is set to mmap; close and open"
" the device again to choose the read method\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EINVAL;
}
if (dev->io == IO_NONE) {
if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
em28xx_errdev("read failed, not enough memory\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -ENOMEM;
}
dev->io = IO_READ;
@@ -617,13 +619,13 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
}
if (!count) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return 0;
}
if (list_empty(&dev->outqueue)) {
if (filp->f_flags & O_NONBLOCK) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EAGAIN;
}
ret = wait_event_interruptible
@@ -631,11 +633,11 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
(!list_empty(&dev->outqueue)) ||
(dev->state & DEV_DISCONNECTED));
if (ret) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return ret;
}
if (dev->state & DEV_DISCONNECTED) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -ENODEV;
}
}
@@ -654,12 +656,12 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
count = f->buf.length;
if (copy_to_user(buf, f->bufmem, count)) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EFAULT;
}
*f_pos += count;
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return count;
}
@@ -673,7 +675,7 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
unsigned int mask = 0;
struct em28xx *dev = filp->private_data;
- if (down_interruptible(&dev->fileop_lock))
+ if (mutex_lock_interruptible(&dev->fileop_lock))
return POLLERR;
if (dev->state & DEV_DISCONNECTED) {
@@ -699,13 +701,13 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
if (!list_empty(&dev->outqueue))
mask |= POLLIN | POLLRDNORM;
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return mask;
}
}
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return POLLERR;
}
@@ -745,25 +747,25 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
struct em28xx *dev = filp->private_data;
- if (down_interruptible(&dev->fileop_lock))
+ if (mutex_lock_interruptible(&dev->fileop_lock))
return -ERESTARTSYS;
if (dev->state & DEV_DISCONNECTED) {
em28xx_videodbg("mmap: device not present\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -ENODEV;
}
if (dev->state & DEV_MISCONFIGURED) {
em28xx_videodbg ("mmap: Device is misconfigured; close and "
"open it again\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EIO;
}
if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
size != PAGE_ALIGN(dev->frame[0].buf.length)) {
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EINVAL;
}
@@ -773,7 +775,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
}
if (i == dev->num_frames) {
em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EINVAL;
}
@@ -792,7 +794,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
em28xx_videodbg("mmap: vm_insert_page failed\n");
#endif
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EAGAIN;
}
start += PAGE_SIZE;
@@ -804,7 +806,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_private_data = &dev->frame[i];
em28xx_vm_open(vma);
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return 0;
}
@@ -1234,7 +1236,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
if (i == TVNORMS)
return -EINVAL;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
dev->tvnorm = &tvnorms[i];
em28xx_set_norm(dev, dev->width, dev->height);
@@ -1244,7 +1246,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
&dev->tvnorm->id);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -1298,9 +1300,9 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
if (0 == INPUT(*index)->type)
return -EINVAL;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
video_mux(dev, *index);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -1449,10 +1451,10 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
/* t->signal = 0xffff;*/
/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
/* No way to get signal strength? */
- down(&dev->lock);
+ mutex_lock(&dev->lock);
em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
&status);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
t->signal =
(status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
@@ -1474,10 +1476,10 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
/* t->signal = 0xffff; */
/* No way to get signal strength? */
- down(&dev->lock);
+ mutex_lock(&dev->lock);
em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
&status);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
t->signal =
(status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
@@ -1505,10 +1507,10 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
if (V4L2_TUNER_ANALOG_TV != f->type)
return -EINVAL;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
#if 0 /* ioctl is optional */
@@ -1808,25 +1810,25 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
int ret = 0;
struct em28xx *dev = filp->private_data;
- if (down_interruptible(&dev->fileop_lock))
+ if (mutex_lock_interruptible(&dev->fileop_lock))
return -ERESTARTSYS;
if (dev->state & DEV_DISCONNECTED) {
em28xx_errdev("v4l2 ioctl: device not present\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -ENODEV;
}
if (dev->state & DEV_MISCONFIGURED) {
em28xx_errdev
("v4l2 ioctl: device is misconfigured; close and open it again\n");
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return -EIO;
}
ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
- up(&dev->fileop_lock);
+ mutex_unlock(&dev->fileop_lock);
return ret;
}
@@ -1862,7 +1864,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
dev->udev = udev;
dev->model = model;
- init_MUTEX(&dev->lock);
+ mutex_init(&dev->lock);
init_waitqueue_head(&dev->open);
dev->em28xx_write_regs = em28xx_write_regs;
@@ -1938,7 +1940,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
return -ENOMEM;
}
- down(&dev->lock);
+ mutex_lock(&dev->lock);
/* register i2c bus */
em28xx_i2c_register(dev);
@@ -1948,7 +1950,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
/* configure the device */
em28xx_config_i2c(dev);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
errCode = em28xx_config(dev);
@@ -2005,12 +2007,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
#endif
/* register v4l2 device */
- down(&dev->lock);
+ mutex_lock(&dev->lock);
if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
video_nr[dev->devno]))) {
em28xx_errdev("unable to register video device (error=%i).\n",
retval);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
list_del(&dev->devlist);
video_device_release(dev->vdev);
kfree(dev);
@@ -2021,7 +2023,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
vbi_nr[dev->devno]) < 0) {
printk("unable to register vbi device\n");
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
list_del(&dev->devlist);
video_device_release(dev->vbi_dev);
video_device_release(dev->vdev);
@@ -2042,7 +2044,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
video_mux(dev, 0);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
@@ -2191,7 +2193,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
down_write(&em28xx_disconnect);
- down(&dev->lock);
+ mutex_lock(&dev->lock);
em28xx_info("disconnecting %s\n", dev->vdev->name);
@@ -2213,7 +2215,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
em28xx_release_resources(dev);
}
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
if (!dev->users) {
kfree(dev->alt_max_pkt_size);
diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h
index cb46f77f6..ab9ff4672 100644
--- a/linux/drivers/media/video/em28xx/em28xx.h
+++ b/linux/drivers/media/video/em28xx/em28xx.h
@@ -28,6 +28,9 @@
#include "compat.h"
#include <linux/videodev.h>
#include <linux/i2c.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include <media/ir-kbd-i2c.h>
/* Boards supported by driver */
@@ -261,7 +264,11 @@ struct em28xx {
enum em28xx_stream_state stream;
enum em28xx_io_method io;
/* locks */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock, fileop_lock;
+#else
struct semaphore lock, fileop_lock;
+#endif
spinlock_t queue_lock;
struct list_head inqueue, outqueue;
wait_queue_head_t open, wait_frame, wait_stream;
diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c
index 294078e92..f009567b3 100644
--- a/linux/drivers/media/video/saa6588.c
+++ b/linux/drivers/media/video/saa6588.c
@@ -57,15 +57,15 @@ static unsigned int rbds = 0;
static unsigned int plvl = 0;
static unsigned int bufblocks = 100;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");
-MODULE_PARM(xtal, "i");
+module_param(xtal, int, 0);
MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0");
-MODULE_PARM(rbds, "i");
+module_param(rbds, int, 0);
MODULE_PARM_DESC(rbds, "select mode, 0=RDS, 1=RBDS, default 0");
-MODULE_PARM(plvl, "i");
+module_param(plvl, int, 0);
MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0");
-MODULE_PARM(bufblocks, "i");
+module_param(bufblocks, int, 0);
MODULE_PARM_DESC(bufblocks, "number of buffered blocks, default 100");
MODULE_DESCRIPTION("v4l2 driver module for SAA6588 RDS decoder");
diff --git a/linux/drivers/media/video/saa711x.c b/linux/drivers/media/video/saa711x.c
index ba187966a..f51cd9442 100644
--- a/linux/drivers/media/video/saa711x.c
+++ b/linux/drivers/media/video/saa711x.c
@@ -56,7 +56,7 @@ MODULE_LICENSE("GPL");
#include <linux/video_decoder.h>
static int debug = 0;
-MODULE_PARM(debug, "i");
+module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)");
diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c
index c448cb158..1339b18ad 100644
--- a/linux/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c
@@ -620,12 +620,12 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
struct saa7134_dev *dev = saa7134->dev;
int err;
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
dev->dmasound.read_count = 0;
dev->dmasound.read_offset = 0;
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
if (pcm == NULL)
@@ -943,7 +943,7 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
chip->irq = dev->pci->irq;
- init_MUTEX(&dev->dmasound.lock);
+ mutex_init(&dev->dmasound.lock);
if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
goto __nodev;
diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c
index db2b2da14..93313ec45 100644
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c
@@ -2642,6 +2642,70 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
}},
},
+ [SAA7134_BOARD_FLYDVBT_LR301] = {
+ /* LifeView FlyDVB-T */
+ /* Giampiero Giancipoli <gianci@libero.it> */
+ .name = "LifeView FlyDVB-T",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_comp1, /* Composite input */
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo, /* S-Video signal on S-Video input */
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331] = {
+ .name = "ADS Instant TV Duo Cardbus PTV331",
+ .audio_clock = 0x00200000,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .gpiomask = 0x00600000, /* Bit 21 0=Radio, Bit 22 0=TV */
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x00200000,
+ }},
+ },
+ [SAA7134_BOARD_TEVION_DVBT_220RF] = {
+ .name = "Tevion DVB-T 220RF",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 0,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3119,6 +3183,24 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x2c05,
.driver_data = SAA7134_BOARD_AVERMEDIA_777,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x5168,
+ .subdevice = 0x0301,
+ .driver_data = SAA7134_BOARD_FLYDVBT_LR301,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0331,
+ .subdevice = 0x1421,
+ .driver_data = SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x17de,
+ .subdevice = 0x7201,
+ .driver_data = SAA7134_BOARD_TEVION_DVBT_220RF,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3255,6 +3337,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_GOTVIEW_7135:
case SAA7134_BOARD_KWORLD_TERMINATOR:
case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
+ case SAA7134_BOARD_FLYDVBT_LR301:
dev->has_remote = SAA7134_REMOTE_GPIO;
break;
case SAA7134_BOARD_MD5044:
@@ -3277,6 +3360,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
break;
+ case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
+ saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
+ saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00);
+ break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS:
/* power-up tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff);
@@ -3419,14 +3506,25 @@ int saa7134_board_init2(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_PHILIPS_TIGER:
+ case SAA7134_BOARD_TEVION_DVBT_220RF:
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
- /* this is a hybrid board, initialize to analog mode */
+ /* this is a hybrid board, initialize to analog mode
+ * and configure firmware eeprom address
+ */
{
u8 data[] = { 0x3c, 0x33, 0x68};
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
i2c_transfer(&dev->i2c_adap, &msg, 1);
}
break;
+ case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
+ /* make the tda10046 find its eeprom */
+ {
+ u8 data[] = { 0x3c, 0x33, 0x62};
+ struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
+ i2c_transfer(&dev->i2c_adap, &msg, 1);
+ }
+ break;
}
return 0;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c
index f6b3ea236..e23c6a42d 100644
--- a/linux/drivers/media/video/saa7134/saa7134-core.c
+++ b/linux/drivers/media/video/saa7134/saa7134-core.c
@@ -682,7 +682,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, 0);
- init_MUTEX(&dev->lock);
+ mutex_init(&dev->lock);
spin_lock_init(&dev->slock);
saa7134_track_gpio(dev,"pre-init");
diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c
index 5e2e28bb3..909b82f19 100644
--- a/linux/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c
@@ -848,6 +848,77 @@ static struct tda1004x_config philips_tiger_config = {
.request_firmware = NULL,
};
+/* ------------------------------------------------------------------ */
+
+static int ads_duo_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ int ret;
+
+ ret = philips_tda827xa_pll_set(0x61, fe, params);
+ return ret;
+};
+
+static int ads_duo_dvb_mode(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ /* route TDA8275a AGC input to the channel decoder */
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x60);
+ return 0;
+}
+
+static void ads_duo_analog_mode(struct dvb_frontend *fe)
+{
+ struct saa7134_dev *dev = fe->dvb->priv;
+ /* route TDA8275a AGC input to the analog IF chip*/
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x20);
+ philips_tda827xa_pll_sleep( 0x61, fe);
+}
+
+static struct tda1004x_config ads_tech_duo_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X_GPL,
+ .if_freq = TDA10046_FREQ_045,
+ .pll_init = ads_duo_dvb_mode,
+ .pll_set = ads_duo_pll_set,
+ .pll_sleep = ads_duo_analog_mode,
+ .request_firmware = NULL,
+};
+
+/* ------------------------------------------------------------------ */
+
+static int tevion_dvb220rf_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ int ret;
+ ret = philips_tda827xa_pll_set(0x60, fe, params);
+ return ret;
+}
+
+static int tevion_dvb220rf_pll_init(struct dvb_frontend *fe)
+{
+ return 0;
+}
+
+static void tevion_dvb220rf_pll_sleep(struct dvb_frontend *fe)
+{
+ philips_tda827xa_pll_sleep( 0x61, fe);
+}
+
+static struct tda1004x_config tevion_dvbt220rf_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .if_freq = TDA10046_FREQ_045,
+ .pll_init = tevion_dvb220rf_pll_init,
+ .pll_set = tevion_dvb220rf_pll_set,
+ .pll_sleep = tevion_dvb220rf_pll_sleep,
+ .request_firmware = NULL,
+};
+
#endif
/* ------------------------------------------------------------------ */
@@ -926,6 +997,18 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
&dev->i2c_adap);
break;
+ case SAA7134_BOARD_FLYDVBT_LR301:
+ dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
+ dev->dvb.frontend = tda10046_attach(&ads_tech_duo_config,
+ &dev->i2c_adap);
+ break;
+ case SAA7134_BOARD_TEVION_DVBT_220RF:
+ dev->dvb.frontend = tda10046_attach(&tevion_dvbt220rf_config,
+ &dev->i2c_adap);
+ break;
#endif
#ifdef HAVE_NXT200X
case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c
index 032efb791..512c6173d 100644
--- a/linux/drivers/media/video/saa7134/saa7134-empress.c
+++ b/linux/drivers/media/video/saa7134/saa7134-empress.c
@@ -100,7 +100,7 @@ static int ts_open(struct inode *inode, struct file *file)
dprintk("open minor=%d\n",minor);
err = -EBUSY;
- if (down_trylock(&dev->empress_tsq.lock))
+ if (!mutex_trylock(&dev->empress_tsq.lock))
goto done;
if (dev->empress_users)
goto done_up;
@@ -110,7 +110,7 @@ static int ts_open(struct inode *inode, struct file *file)
err = 0;
done_up:
- up(&dev->empress_tsq.lock);
+ mutex_unlock(&dev->empress_tsq.lock);
done:
return err;
}
@@ -121,7 +121,7 @@ static int ts_release(struct inode *inode, struct file *file)
if (dev->empress_tsq.streaming)
videobuf_streamoff(&dev->empress_tsq);
- down(&dev->empress_tsq.lock);
+ mutex_lock(&dev->empress_tsq.lock);
if (dev->empress_tsq.reading)
videobuf_read_stop(&dev->empress_tsq);
videobuf_mmap_free(&dev->empress_tsq);
@@ -130,7 +130,7 @@ static int ts_release(struct inode *inode, struct file *file)
/* stop the encoder */
ts_reset_encoder(dev);
- up(&dev->empress_tsq.lock);
+ mutex_unlock(&dev->empress_tsq.lock);
return 0;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c
index 493e3c1d6..1eb1ae13f 100644
--- a/linux/drivers/media/video/saa7134/saa7134-input.c
+++ b/linux/drivers/media/video/saa7134/saa7134-input.c
@@ -232,6 +232,11 @@ int saa7134_input_init1(struct saa7134_dev *dev)
mask_keycode = 0x003F00;
mask_keyup = 0x040000;
break;
+ case SAA7134_BOARD_FLYDVBT_LR301:
+ ir_codes = ir_codes_flydvb;
+ mask_keycode = 0x0001F00;
+ mask_keydown = 0x0040000;
+ break;
}
if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n",
diff --git a/linux/drivers/media/video/saa7134/saa7134-oss.c b/linux/drivers/media/video/saa7134/saa7134-oss.c
index f95ac8374..742692ab2 100644
--- a/linux/drivers/media/video/saa7134/saa7134-oss.c
+++ b/linux/drivers/media/video/saa7134/saa7134-oss.c
@@ -273,7 +273,7 @@ static int dsp_open(struct inode *inode, struct file *file)
if (NULL == dev)
return -ENODEV;
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
err = -EBUSY;
if (dev->dmasound.users_dsp)
goto fail1;
@@ -289,13 +289,13 @@ static int dsp_open(struct inode *inode, struct file *file)
if (0 != err)
goto fail2;
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
return 0;
fail2:
dev->dmasound.users_dsp--;
fail1:
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
return err;
}
@@ -303,13 +303,13 @@ static int dsp_release(struct inode *inode, struct file *file)
{
struct saa7134_dev *dev = file->private_data;
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
if (dev->dmasound.recording_on)
dsp_rec_stop(dev);
dsp_buffer_free(dev);
dev->dmasound.users_dsp--;
file->private_data = NULL;
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
return 0;
}
@@ -323,7 +323,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
int err,ret = 0;
add_wait_queue(&dev->dmasound.wq, &wait);
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
while (count > 0) {
/* wait for data if needed */
if (0 == dev->dmasound.read_count) {
@@ -347,12 +347,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
ret = -EAGAIN;
break;
}
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
set_current_state(TASK_INTERRUPTIBLE);
if (0 == dev->dmasound.read_count)
schedule();
set_current_state(TASK_RUNNING);
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
if (signal_pending(current)) {
if (0 == ret)
ret = -EINTR;
@@ -381,7 +381,7 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
if (dev->dmasound.read_offset == dev->dmasound.bufsize)
dev->dmasound.read_offset = 0;
}
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
remove_wait_queue(&dev->dmasound.wq, &wait);
return ret;
}
@@ -454,13 +454,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
case SNDCTL_DSP_STEREO:
if (get_user(val, p))
return -EFAULT;
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
dev->dmasound.channels = val ? 2 : 1;
if (dev->dmasound.recording_on) {
dsp_rec_stop(dev);
dsp_rec_start(dev);
}
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
return put_user(dev->dmasound.channels-1, p);
case SNDCTL_DSP_CHANNELS:
@@ -468,13 +468,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
if (val != 1 && val != 2)
return -EINVAL;
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
dev->dmasound.channels = val;
if (dev->dmasound.recording_on) {
dsp_rec_stop(dev);
dsp_rec_start(dev);
}
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
/* fall through */
case SOUND_PCM_READ_CHANNELS:
return put_user(dev->dmasound.channels, p);
@@ -497,13 +497,13 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
case AFMT_U16_BE:
case AFMT_S16_LE:
case AFMT_S16_BE:
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
dev->dmasound.afmt = val;
if (dev->dmasound.recording_on) {
dsp_rec_stop(dev);
dsp_rec_start(dev);
}
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
return put_user(dev->dmasound.afmt, p);
default:
return -EINVAL;
@@ -528,10 +528,10 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
return 0;
case SNDCTL_DSP_RESET:
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
if (dev->dmasound.recording_on)
dsp_rec_stop(dev);
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
return 0;
case SNDCTL_DSP_GETBLKSIZE:
return put_user(dev->dmasound.blksize, p);
@@ -575,10 +575,10 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
poll_wait(file, &dev->dmasound.wq, wait);
if (0 == dev->dmasound.read_count) {
- down(&dev->dmasound.lock);
+ mutex_lock(&dev->dmasound.lock);
if (!dev->dmasound.recording_on)
dsp_rec_start(dev);
- up(&dev->dmasound.lock);
+ mutex_unlock(&dev->dmasound.lock);
} else
mask |= (POLLIN | POLLRDNORM);
return mask;
@@ -871,7 +871,7 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
return -1;
/* general */
- init_MUTEX(&dev->dmasound.lock);
+ mutex_init(&dev->dmasound.lock);
init_waitqueue_head(&dev->dmasound.wq);
switch (dev->pci->device) {
diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c
index 48c383a4b..daab08493 100644
--- a/linux/drivers/media/video/saa7134/saa7134-video.c
+++ b/linux/drivers/media/video/saa7134/saa7134-video.c
@@ -464,17 +464,17 @@ static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int
return 1;
/* is it free? */
- down(&dev->lock);
+ mutex_lock(&dev->lock);
if (dev->resources & bit) {
/* no, someone else uses it */
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
dev->resources |= bit;
dprintk("res: get %d\n",bit);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 1;
}
@@ -496,11 +496,11 @@ void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
if ((fh->resources & bits) != bits)
BUG();
- down(&dev->lock);
+ mutex_lock(&dev->lock);
fh->resources &= ~bits;
dev->resources &= ~bits;
dprintk("res: put %d\n",bits);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
}
/* ------------------------------------------------------------------ */
@@ -1344,21 +1344,21 @@ video_poll(struct file *file, struct poll_table_struct *wait)
if (!list_empty(&fh->cap.stream))
buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
} else {
- down(&fh->cap.lock);
+ mutex_lock(&fh->cap.lock);
if (UNSET == fh->cap.read_off) {
/* need to capture a new frame */
if (res_locked(fh->dev,RESOURCE_VIDEO)) {
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return POLLERR;
}
if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
return POLLERR;
}
fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
fh->cap.read_off = 0;
}
- up(&fh->cap.lock);
+ mutex_unlock(&fh->cap.lock);
buf = fh->cap.read_buf;
}
@@ -1572,14 +1572,14 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
if (0 != err)
return err;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
fh->win = f->fmt.win;
fh->nclips = f->fmt.win.clipcount;
if (fh->nclips > 8)
fh->nclips = 8;
if (copy_from_user(fh->clips,f->fmt.win.clips,
sizeof(struct v4l2_clip)*fh->nclips)) {
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return -EFAULT;
}
@@ -1589,7 +1589,7 @@ static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
start_preview(dev,fh);
spin_unlock_irqrestore(&dev->slock,flags);
}
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
case V4L2_BUF_TYPE_VBI_CAPTURE:
saa7134_vbi_fmt(dev,f);
@@ -1623,9 +1623,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev,
return get_control(dev,arg);
case VIDIOC_S_CTRL:
{
- down(&dev->lock);
+ mutex_lock(&dev->lock);
err = set_control(dev,NULL,arg);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return err;
}
/* --- input switching --------------------------------------- */
@@ -1675,9 +1675,9 @@ int saa7134_common_ioctl(struct saa7134_dev *dev,
return -EINVAL;
if (NULL == card_in(dev,*i).name)
return -EINVAL;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
video_mux(dev,*i);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -1777,7 +1777,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
if (i == TVNORMS)
return -EINVAL;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
if (res_check(fh, RESOURCE_OVERLAY)) {
spin_lock_irqsave(&dev->slock,flags);
stop_preview(dev,fh);
@@ -1787,7 +1787,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
} else
set_tvnorm(dev,&tvnorms[i]);
saa7134_tvaudio_do_scan(dev);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -1920,13 +1920,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
return -EINVAL;
- down(&dev->lock);
+ mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
saa7134_tvaudio_do_scan(dev);
- up(&dev->lock);
+ mutex_unlock(&dev->lock);
return 0;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index c6780aeab..522ae567f 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -30,6 +30,9 @@
#include <linux/input.h>
#include <linux/notifier.h>
#include <linux/delay.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#include <asm/io.h>
@@ -220,6 +223,9 @@ struct saa7134_format {
#define SAA7134_BOARD_CINERGY250PCI 83
#define SAA7134_BOARD_FLYDVB_TRIO 84
#define SAA7134_BOARD_AVERMEDIA_777 85
+#define SAA7134_BOARD_FLYDVBT_LR301 86
+#define SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331 87
+#define SAA7134_BOARD_TEVION_DVBT_220RF 88
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
@@ -369,7 +375,11 @@ struct saa7134_fh {
/* dmasound dsp status */
struct saa7134_dmasound {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock;
+#else
struct semaphore lock;
+#endif
int minor_mixer;
int minor_dsp;
unsigned int users_dsp;
@@ -435,7 +445,11 @@ struct saa7134_mpeg_ops {
/* global device status */
struct saa7134_dev {
struct list_head devlist;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock;
+#else
struct semaphore lock;
+#endif
spinlock_t slock;
#ifdef VIDIOC_G_PRIORITY
struct v4l2_prio_state prio;
diff --git a/linux/drivers/media/video/tda8290.c b/linux/drivers/media/video/tda8290.c
index 28422f177..7c1e17ebb 100644
--- a/linux/drivers/media/video/tda8290.c
+++ b/linux/drivers/media/video/tda8290.c
@@ -286,7 +286,7 @@ static void tda827xa_agcf(struct i2c_client *c)
static void tda8290_i2c_bridge(struct i2c_client *c, int close)
{
unsigned char enable[2] = { 0x21, 0xC0 };
- unsigned char disable[2] = { 0x21, 0x80 };
+ unsigned char disable[2] = { 0x21, 0x00 };
unsigned char *msg;
if(close) {
msg = enable;
@@ -307,6 +307,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
unsigned char soft_reset[] = { 0x00, 0x00 };
unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode };
unsigned char expert_mode[] = { 0x01, 0x80 };
+ unsigned char agc_out_on[] = { 0x02, 0x00 };
unsigned char gainset_off[] = { 0x28, 0x14 };
unsigned char if_agc_spd[] = { 0x0f, 0x88 };
unsigned char adc_head_6[] = { 0x05, 0x04 };
@@ -325,6 +326,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
pll_stat;
i2c_master_send(c, easy_mode, 2);
+ i2c_master_send(c, agc_out_on, 2);
i2c_master_send(c, soft_reset, 2);
msleep(1);
@@ -475,6 +477,7 @@ static void standby(struct i2c_client *c)
struct tuner *t = i2c_get_clientdata(c);
unsigned char cb1[] = { 0x30, 0xD0 };
unsigned char tda8290_standby[] = { 0x00, 0x02 };
+ unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
tda8290_i2c_bridge(c, 1);
@@ -482,6 +485,7 @@ static void standby(struct i2c_client *c)
cb1[1] = 0x90;
i2c_transfer(c->adapter, &msg, 1);
tda8290_i2c_bridge(c, 0);
+ i2c_master_send(c, tda8290_agc_tri, 2);
i2c_master_send(c, tda8290_standby, 2);
}
@@ -570,7 +574,7 @@ int tda8290_init(struct i2c_client *c)
strlcpy(c->name, "tda8290+75a", sizeof(c->name));
t->tda827x_ver = 2;
}
- tuner_info("tuner: type set to %s\n", c->name);
+ tuner_info("type set to %s\n", c->name);
t->set_tv_freq = set_tv_freq;
t->set_radio_freq = set_radio_freq;
diff --git a/linux/drivers/media/video/tda9887.c b/linux/drivers/media/video/tda9887.c
index 0afa96336..ab134a8c0 100644
--- a/linux/drivers/media/video/tda9887.c
+++ b/linux/drivers/media/video/tda9887.c
@@ -238,7 +238,7 @@ static struct tvnorm tvnorms[] = {
cAudioIF_6_5 |
cVideoIF_38_90 ),
},{
- .std = V4L2_STD_NTSC_M,
+ .std = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
.name = "NTSC-M",
.b = ( cNegativeFmTV |
cQSS ),
@@ -639,6 +639,11 @@ static int tda9887_fixup_std(struct tda9887 *t)
tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
t->std = V4L2_STD_NTSC_M_JP;
break;
+ case 'k':
+ case 'K':
+ tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+ t->std = V4L2_STD_NTSC_M_KR;
+ break;
case '-':
/* default parameter, do nothing */
break;
diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c
index f5fbdf9cf..007a3a8b4 100644
--- a/linux/drivers/media/video/tuner-core.c
+++ b/linux/drivers/media/video/tuner-core.c
@@ -202,7 +202,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
#endif
t->type = type;
-
switch (t->type) {
case TUNER_MT2032:
microtune_init(c);
@@ -246,6 +245,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
i2c_master_send(c,buffer,4);
default_tuner_init(c);
break;
+ case TUNER_XCEIVE_XC3028:
+ xc3028_init(c);
+ break;
default:
default_tuner_init(c);
break;
@@ -402,6 +404,11 @@ static int tuner_fixup_std(struct tuner *t)
tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
t->std = V4L2_STD_NTSC_M_JP;
break;
+ case 'k':
+ case 'K':
+ tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+ t->std = V4L2_STD_NTSC_M_KR;
+ break;
case '-':
/* default parameter, do nothing */
break;
diff --git a/linux/drivers/media/video/tuner-types.c b/linux/drivers/media/video/tuner-types.c
index 20744bac9..d9ac7ed77 100644
--- a/linux/drivers/media/video/tuner-types.c
+++ b/linux/drivers/media/video/tuner-types.c
@@ -1032,6 +1032,23 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
},
};
+/* ------------ TUNER_XCEIVE_XC3028 - Xceive xc3028 ------------ */
+
+static struct tuner_range tuner_xceive_xc3028_ranges[] = {
+ { 16 * 140.25 /*MHz*/, 0x02, },
+ { 16 * 463.25 /*MHz*/, 0x04, },
+ { 16 * 999.99 , 0x01, },
+};
+
+static struct tuner_params tuner_xceive_xc3028_params[] = {
+ {
+ .type = TUNER_XCEIVE_XC3028,
+ .ranges = tuner_xceive_xc3028_ranges,
+ .count = ARRAY_SIZE(tuner_xceive_xc3028_ranges),
+ },
+};
+
+
/* --------------------------------------------------------------------- */
struct tunertype tuners[] = {
@@ -1399,6 +1416,10 @@ struct tunertype tuners[] = {
.params = tuner_samsung_tcpn_2121p30a_params,
.count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params),
},
+ [TUNER_XCEIVE_XC3028] = { /* Xceive 3028 */
+ .name = "Xceive xc3028",
+ .params = tuner_xceive_xc3028_params,
+ },
};
unsigned const int tuner_count = ARRAY_SIZE(tuners);
diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c
index da9c9e944..d3b64130e 100644
--- a/linux/drivers/media/video/tvp5150.c
+++ b/linux/drivers/media/video/tvp5150.c
@@ -124,7 +124,7 @@ struct tvp5150 {
int sat;
};
-static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
+static int tvp5150_read(struct i2c_client *c, unsigned char addr)
{
unsigned char buffer[1];
int rc;
diff --git a/linux/drivers/media/video/video-buf-dvb.c b/linux/drivers/media/video/video-buf-dvb.c
index 92685d9fa..02e5ffaf3 100644
--- a/linux/drivers/media/video/video-buf-dvb.c
+++ b/linux/drivers/media/video/video-buf-dvb.c
@@ -105,7 +105,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed)
if (!demux->dmx.frontend)
return -EINVAL;
- down(&dvb->lock);
+ mutex_lock(&dvb->lock);
dvb->nfeeds++;
rc = dvb->nfeeds;
@@ -119,7 +119,7 @@ static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed)
}
out:
- up(&dvb->lock);
+ mutex_unlock(&dvb->lock);
return rc;
}
@@ -129,14 +129,14 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
struct videobuf_dvb *dvb = demux->priv;
int err = 0;
- down(&dvb->lock);
+ mutex_lock(&dvb->lock);
dvb->nfeeds--;
if (0 == dvb->nfeeds && NULL != dvb->thread) {
// FIXME: cx8802_cancel_buffers(dev);
err = kthread_stop(dvb->thread);
dvb->thread = NULL;
}
- up(&dvb->lock);
+ mutex_unlock(&dvb->lock);
return err;
}
@@ -148,7 +148,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
{
int result;
- init_MUTEX(&dvb->lock);
+ mutex_init(&dvb->lock);
/* register adapter */
result = dvb_register_adapter(&dvb->adapter, dvb->name, module);
diff --git a/linux/drivers/media/video/video-buf.c b/linux/drivers/media/video/video-buf.c
index a2222b6b9..c4e2c58a2 100644
--- a/linux/drivers/media/video/video-buf.c
+++ b/linux/drivers/media/video/video-buf.c
@@ -392,7 +392,7 @@ void videobuf_queue_init(struct videobuf_queue* q,
q->ops = ops;
q->priv_data = priv;
- init_MUTEX(&q->lock);
+ mutex_init(&q->lock);
INIT_LIST_HEAD(&q->stream);
}
@@ -556,7 +556,7 @@ videobuf_reqbufs(struct videobuf_queue *q,
if (!list_empty(&q->stream))
return -EBUSY;
- down(&q->lock);
+ mutex_lock(&q->lock);
count = req->count;
if (count > VIDEO_MAX_FRAME)
count = VIDEO_MAX_FRAME;
@@ -573,7 +573,7 @@ videobuf_reqbufs(struct videobuf_queue *q,
req->count = count;
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
@@ -599,7 +599,7 @@ videobuf_qbuf(struct videobuf_queue *q,
unsigned long flags;
int retval;
- down(&q->lock);
+ mutex_lock(&q->lock);
retval = -EBUSY;
if (q->reading)
goto done;
@@ -659,7 +659,7 @@ videobuf_qbuf(struct videobuf_queue *q,
retval = 0;
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
@@ -670,7 +670,7 @@ videobuf_dqbuf(struct videobuf_queue *q,
struct videobuf_buffer *buf;
int retval;
- down(&q->lock);
+ mutex_lock(&q->lock);
retval = -EBUSY;
if (q->reading)
goto done;
@@ -700,7 +700,7 @@ videobuf_dqbuf(struct videobuf_queue *q,
videobuf_status(b,buf,q->type);
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
@@ -711,7 +711,7 @@ int videobuf_streamon(struct videobuf_queue *q)
unsigned long flags;
int retval;
- down(&q->lock);
+ mutex_lock(&q->lock);
retval = -EBUSY;
if (q->reading)
goto done;
@@ -728,7 +728,7 @@ int videobuf_streamon(struct videobuf_queue *q)
spin_unlock_irqrestore(q->irqlock,flags);
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
@@ -736,7 +736,7 @@ int videobuf_streamoff(struct videobuf_queue *q)
{
int retval = -EINVAL;
- down(&q->lock);
+ mutex_lock(&q->lock);
if (!q->streaming)
goto done;
videobuf_queue_cancel(q);
@@ -744,7 +744,7 @@ int videobuf_streamoff(struct videobuf_queue *q)
retval = 0;
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
@@ -799,7 +799,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
unsigned size, nbufs, bytes;
int retval;
- down(&q->lock);
+ mutex_lock(&q->lock);
nbufs = 1; size = 0;
q->ops->buf_setup(q,&nbufs,&size);
@@ -867,7 +867,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
}
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
@@ -929,7 +929,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
unsigned long flags;
dprintk(2,"%s\n",__FUNCTION__);
- down(&q->lock);
+ mutex_lock(&q->lock);
retval = -EBUSY;
if (q->streaming)
goto done;
@@ -1003,7 +1003,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
}
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
@@ -1014,7 +1014,7 @@ unsigned int videobuf_poll_stream(struct file *file,
struct videobuf_buffer *buf = NULL;
unsigned int rc = 0;
- down(&q->lock);
+ mutex_lock(&q->lock);
if (q->streaming) {
if (!list_empty(&q->stream))
buf = list_entry(q->stream.next,
@@ -1042,7 +1042,7 @@ unsigned int videobuf_poll_stream(struct file *file,
buf->state == STATE_ERROR)
rc = POLLIN|POLLRDNORM;
}
- up(&q->lock);
+ mutex_unlock(&q->lock);
return rc;
}
@@ -1071,7 +1071,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
map->count--;
if (0 == map->count) {
dprintk(1,"munmap %p q=%p\n",map,q);
- down(&q->lock);
+ mutex_lock(&q->lock);
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
@@ -1083,7 +1083,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
q->bufs[i]->baddr = 0;
q->ops->buf_release(q,q->bufs[i]);
}
- up(&q->lock);
+ mutex_unlock(&q->lock);
kfree(map);
}
return;
@@ -1188,7 +1188,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
unsigned int first,last,size,i;
int retval;
- down(&q->lock);
+ mutex_lock(&q->lock);
retval = -EINVAL;
if (!(vma->vm_flags & VM_WRITE)) {
dprintk(1,"mmap app bug: PROT_WRITE please\n");
@@ -1256,7 +1256,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q,
retval = 0;
done:
- up(&q->lock);
+ mutex_unlock(&q->lock);
return retval;
}
diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c
index 98a9deaf2..8747de34a 100644
--- a/linux/drivers/media/video/videodev.c
+++ b/linux/drivers/media/video/videodev.c
@@ -238,13 +238,13 @@ int video_exclusive_open(struct inode *inode, struct file *file)
struct video_device *vfl = video_devdata(file);
int retval = 0;
- down(&vfl->lock);
+ mutex_lock(&vfl->lock);
if (vfl->users) {
retval = -EBUSY;
} else {
vfl->users++;
}
- up(&vfl->lock);
+ mutex_unlock(&vfl->lock);
return retval;
}
@@ -342,7 +342,7 @@ int video_register_device(struct video_device *vfd, int type, int nr)
sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base);
devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor),
S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name);
- init_MUTEX(&vfd->lock);
+ mutex_init(&vfd->lock);
/* sysfs class */
memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
diff --git a/linux/drivers/media/video/xc3028.c b/linux/drivers/media/video/xc3028.c
new file mode 100644
index 000000000..a2d5df4c0
--- /dev/null
+++ b/linux/drivers/media/video/xc3028.c
@@ -0,0 +1,236 @@
+/*
+
+ Xceive - xc3028 tuner interface
+
+ Copyright (c) 2006 Markus Rechberger <mrechberger@gmail.com>
+
+
+TODO: - remove em28xx dependency
+ - add channel locking (requires some more reverse engineering)
+ - try to get the datasheet from Xceive :)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/i2c.h>
+#include <linux/usb.h>
+#include "compat.h"
+#include <linux/videodev.h>
+#include "em28xx.h"
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <media/tuner.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include "i2c-compat.h"
+#endif
+
+#define XC3028_DEFAULT_FIRMWARE "xceive_xc_3028.fw"
+
+int xceive_set_color(struct i2c_client *c);
+
+/* ---------------------------------------------------------------------- */
+
+int xc3028_probe(struct i2c_client *c)
+{
+ printk("xc3028: probe function unknown\n");
+ return -1;
+}
+
+static void xc3028_set_tv_freq(struct i2c_client *c, unsigned int freq){
+ /*
+ the frequency is just shifted and there's a 1:1 relation for all frequencies
+ E11 is Das Erste in Germany/Ulm all other channels match their frequency too
+ */
+
+ unsigned char chanbuf[4];
+ freq<<=2;
+ chanbuf[0]=0;
+ chanbuf[1]=0;
+ chanbuf[2]=(freq&0xff00)>>8;
+ chanbuf[3]=freq&0x00ff;
+ i2c_master_send(c,"\xa0\x00\x00\x00",4);
+ i2c_master_send(c,"\x1e\x1f\x13\x87\x18\x02\x93\x91\x44\x86\x96\x8c",12);
+ i2c_master_send(c,"\x00\x8c",2);
+ i2c_master_send(c,"\x80\x02\x00\x00",4);
+ i2c_master_send(c,chanbuf,4);
+}
+
+int xc3028_init(struct i2c_client *c)
+{
+ struct tuner *t = i2c_get_clientdata(c);
+ struct em28xx *dev;
+ const struct firmware *fw = NULL;
+ size_t firmware_size;
+ int ret=-1;
+ int i=0;
+ int d=0;
+ int txtlen;
+ long fwoff;
+ u8 *firmware;
+ u8 linebuffer[100];
+ char *fwoffset;
+
+ /*
+ request firmware from /lib/firmware, note that the file got extracted by the convert application I wrote and which is available
+ on linuxtv.org / xc3028
+ */
+
+ ret = request_firmware(&fw, XC3028_DEFAULT_FIRMWARE, &t->i2c.dev);
+ if (ret) {
+ printk("xc3028: no firmware uploaded please check %s\n",XC3028_DEFAULT_FIRMWARE);
+ return ret;
+ }
+ firmware = fw->data;
+ firmware_size = fw->size;
+
+ /* small firmware check, both firmwares I have are between 6 and 7k bytes */
+
+ if(fw->size>7000||fw->size<6000){
+ printk("xc3028: wrong firmware provided!\n");
+ release_firmware(fw);
+ return(ret);
+ }
+ for(i=0;i<8&&firmware[i]!='\n';i++);
+ txtlen=i;
+ firmware[i++]=0;
+ fwoff=simple_strtol(firmware,&fwoffset,10);
+ if(fwoff>fw->size){
+ printk("xc3028: firmware offset doesn't match!\n");
+ release_firmware(fw);
+ return(-1);
+ }
+
+ linebuffer[d++]=0x2a;
+ dev=c->adapter->algo_data;
+
+ /* 0x08 is a GPIO address of the em28xx has to get replaced with something generic here */
+
+ dev->em28xx_write_regs(dev, 0x08, "\x6d", 1);
+ dev->em28xx_write_regs(dev, 0x08, "\x7d", 1);
+
+ /*
+ the firmware always starts with 0x2a + 0x40 bytes payload I use to add the offset of the first part
+ as the first line into the firmware binary
+ */
+ while(i!=fw->size){
+ linebuffer[d++]=firmware[i];
+ if((d%64==0&&d!=0)||i==fwoff+txtlen){
+ i2c_master_send(c,linebuffer,d);
+ if(i==(fwoff+txtlen)){
+ i2c_master_send(c,"\x02\x02",2);
+ i2c_master_send(c,"\x02\x03",2);
+ i2c_master_send(c,"\x00\x8c",2);
+ i2c_master_send(c,"\x00\x00\x00\x00",4);
+ /* at least 100 ms delay here, if less terratec FW won't work */
+ msleep(100);
+ /* another reset here */
+ dev->em28xx_write_regs(dev, 0x08, "\x6d", 1);
+ dev->em28xx_write_regs(dev, 0x08, "\x7d", 1);
+
+ }
+ linebuffer[0]=0x2a;
+ d=1;
+ }
+ i++;
+ }
+ printk("xc3024: Firmware uploaded\n");
+ release_firmware(fw);
+
+ /* MAGIC VALUES Hauppauge */
+ i2c_master_send(c,"\x13\x39",2);
+ i2c_master_send(c,"\x0c\x80\xf0\xf7\x3e\x75\xc1\x8a\xe4\x02\x00",11);
+ i2c_master_send(c,"\x05\x0f\xee\xaa\x5f\xea\x90",7);
+ i2c_master_send(c,"\x06\x00\x0a\x4d\x8c\xf2\xd8\xcf\x30\x79\x9f",11);
+ i2c_master_send(c,"\x0b\x0d\xa4\x6c",4);
+ i2c_master_send(c,"\x0a\x01\x67\x24\x40\x08\xc3\x20\x10\x64\x3c\xfa\xf7\xe1\x0c\x2c",0x10);
+ i2c_master_send(c,"\x09\x0b",0x2);
+ i2c_master_send(c,"\x10\x13",0x2);
+ i2c_master_send(c,"\x16\x12",0x2);
+ i2c_master_send(c,"\x1f\x02",0x2);
+ i2c_master_send(c,"\x21\x02",0x2);
+ i2c_master_send(c,"\x01\x02",0x2);
+ i2c_master_send(c,"\x2b\x10",0x2);
+ i2c_master_send(c,"\x02\x02",0x2);
+ i2c_master_send(c,"\x02\x03",0x2);
+ i2c_master_send(c,"\x00\x8c",0x2);
+
+#if 0
+ /* MAGIC Values Terratec - dvb init*/
+ i2c_master_send(c,"\x13\x39",0x02);
+ i2c_master_send(c,"\x0c\x80\xf0\xf7\x3e\x75\xc1\x8a\xe4\x02\x00",11);
+ i2c_master_send(c,"\x05\x0f\xee\xaa\x5f\xea\x90",7);
+ i2c_master_send(c,"\x06\x00\x0a\x4d\x8c\xf2\xd8\xcf\x30\x79\x9f",11);
+ i2c_master_send(c,"\x0b\x0d\xa4\x6c",4);
+ i2c_master_send(c,"\x0a\x01\x67\x24\x40\x08\xc3\x20\x10\x64\x3c\xfa\xf7\xe1\x0c\x2c",0x10);
+ i2c_master_send(c,"\x09\x0b",0x02);
+ i2c_master_send(c,"\x10\x13",0x02);
+ i2c_master_send(c,"\x16\x12",0x02);
+ i2c_master_send(c,"\x1f\x02",0x02);
+ i2c_master_send(c,"\x21\x02",0x02);
+ i2c_master_send(c,"\x01\x02",0x02);
+ i2c_master_send(c,"\x2b\x10",0x02);
+ i2c_master_send(c,"\x02\x02",0x02);
+ i2c_master_send(c,"\x02\x03",0x02);
+ i2c_master_send(c,"\x00\x8c",0x02);
+#endif
+#if 0
+ /* if set video will mostly be black/white - if set_color is called instead the video will have color */
+ i2c_master_send(c,"\x80\x01\x00\x00",0x4);
+ i2c_master_send(c,"\x00\x5e\x00\x29",0x4);
+ i2c_master_send(c,"\x2b\x1a",0x2);
+#endif
+ xceive_set_color(c);
+ t->set_tv_freq = xc3028_set_tv_freq;
+ return(0);
+}
+
+int xceive_set_color(struct i2c_client *c){
+ /* I found this codeblock within the sniffed logfile it got called as it is a several times after 0x00 0x04 tuner settings are made */
+ /* codeblock hauppauge/terratec - analog */
+ i2c_master_send(c,"\x80\x01\x00\x00",4);
+ i2c_master_send(c,"\x00\x5e\x00\x29",4);
+ i2c_master_send(c,"\x2b\x1a",2);
+ i2c_master_send(c,"\x2b\x1b",2);
+ i2c_master_send(c,"\x14\x01\x6c\x25\x82\x38\xa4\x49\xa9\x24\x96\x69",0x0c);
+ i2c_master_send(c,"\x13\x14\x08\x30\x10\x6c\x18\x12\x0d\x19\x32\xad",0x0c);
+ i2c_master_send(c,"\x0d\x01\x4b\x03\x97\x55\xc7\xd7\x00\xa1\xeb\x8f\x5c",0x0d);
+ i2c_master_send(c,"\x1a\x00\x00\x16\x8a\x40\x00\x00\x00\x20",0x0a);
+ i2c_master_send(c,"\x2d\x01",2);
+ i2c_master_send(c,"\x18\x01",2);
+ i2c_master_send(c,"\x1b\x01\xb6\x15\x16\xb1\xa6\xd2\xa9\x12\x41\x66",0x0c);
+ i2c_master_send(c,"\x1d\x00",2);
+ i2c_master_send(c,"\x0f\x00\x29\x56\xb0\x00\xb6",0x07);
+ i2c_master_send(c,"\x20\x00",0x02);
+ i2c_master_send(c,"\x1e\x10\x32\x00\x00\x02\xe4\x81\x00\x06\xa9\x04",0x0c);
+ i2c_master_send(c,"\x22\x29",0x02);
+ i2c_master_send(c,"\x23\x06",0x02);
+ i2c_master_send(c,"\x25\x00\x09\x90\x09\x06\x64\x02\x41",0x09);
+ i2c_master_send(c,"\x26\xcc",0x02);
+ i2c_master_send(c,"\x29\x40",0x02);
+ i2c_master_send(c,"\x21\x03",0x02);
+ i2c_master_send(c,"\x00\x8c",0x02);
+ i2c_master_send(c,"\x00\x00\x00\x00",0x04); /* just wonder no sleep here regarding the logs */
+ i2c_master_send(c,"\x00\x04",0x02);
+ return(0);
+}
+
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h
index e2e28e450..1b76d3e9a 100644
--- a/linux/include/linux/videodev2.h
+++ b/linux/include/linux/videodev2.h
@@ -21,6 +21,9 @@
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
#include <linux/device.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
#endif
#endif
#include <linux/compiler.h> /* need __user */
@@ -108,7 +111,11 @@ struct video_device
/* for videodev.c intenal usage -- please don't touch */
int users; /* video_exclusive_{open|close} ... */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock; /* ... helper function uses these */
+#else
struct semaphore lock; /* ... helper function uses these */
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
devfs_handle_t devfs_handle; /* devfs */
#else
@@ -349,6 +356,7 @@ struct v4l2_pix_format
#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */
#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */
#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */
+#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */
/*
* F O R M A T E N U M E R A T I O N
@@ -664,6 +672,7 @@ typedef __u64 v4l2_std_id;
#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000)
#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
@@ -696,7 +705,8 @@ typedef __u64 v4l2_std_id;
V4L2_STD_PAL_H |\
V4L2_STD_PAL_I)
#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
- V4L2_STD_NTSC_M_JP)
+ V4L2_STD_NTSC_M_JP |\
+ V4L2_STD_NTSC_M_KR)
#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
V4L2_STD_SECAM_K |\
V4L2_STD_SECAM_K1)
diff --git a/linux/include/media/saa7146.h b/linux/include/media/saa7146.h
index 760ae6324..be8b003c0 100644
--- a/linux/include/media/saa7146.h
+++ b/linux/include/media/saa7146.h
@@ -11,9 +11,13 @@
#include <linux/i2c.h> /* for i2c subsystem */
#include <asm/io.h> /* for accessing devices */
#include <linux/stringify.h>
+#include "compat.h"
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#include <linux/mutex.h>
+#endif
+
#include <linux/vmalloc.h> /* for vmalloc() */
#include <linux/mm.h> /* for vmalloc_to_page() */
-#include "compat.h"
#define SAA7146_VERSION_CODE 0x000500 /* 0.5.0 */
@@ -122,7 +126,11 @@ struct saa7146_dev
/* different device locks */
spinlock_t slock;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock;
+#else
struct semaphore lock;
+#endif
unsigned char __iomem *mem; /* pointer to mapped IO memory */
int revision; /* chip revision; needed for bug-workarounds*/
@@ -143,15 +151,20 @@ struct saa7146_dev
void (*vv_callback)(struct saa7146_dev *dev, unsigned long status);
/* i2c-stuff */
- struct semaphore i2c_lock;
- u32 i2c_bitrate;
- struct saa7146_dma d_i2c; /* pointer to i2c memory */
- wait_queue_head_t i2c_wq;
- int i2c_op;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex i2c_lock;
+#else
+ struct semaphore i2c_lock;
+#endif
+
+ u32 i2c_bitrate;
+ struct saa7146_dma d_i2c; /* pointer to i2c memory */
+ wait_queue_head_t i2c_wq;
+ int i2c_op;
/* memories */
- struct saa7146_dma d_rps0;
- struct saa7146_dma d_rps1;
+ struct saa7146_dma d_rps0;
+ struct saa7146_dma d_rps1;
};
/* from saa7146_i2c.c */
@@ -160,7 +173,11 @@ int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg *msgs, in
/* from saa7146_core.c */
extern struct list_head saa7146_devices;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+extern struct mutex saa7146_devices_lock;
+#else
extern struct semaphore saa7146_devices_lock;
+#endif
int saa7146_register_extension(struct saa7146_extension*);
int saa7146_unregister_extension(struct saa7146_extension*);
struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc);
diff --git a/linux/include/media/tuner.h b/linux/include/media/tuner.h
index 50e3bd601..2e5e8c25c 100644
--- a/linux/include/media/tuner.h
+++ b/linux/include/media/tuner.h
@@ -118,6 +118,8 @@
#define TUNER_TNF_5335MF 69 /* Sabrent Bt848 */
#define TUNER_SAMSUNG_TCPN_2121P30A 70 /* Hauppauge PVR-500MCE NTSC */
+#define TUNER_XCEIVE_XC3028 71
+
/* tv card specific */
#define TDA9887_PRESENT (1<<0)
#define TDA9887_PORT1_INACTIVE (1<<1)
@@ -210,6 +212,7 @@ struct tuner {
extern unsigned const int tuner_count;
extern int microtune_init(struct i2c_client *c);
+extern int xc3028_init(struct i2c_client *c);
extern int tda8290_init(struct i2c_client *c);
extern int tda8290_probe(struct i2c_client *c);
extern int tea5767_tuner_init(struct i2c_client *c);
diff --git a/linux/include/media/video-buf-dvb.h b/linux/include/media/video-buf-dvb.h
index 94d16e0ed..8dcaad6a1 100644
--- a/linux/include/media/video-buf-dvb.h
+++ b/linux/include/media/video-buf-dvb.h
@@ -12,7 +12,11 @@ struct videobuf_dvb {
struct videobuf_queue dvbq;
/* video-buf-dvb state info */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock;
+#else
struct semaphore lock;
+#endif
struct task_struct *thread;
int nfeeds;
diff --git a/linux/include/media/video-buf.h b/linux/include/media/video-buf.h
index 6c1dc2777..dd2bb1800 100644
--- a/linux/include/media/video-buf.h
+++ b/linux/include/media/video-buf.h
@@ -178,7 +178,11 @@ struct videobuf_queue_ops {
};
struct videobuf_queue {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ struct mutex lock;
+#else
struct semaphore lock;
+#endif
spinlock_t *irqlock;
struct pci_dev *pci;
diff --git a/linux/sound/pci/bt87x.c b/linux/sound/pci/bt87x.c
index e4e99e429..65f7b6a4f 100644
--- a/linux/sound/pci/bt87x.c
+++ b/linux/sound/pci/bt87x.c
@@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
/* Viewcast Osprey 200 */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+ /* AVerMedia Studio No. 103, 203, ...? */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
{ }
};
MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
@@ -808,7 +810,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
const struct pci_device_id *supported;
supported = pci_match_device(&driver, pci);
- if (supported)
+ if (supported && supported->driver_data > 0)
return supported->driver_data;
for (i = 0; i < ARRAY_SIZE(blacklist); ++i)
diff --git a/v4l/Make.config b/v4l/Make.config
index 476e9019f..d51f77db6 100644
--- a/v4l/Make.config
+++ b/v4l/Make.config
@@ -93,9 +93,13 @@ ifeq ($(CONFIG_DVB_CORE),m)
CONFIG_DVB_BUDGET_PATCH := m
CONFIG_DVB_AV7110 := m
CONFIG_DVB_AV7110_OSD := y
+# Uncomment the next two lines to compile the av7110 firmware into the driver.
+# CONFIG_DVB_AV7110_FIRMWARE := y
+# CONFIG_DVB_AV7110_FIRMWARE_FILE := /path/to/firmware/dvb-ttpci-01.fw
CONFIG_DVB_TTUSB_BUDGET := m
CONFIG_DVB_TTUSB_DEC := m
CONFIG_VIDEO_SAA7146 := m
CONFIG_VIDEO_SAA7146_VV := m
+ CONFIG_DVB_FIRESAT := n
endif
diff --git a/v4l/Makefile b/v4l/Makefile
index 003140d78..889e1581c 100644
--- a/v4l/Makefile
+++ b/v4l/Makefile
@@ -30,7 +30,7 @@ cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
cx88-input.o
cx8800-objs := cx88-video.o cx88-vbi.o
cx8802-objs := cx88-mpeg.o
-tuner-objs := tuner-core.o tuner-types.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
+tuner-objs := tuner-core.o tuner-types.o tuner-simple.o mt20xx.o tda8290.o tea5767.o xc3028.o
msp3400-objs := msp3400-driver.o msp3400-kthreads.o
list-multi := bttv.o saa7134.o cx88xx.o cx8800.o cx88-alsa.o cx8802.o
em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
@@ -70,6 +70,7 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
pvrusb2-sysfs.o pvrusb2-context.o pvrusb2-io.o \
pvrusb2-ioread.o pvrusb2-debugifc.o
+dvb-firesat-objs := firesat.o avc_api.o cmp.o firesat-rc.o
obj-m := video-buf.o v4l1-compat.o v4l2-common.o
obj-m += compat_ioctl32.o
@@ -96,7 +97,7 @@ endif
obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o
obj-$(CONFIG_VIDEO_SAA7134) += saa7134-oss.o
obj-$(CONFIG_VIDEO_IR) += ir-common.o
-obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o saa6588.o
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o saa6588.o
obj-$(CONFIG_VIDEO_TVAUDIO) += msp3400.o tvaudio.o tvmixer.o wm8775.o \
cs53l32a.o tda7432.o tda9875.o
@@ -140,6 +141,7 @@ obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o
obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
+obj-$(CONFIG_DVB_FIRESAT) += dvb-firesat.o
# 2.6-only stuff
ifeq ($(VERSION).$(PATCHLEVEL),2.6)
@@ -160,6 +162,9 @@ endif
EXTRA_CFLAGS += -DDVB_CVS=1
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core/
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends/
+ifeq ($(CONFIG_DVB_FIRESAT),m)
+ EXTRA_CFLAGS += -I$(srctree)/drivers/ieee1394/
+endif
ifeq ($(CONFIG_VIDEO_CX88_DVB),m)
EXTRA_CFLAGS += -DCONFIG_VIDEO_CX88_DVB_MODULE=1
EXTRA_CFLAGS += -DHAVE_CX22702=1
@@ -191,6 +196,8 @@ $(obj)/fdump:
$(obj)/av7110_firm.h: $(obj)/fdump
$(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
+
+EXTRA_CFLAGS += -DCONFIG_DVB_AV7110_FIRMWARE_FILE
endif
@@ -308,6 +315,7 @@ inst_ttpci += budget-ci.ko budget-patch.ko dvb-ttpci.ko
inst_ttusb-budget := dvb-ttusb-budget.ko
inst_ttusb-dec := ttusb_dec.ko ttusbdecfe.ko
inst_pvrusb2 := pvrusb2.ko
+inst_firesat := dvb-firesat.ko
v4l_modules := $(shell /sbin/lsmod|cut -d' ' -f1 ) $(patsubst %.ko,%,$(inst-m))
@@ -404,6 +412,9 @@ dvb-install:: dvb-rminstall
-install -d $(KDIR26)/dvb/ttusb-dec
-install -m 644 -c $(inst_ttusb-dec) $(KDIR26)/dvb/ttusb-dec
+ -install -d $(KDIR26)/dvb/firesat
+ -install -m 644 -c $(inst_firesat) $(KDIR26)/dvb/firesat
+
/sbin/depmod -a ${KERNELRELEASE}
old-install:: rminstall
@@ -451,6 +462,7 @@ dvb-rminstall::
$(addprefix $(KDIR26)/dvb/ttpci/, $(inst_ttpci)) \
$(addprefix $(KDIR26)/dvb/ttusb-budget/, $(inst_ttusb-budget)) \
$(addprefix $(KDIR26)/dvb/ttusb-dec/, $(inst_ttusb-dec)) \
+ $(addprefix $(KDIR26)/dvb/firesat/, $(inst_firesat)) \
$(addprefix $(KDIR26)/dvb/bt8xx/, $(addsuffix .gz,$(inst_bt8xx))) \
$(addprefix $(KDIR26)/dvb/frontends/, $(addsuffix .gz,$(inst_frontends))) \
$(addprefix $(KDIR26)/dvb/dvb-core/, $(addsuffix .gz,$(inst_dvb-core))) \
@@ -460,7 +472,8 @@ dvb-rminstall::
$(addprefix $(KDIR26)/dvb/pluto2/, $(addsuffix .gz,$(inst_pluto2))) \
$(addprefix $(KDIR26)/dvb/ttpci/, $(addsuffix .gz,$(inst_ttpci))) \
$(addprefix $(KDIR26)/dvb/ttusb-budget/, $(addsuffix .gz,$(inst_ttusb-budget))) \
- $(addprefix $(KDIR26)/dvb/ttusb-dec/, $(addsuffix .gz,$(inst_ttusb-dec))) 2>/dev/null
+ $(addprefix $(KDIR26)/dvb/ttusb-dec/, $(addsuffix .gz,$(inst_ttusb-dec))) \
+ $(addprefix $(KDIR26)/dvb/firesat/, $(addsuffix .gz,$(inst_firesat))) 2>/dev/null
@echo
rmmodules::
diff --git a/v4l/compat.h b/v4l/compat.h
index 774afc8da..9efcfebd1 100644
--- a/v4l/compat.h
+++ b/v4l/compat.h
@@ -276,6 +276,7 @@ static inline unsigned long vmalloc_to_pfn(void * vmalloc_addr)
#define mutex_unlock(a) up(a)
#define mutex_lock(a) down(a)
#define mutex_init(a) init_MUTEX(a)
+#define mutex_trylock(a) down_trylock(a)
#endif
#endif
diff --git a/v4l/scripts/makelinks.sh b/v4l/scripts/makelinks.sh
index 56bc40588..44fa17759 100755
--- a/v4l/scripts/makelinks.sh
+++ b/v4l/scripts/makelinks.sh
@@ -58,14 +58,3 @@ diff -u -p videodev.h
#include <linux/types.h>
#define HAVE_V4L1 1
-diff -up v4l-kernel.orig/v4l/Makefile v4l-kernel/v4l/Makefile
---- v4l/Makefile 2005-10-10 00:57:41.000000000 -0400
-+++ v4l/Makefile 2005-10-10 00:58:26.000000000 -0400
-@@ -407,6 +407,7 @@ clean::
- @find . -name '*.c' -type l -exec rm '{}' \;
- @find . -name '*.h' -type l -exec rm '{}' \;
- -rm -f *~ *.o *.ko *.mod.c
-+ @cd ..; patch -p0 -s -R -N < v4l/scripts/makelinks.sh
-
- distclean:: clean
- -rm -f .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
diff --git a/v4l_experimental/firesat/Kconfig b/v4l_experimental/firesat/Kconfig
new file mode 100644
index 000000000..fe8c82b32
--- /dev/null
+++ b/v4l_experimental/firesat/Kconfig
@@ -0,0 +1,11 @@
+config DVB_FIRESAT
+ tristate "FireSAT devices"
+ depends on DVB_CORE && ieee1394
+ help
+ Support for external IEEE1394 adapters designed by Digital Everywhere and
+ produced by El Gato, shipped under the brand name 'EyeTV 300/400'.
+
+ These devices don't have a MPEG decoder built in, so you need
+ an external software decoder to watch TV.
+
+ Say Y if you own such a device and want to use it.
diff --git a/v4l_experimental/firesat/Makefile b/v4l_experimental/firesat/Makefile
new file mode 100644
index 000000000..54e93b366
--- /dev/null
+++ b/v4l_experimental/firesat/Makefile
@@ -0,0 +1,11 @@
+obj-$(CONFIG_DVB_FIRESAT) := dvb-firesat.o
+
+dvb-firesat-objs := firesat.o avc_api.o cmp.o firesat-rc.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
+
+firesat.c: firesat.h avc_api.h cmp.h firesat-rc.h firesat-ci.h
+avc_api.c: avc_api.h firesat.h
+cmp.c: cmp.h avc_api.h
+firesat-rc.c: firesat-rc.h
+firesat-ci.c: firesat-ci.h
diff --git a/v4l_experimental/firesat/avc_api.c b/v4l_experimental/firesat/avc_api.c
new file mode 100644
index 000000000..bff42413c
--- /dev/null
+++ b/v4l_experimental/firesat/avc_api.c
@@ -0,0 +1,953 @@
+/*
+ * FireSAT AVC driver
+ *
+ * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <ieee1394_transactions.h>
+#include <nodemgr.h>
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+#include "firesat.h"
+#include "avc_api.h"
+#include "firesat-rc.h"
+
+#define RESPONSE_REGISTER 0xFFFFF0000D00ULL
+#define COMMAND_REGISTER 0xFFFFF0000B00ULL
+#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
+
+static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
+
+/* Frees an allocated packet */
+static void avc_free_packet(struct hpsb_packet *packet)
+{
+ hpsb_free_tlabel(packet);
+ hpsb_free_packet(packet);
+}
+
+/*
+ * Goofy routine that basically does a down_timeout function.
+ * Stolen from sbp2.c
+ */
+static int avc_down_timeout(atomic_t *done, int timeout)
+{
+ int i;
+
+ for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout(HZ/10)) /* 100ms */
+ return(1);
+ }
+ return ((i > 0) ? 0:1);
+}
+
+static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
+ struct hpsb_packet *packet;
+ struct node_entry *ne;
+
+ ne = firesat->nodeentry;
+ if(!ne) {
+ printk("%s: lost node!\n",__FUNCTION__);
+ return -EIO;
+ }
+
+ /* need all input data */
+ if(!firesat || !ne || !CmdFrm)
+ return -EINVAL;
+
+// printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode);
+
+// for(k=0;k<CmdFrm->length;k++)
+// printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]);
+
+ packet=hpsb_make_writepacket(ne->host, ne->nodeid, COMMAND_REGISTER,
+ (quadlet_t*)CmdFrm, CmdFrm->length);
+
+ hpsb_set_packet_complete_task(packet, (void (*)(void*))avc_free_packet,
+ packet);
+
+ hpsb_node_fill_packet(ne, packet);
+
+ if(RspFrm)
+ atomic_set(&firesat->avc_reply_received, 0);
+
+ if (hpsb_send_packet(packet) < 0) {
+ avc_free_packet(packet);
+ atomic_set(&firesat->avc_reply_received, 1);
+ return -EIO;
+ }
+
+ if(RspFrm) {
+ if(avc_down_timeout(&firesat->avc_reply_received,HZ/2)) {
+ printk("%s: timeout waiting for avc response\n",__FUNCTION__);
+ atomic_set(&firesat->avc_reply_received, 1);
+ return -ETIMEDOUT;
+ }
+
+ memcpy(RspFrm,firesat->respfrm,firesat->resp_length);
+ }
+
+ return 0;
+}
+
+int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
+ int ret;
+ if(down_interruptible(&firesat->avc_sem))
+ return -EINTR;
+
+ ret = __AVCWrite(firesat, CmdFrm, RspFrm);
+
+ up(&firesat->avc_sem);
+ return ret;
+}
+
+static void do_schedule_remotecontrol(unsigned long ignored);
+DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0);
+
+static void do_schedule_remotecontrol(unsigned long ignored) {
+ struct firesat *firesat;
+ unsigned long flags;
+
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_for_each_entry(firesat,&firesat_list,list) {
+ if(atomic_read(&firesat->reschedule_remotecontrol) == 1) {
+ if(down_trylock(&firesat->avc_sem))
+ tasklet_schedule(&schedule_remotecontrol);
+ else {
+ if(__AVCRegisterRemoteControl(firesat, 1) == 0)
+ atomic_set(&firesat->reschedule_remotecontrol, 0);
+ else
+ tasklet_schedule(&schedule_remotecontrol);
+
+ up(&firesat->avc_sem);
+ }
+ }
+ }
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+}
+
+int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
+// printk(KERN_INFO "%s\n",__FUNCTION__);
+
+ // remote control handling
+
+ AVCRspFrm *RspFrm = (AVCRspFrm*)data;
+
+ if(/*RspFrm->length >= 8 && ###*/
+ ((RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
+ RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
+ RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2) ||
+ (RspFrm->operand[0] == SFE_VENDOR_EL_COMPANYID_0 &&
+ RspFrm->operand[1] == SFE_VENDOR_EL_COMPANYID_1 &&
+ RspFrm->operand[2] == SFE_VENDOR_EL_COMPANYID_2)) &&
+ RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
+ if(RspFrm->resp == CHANGED) {
+// printk(KERN_INFO "%s: code = %02x %02x\n",__FUNCTION__,RspFrm->operand[4],RspFrm->operand[5]);
+ firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5]));
+
+ // schedule
+ atomic_set(&firesat->reschedule_remotecontrol, 1);
+ tasklet_schedule(&schedule_remotecontrol);
+ } else if(RspFrm->resp != INTERIM)
+ printk(KERN_INFO "%s: remote control result = %d\n",__FUNCTION__, RspFrm->resp);
+ return 0;
+ }
+
+ if(atomic_read(&firesat->avc_reply_received) == 1) {
+ printk("%s: received out-of-order AVC response, ignored\n",__FUNCTION__);
+ return -EINVAL;
+ }
+// AVCRspFrm *resp=(AVCRspFrm *)data;
+// int k;
+/*
+ printk(KERN_INFO "resp=0x%x\n",resp->resp);
+ printk(KERN_INFO "cts=0x%x\n",resp->cts);
+ printk(KERN_INFO "suid=0x%x\n",resp->suid);
+ printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
+ printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
+ printk(KERN_INFO "length=%d\n",resp->length);
+*/
+// for(k=0;k<2;k++)
+// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]);
+
+ memcpy(firesat->respfrm,data,length);
+ firesat->resp_length=length;
+
+ atomic_set(&firesat->avc_reply_received, 1);
+
+ return 0;
+}
+
+// tuning command for setting the relative LNB frequency (not supported by the AVC standard)
+static void AVCTuner_DSD_directcmd(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) {
+ memset(CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm->cts = AVC;
+ CmdFrm->ctype = CONTROL;
+ CmdFrm->sutyp = 0x5;
+ CmdFrm->suid = firesat->subunit;
+ CmdFrm->opcode = VENDOR;
+
+ /* ### should check for elgato and use SFE_VENDOR_EL_COMPANYID_0 in this case */
+ CmdFrm->operand[0]=SFE_VENDOR_DE_COMPANYID_0;
+ CmdFrm->operand[1]=SFE_VENDOR_DE_COMPANYID_1;
+ CmdFrm->operand[2]=SFE_VENDOR_DE_COMPANYID_2;
+ CmdFrm->operand[3]=0x58;
+
+ printk(KERN_INFO "%s: tuning to frequency %u\n",__FUNCTION__,params->frequency);
+
+ CmdFrm->operand[4] = (params->frequency >> 24) & 0xFF;
+ CmdFrm->operand[5] = (params->frequency >> 16) & 0xFF;
+ CmdFrm->operand[6] = (params->frequency >> 8) & 0xFF;
+ CmdFrm->operand[7] = params->frequency & 0xFF;
+
+ printk(KERN_INFO "%s: symbol rate = %uBd\n",__FUNCTION__,params->u.qpsk.symbol_rate);
+
+ CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate/1000) >> 8) & 0xFF;
+ CmdFrm->operand[9] = (params->u.qpsk.symbol_rate/1000) & 0xFF;
+
+ switch(params->u.qpsk.fec_inner) {
+ case FEC_1_2:
+ CmdFrm->operand[10] = 0x1;
+ break;
+ case FEC_2_3:
+ CmdFrm->operand[10] = 0x2;
+ break;
+ case FEC_3_4:
+ CmdFrm->operand[10] = 0x3;
+ break;
+ case FEC_5_6:
+ CmdFrm->operand[10] = 0x4;
+ break;
+ case FEC_7_8:
+ CmdFrm->operand[10] = 0x5;
+ break;
+ case FEC_4_5:
+ case FEC_8_9:
+ case FEC_AUTO:
+ default:
+ CmdFrm->operand[10] = 0x0;
+ }
+
+ if(firesat->voltage == 0xff)
+ CmdFrm->operand[11] = 0xff;
+ else
+ CmdFrm->operand[11] = (firesat->voltage==SEC_VOLTAGE_18)?0:1; // polarisation
+ if(firesat->tone == 0xff)
+ CmdFrm->operand[12] = 0xff;
+ else
+ CmdFrm->operand[12] = (firesat->tone==SEC_TONE_ON)?1:0; // band
+
+ CmdFrm->length = 16;
+}
+
+int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+ M_VALID_FLAGS flags;
+ int k;
+
+// printk(KERN_INFO "%s\n", __FUNCTION__);
+
+ if(firesat->type == FireSAT_DVB_S)
+ AVCTuner_DSD_directcmd(firesat, params, &CmdFrm);
+ else {
+ if(firesat->type == FireSAT_DVB_T) {
+ flags.Bits_T.GuardInterval = (params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO);
+ flags.Bits_T.CodeRateLPStream = (params->u.ofdm.code_rate_LP != FEC_AUTO);
+ flags.Bits_T.CodeRateHPStream = (params->u.ofdm.code_rate_HP != FEC_AUTO);
+ flags.Bits_T.HierarchyInfo = (params->u.ofdm.hierarchy_information != HIERARCHY_AUTO);
+ flags.Bits_T.Constellation = (params->u.ofdm.constellation != QAM_AUTO);
+ flags.Bits_T.Bandwidth = (params->u.ofdm.bandwidth != BANDWIDTH_AUTO);
+ flags.Bits_T.CenterFrequency = 1;
+ flags.Bits_T.reserved1 = 0;
+ flags.Bits_T.reserved2 = 0;
+ flags.Bits_T.OtherFrequencyFlag = 0;
+ flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
+ flags.Bits_T.NetworkId = 0;
+ } else {
+ flags.Bits.Modulation = 0;
+ if(firesat->type == FireSAT_DVB_S) {
+ flags.Bits.FEC_inner = 1;
+ } else if(firesat->type == FireSAT_DVB_C) {
+ flags.Bits.FEC_inner = 0;
+ }
+ flags.Bits.FEC_outer = 0;
+ flags.Bits.Symbol_Rate = 1;
+ flags.Bits.Frequency = 1;
+ flags.Bits.Orbital_Pos = 0;
+ if(firesat->type == FireSAT_DVB_S) {
+ flags.Bits.Polarisation = 1;
+ } else if(firesat->type == FireSAT_DVB_C) {
+ flags.Bits.Polarisation = 0;
+ }
+ flags.Bits.reserved_fields = 0;
+ flags.Bits.reserved1 = 0;
+ flags.Bits.Network_ID = 0;
+ }
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = CONTROL;
+ CmdFrm.sutyp = 0x5;
+ CmdFrm.suid = firesat->subunit;
+ CmdFrm.opcode = DSD;
+
+ CmdFrm.operand[0] = 0; // source plug
+ CmdFrm.operand[1] = 0xD2; // subfunction replace
+ CmdFrm.operand[2] = 0x20; // system id = DVB
+ CmdFrm.operand[3] = 0x00; // antenna number
+ CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length
+ CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
+ CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
+
+ if(firesat->type == FireSAT_DVB_T) {
+ CmdFrm.operand[7] = 0x0;
+ CmdFrm.operand[8] = (params->frequency/10) >> 24;
+ CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF;
+ CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF;
+ CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
+ switch(params->u.ofdm.bandwidth) {
+ case BANDWIDTH_7_MHZ:
+ CmdFrm.operand[12] = 0x20;
+ break;
+ case BANDWIDTH_8_MHZ:
+ case BANDWIDTH_6_MHZ: // not defined by AVC spec
+ case BANDWIDTH_AUTO:
+ default:
+ CmdFrm.operand[12] = 0x00;
+ }
+ switch(params->u.ofdm.constellation) {
+ case QAM_16:
+ CmdFrm.operand[13] = 1 << 6;
+ break;
+ case QAM_64:
+ CmdFrm.operand[13] = 2 << 6;
+ break;
+ case QPSK:
+ default:
+ CmdFrm.operand[13] = 0x00;
+ }
+ switch(params->u.ofdm.hierarchy_information) {
+ case HIERARCHY_1:
+ CmdFrm.operand[13] |= 1 << 3;
+ break;
+ case HIERARCHY_2:
+ CmdFrm.operand[13] |= 2 << 3;
+ break;
+ case HIERARCHY_4:
+ CmdFrm.operand[13] |= 3 << 3;
+ break;
+ case HIERARCHY_AUTO:
+ case HIERARCHY_NONE:
+ default:
+ break;
+ }
+ switch(params->u.ofdm.code_rate_HP) {
+ case FEC_2_3:
+ CmdFrm.operand[13] |= 1;
+ break;
+ case FEC_3_4:
+ CmdFrm.operand[13] |= 2;
+ break;
+ case FEC_5_6:
+ CmdFrm.operand[13] |= 3;
+ break;
+ case FEC_7_8:
+ CmdFrm.operand[13] |= 4;
+ break;
+ case FEC_1_2:
+ default:
+ break;
+ }
+ switch(params->u.ofdm.code_rate_LP) {
+ case FEC_2_3:
+ CmdFrm.operand[14] = 1 << 5;
+ break;
+ case FEC_3_4:
+ CmdFrm.operand[14] = 2 << 5;
+ break;
+ case FEC_5_6:
+ CmdFrm.operand[14] = 3 << 5;
+ break;
+ case FEC_7_8:
+ CmdFrm.operand[14] = 4 << 5;
+ break;
+ case FEC_1_2:
+ default:
+ CmdFrm.operand[14] = 0x00;
+ break;
+ }
+ switch(params->u.ofdm.guard_interval) {
+ case GUARD_INTERVAL_1_16:
+ CmdFrm.operand[14] |= 1 << 3;
+ break;
+ case GUARD_INTERVAL_1_8:
+ CmdFrm.operand[14] |= 2 << 3;
+ break;
+ case GUARD_INTERVAL_1_4:
+ CmdFrm.operand[14] |= 3 << 3;
+ break;
+ case GUARD_INTERVAL_1_32:
+ case GUARD_INTERVAL_AUTO:
+ default:
+ break;
+ }
+ switch(params->u.ofdm.transmission_mode) {
+ case TRANSMISSION_MODE_8K:
+ CmdFrm.operand[14] |= 1 << 1;
+ break;
+ case TRANSMISSION_MODE_2K:
+ case TRANSMISSION_MODE_AUTO:
+ default:
+ break;
+ }
+
+ CmdFrm.operand[15] = 0x00; // network_ID[0]
+ CmdFrm.operand[16] = 0x00; // network_ID[1]
+ CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
+
+ CmdFrm.length = 20;
+ } else {
+ CmdFrm.operand[7] = 0x00;
+ CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */
+ CmdFrm.operand[9] = 0x00;
+ CmdFrm.operand[10] = 0x00;
+
+ if(firesat->type == FireSAT_DVB_S) {
+ /* ### relative frequency -> absolute frequency */
+ CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
+ CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF;
+ CmdFrm.operand[13] = (params->frequency/4) & 0xFF;
+ } else if(firesat->type == FireSAT_DVB_C) {
+ CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
+ CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF;
+ CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
+ }
+
+ CmdFrm.operand[14] = ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
+ CmdFrm.operand[15] = ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
+ CmdFrm.operand[16] = ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
+
+ CmdFrm.operand[17] = 0x00;
+ switch(params->u.qpsk.fec_inner) {
+ case FEC_1_2:
+ CmdFrm.operand[18] = 0x1;
+ break;
+ case FEC_2_3:
+ CmdFrm.operand[18] = 0x2;
+ break;
+ case FEC_3_4:
+ CmdFrm.operand[18] = 0x3;
+ break;
+ case FEC_5_6:
+ CmdFrm.operand[18] = 0x4;
+ break;
+ case FEC_7_8:
+ CmdFrm.operand[18] = 0x5;
+ break;
+ case FEC_4_5:
+ case FEC_8_9:
+ case FEC_AUTO:
+ default:
+ CmdFrm.operand[18] = 0x0;
+ }
+ if(firesat->type == FireSAT_DVB_S) {
+ CmdFrm.operand[19] = 0x08; // modulation
+ } else if(firesat->type == FireSAT_DVB_C) {
+ switch(params->u.qam.modulation) {
+ case QAM_16:
+ CmdFrm.operand[19] = 0x08; // modulation
+ break;
+ case QAM_32:
+ CmdFrm.operand[19] = 0x10; // modulation
+ break;
+ case QAM_64:
+ CmdFrm.operand[19] = 0x18; // modulation
+ break;
+ case QAM_128:
+ CmdFrm.operand[19] = 0x20; // modulation
+ break;
+ case QAM_256:
+ CmdFrm.operand[19] = 0x28; // modulation
+ break;
+ case QAM_AUTO:
+ default:
+ CmdFrm.operand[19] = 0x00; // modulation
+ }
+ }
+ CmdFrm.operand[20] = 0x00;
+ CmdFrm.operand[21] = 0x00;
+ CmdFrm.operand[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
+
+ CmdFrm.length=28;
+ }
+ } // AVCTuner_DSD_direct
+
+ if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
+ return k;
+
+// msleep(250);
+ mdelay(500);
+
+ if(status)
+ *status=RspFrm.operand[2];
+ return 0;
+}
+
+int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+ int pos,k;
+
+ printk(KERN_INFO "%s\n", __FUNCTION__);
+
+ if(pidc > 16 && pidc != 0xFF)
+ return -EINVAL;
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = CONTROL;
+ CmdFrm.sutyp = 0x5;
+ CmdFrm.suid = firesat->subunit;
+ CmdFrm.opcode = DSD;
+
+ CmdFrm.operand[0] = 0; // source plug
+ CmdFrm.operand[1] = 0xD2; // subfunction replace
+ CmdFrm.operand[2] = 0x20; // system id = DVB
+ CmdFrm.operand[3] = 0x00; // antenna number
+ CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length
+ CmdFrm.operand[5] = 0x00; // valid_flags [0]
+ CmdFrm.operand[6] = 0x00; // valid_flags [1]
+
+ if(firesat->type == FireSAT_DVB_T) {
+/* CmdFrm.operand[7] = 0x00;
+ CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24;
+ CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF;
+ CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF;
+ CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF;
+ CmdFrm.operand[12] = 0x00;
+ CmdFrm.operand[13] = 0x00;
+ CmdFrm.operand[14] = 0x00;
+
+ CmdFrm.operand[15] = 0x00; // network_ID[0]
+ CmdFrm.operand[16] = 0x00; // network_ID[1]
+*/ CmdFrm.operand[17] = pidc; // Nr_of_dsd_sel_specs
+
+ pos=18;
+ } else {
+/* CmdFrm.operand[7] = 0x00;
+ CmdFrm.operand[8] = 0x00;
+ CmdFrm.operand[9] = 0x00;
+ CmdFrm.operand[10] = 0x00;
+
+ CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
+ CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF;
+ CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF;
+
+ CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
+ CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
+ CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
+
+ CmdFrm.operand[17] = 0x00;
+ CmdFrm.operand[18] = 0x00;
+ CmdFrm.operand[19] = 0x00; // modulation
+ CmdFrm.operand[20] = 0x00;
+ CmdFrm.operand[21] = 0x00;*/
+ CmdFrm.operand[22] = pidc; // Nr_of_dsd_sel_specs
+
+ pos=23;
+ }
+ if(pidc != 0xFF)
+ for(k=0;k<pidc;k++) {
+ CmdFrm.operand[pos++] = 0x13; // flowfunction relay
+ CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
+ CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F;
+ CmdFrm.operand[pos++] = pid[k] & 0xFF;
+ CmdFrm.operand[pos++] = 0x00; // tableID
+ CmdFrm.operand[pos++] = 0x00; // filter_length
+ }
+
+ CmdFrm.length = pos+3;
+
+ if((pos+3)%4)
+ CmdFrm.length += 4 - ((pos+3)%4);
+
+ if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
+ return k;
+
+ mdelay(250);
+
+ return 0;
+}
+
+int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+
+ memset(&CmdFrm,0,sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = CONTROL;
+ CmdFrm.sutyp = 0x5; // tuner
+ CmdFrm.suid = firesat->subunit;
+ CmdFrm.opcode = READ_DESCRIPTOR;
+
+ CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER;
+ CmdFrm.operand[1]=0xff;
+ CmdFrm.operand[2]=0x00;
+ CmdFrm.operand[3]=0x00; // length highbyte
+ CmdFrm.operand[4]=0x08; // length lowbyte
+ CmdFrm.operand[5]=0x00; // offset highbyte
+ CmdFrm.operand[6]=0x0d; // offset lowbyte
+
+ CmdFrm.length=12;
+
+ if(AVCWrite(firesat,&CmdFrm,&RspFrm)<0)
+ return -EIO;
+
+ if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
+ printk("%s: AVCWrite returned error code %d\n",__FUNCTION__,RspFrm.resp);
+ return -EINVAL;
+ }
+ if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) {
+ printk("%s: Invalid response length\n",__FUNCTION__);
+ return -EINVAL;
+ }
+ if(systemId)
+ *systemId = RspFrm.operand[7];
+ if(transport)
+ *transport = RspFrm.operand[14] & 0x7;
+ switch(RspFrm.operand[14] & 0x7) {
+ case 1:
+ printk(KERN_INFO "%s: found DVB/S\n",__FUNCTION__);
+ break;
+ case 2:
+ printk(KERN_INFO "%s: found DVB/C\n",__FUNCTION__);
+ break;
+ case 3:
+ printk(KERN_INFO "%s: found DVB/T\n",__FUNCTION__);
+ break;
+ default:
+ printk(KERN_INFO "%s: found unknown tuner id %u\n",__FUNCTION__,RspFrm.operand[14] & 0x7);
+ }
+ if(has_ci)
+ *has_ci = (RspFrm.operand[14] >> 4) & 0x1;
+ return 0;
+}
+
+int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+ int length;
+
+ printk(KERN_INFO "%s\n", __FUNCTION__);
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts=AVC;
+ CmdFrm.ctype=CONTROL;
+ CmdFrm.sutyp=0x05; // tuner
+ CmdFrm.suid=firesat->subunit;
+ CmdFrm.opcode=READ_DESCRIPTOR;
+
+ CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS;
+ CmdFrm.operand[1]=0xff;
+ CmdFrm.operand[2]=0x00;
+ CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8;
+ CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF;
+ CmdFrm.operand[5]=0x00;
+ CmdFrm.operand[6]=0x03;
+ CmdFrm.length=12;
+ //Absenden des AVC request und warten auf response
+ if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
+ return -EIO;
+
+ if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
+ printk("%s: AVCWrite returned code %d\n",__FUNCTION__,RspFrm.resp);
+ return -EINVAL;
+ }
+
+ length = (RspFrm.operand[3] << 8) + RspFrm.operand[4];
+ if(length == sizeof(ANTENNA_INPUT_INFO))
+ {
+ memcpy(antenna_input_info,&RspFrm.operand[7],length);
+ return 0;
+ }
+ printk("%s: invalid info returned from AVC\n",__FUNCTION__);
+ return -EINVAL;
+}
+
+int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+ int i,j;
+
+ printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n",__FUNCTION__,voltage,burst,conttone);
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts=AVC;
+ CmdFrm.ctype=CONTROL;
+ CmdFrm.sutyp=0x05;
+ CmdFrm.suid=firesat->subunit;
+ CmdFrm.opcode=VENDOR;
+
+ /* ### should check for elgato and use SFE_VENDOR_EL_COMPANYID_0 in this case */
+ CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
+ CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
+ CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
+ CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL;
+
+ CmdFrm.operand[4]=voltage;
+ CmdFrm.operand[5]=nrdiseq;
+
+ i=6;
+
+ for(j=0;j<nrdiseq;j++) {
+ int k;
+ printk(KERN_INFO "%s: diseq %d len %x\n",__FUNCTION__,j,diseqcmd[j].msg_len);
+ CmdFrm.operand[i++]=diseqcmd[j].msg_len;
+
+ for(k=0;k<diseqcmd[j].msg_len;k++) {
+ printk(KERN_INFO "%s: diseq %d msg[%d] = %x\n",__FUNCTION__,j,k,diseqcmd[j].msg[k]);
+ CmdFrm.operand[i++]=diseqcmd[j].msg[k];
+ }
+ }
+
+ CmdFrm.operand[i++]=burst;
+ CmdFrm.operand[i++]=conttone;
+
+ CmdFrm.length=i+3;
+ if((i+3)%4)
+ CmdFrm.length += 4 - ((i+3)%4);
+
+/* for(j=0;j<CmdFrm.length;j++)
+ printk(KERN_INFO "%s: CmdFrm.operand[%d]=0x%x\n",__FUNCTION__,j,CmdFrm.operand[j]);
+
+ printk(KERN_INFO "%s: cmdfrm.length = %u\n",__FUNCTION__,CmdFrm.length);
+ */
+ if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
+ return -EIO;
+
+ if(RspFrm.resp != ACCEPTED) {
+ printk("%s: AVCWrite returned code %d\n",__FUNCTION__,RspFrm.resp);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int AVCSubUnitInfo(struct firesat*firesat, char *subunitcount) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = STATUS;
+ CmdFrm.sutyp = 0x1f;
+ CmdFrm.suid = 0x7;
+ CmdFrm.opcode = SUBUNIT_Info;
+
+ CmdFrm.operand[0] = 0x07;
+ CmdFrm.operand[1] = 0xff;
+ CmdFrm.operand[2] = 0xff;
+ CmdFrm.operand[3] = 0xff;
+ CmdFrm.operand[4] = 0xff;
+
+ CmdFrm.length = 8;
+
+ if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
+ return -EIO;
+
+ if(RspFrm.resp != STABLE) {
+ printk("%s: AVCWrite returned code %d\n",__FUNCTION__,RspFrm.resp);
+ return -EINVAL;
+ }
+
+ if(subunitcount)
+ *subunitcount = (RspFrm.operand[1] & 0x7) + 1;
+
+ return 0;
+}
+
+static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal) {
+ AVCCmdFrm CmdFrm;
+
+// printk(KERN_INFO "%s\n",__FUNCTION__);
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = NOTIFY;
+ CmdFrm.sutyp = 0x1f;
+ CmdFrm.suid = 0x7;
+ CmdFrm.opcode = VENDOR;
+
+ CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
+// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
+// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
+ CmdFrm.operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
+
+ CmdFrm.length = 8;
+
+ if(internal) {
+ if(__AVCWrite(firesat,&CmdFrm,NULL) < 0)
+ return -EIO;
+ } else
+ if(AVCWrite(firesat,&CmdFrm,NULL) < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int AVCRegisterRemoteControl(struct firesat*firesat) {
+ return __AVCRegisterRemoteControl(firesat, 0);
+}
+
+int AVCResetTPDU(struct firesat*firesat) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = CONTROL;
+ CmdFrm.sutyp = 0x05;
+ CmdFrm.suid = firesat->subunit;
+ CmdFrm.opcode = VENDOR;
+
+ CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
+// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
+// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
+ CmdFrm.operand[3] = SFE_VENDOR_OPCODE_CI_RESET;
+
+ CmdFrm.operand[4] = 0x00; // 0x00 = hard, 0x01 = soft
+
+ CmdFrm.length = 8;
+ if(AVCWrite(firesat, &CmdFrm, &RspFrm) < 0)
+ return -EIO;
+
+ if(RspFrm.resp != STABLE) {
+ printk("%s: AVCWrite returned error %d\n", __FUNCTION__, RspFrm.resp);
+ return RspFrm.resp;
+ }
+
+ return 0;
+}
+
+int AVCWriteTPDU(struct firesat*firesat, const char *tpdupacket, int length) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+
+ if(length < 0 || length > 505 || tpdupacket == NULL)
+ return -EINVAL;
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = CONTROL;
+ CmdFrm.sutyp = 0x05;
+ CmdFrm.suid = firesat->subunit;
+ CmdFrm.opcode = VENDOR;
+
+ CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
+// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
+// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
+ CmdFrm.operand[3] = SFE_VENDOR_OPCODE_CI_WRITE_TPDU;
+
+ memcpy(&CmdFrm.operand[6], tpdupacket, length);
+
+ CmdFrm.length = length + 9;
+ CmdFrm.operand[4] = (CmdFrm.length >> 8) & 0xFF;
+ CmdFrm.operand[5] = CmdFrm.length & 0xFF;
+
+ if(CmdFrm.length % 4)
+ CmdFrm.length += 4 - (CmdFrm.length % 4);
+
+ if(AVCWrite(firesat, &CmdFrm, &RspFrm) < 0)
+ return -EIO;
+
+ if(RspFrm.resp != STABLE) {
+ printk("%s: AVCWrite returned error %d\n",__FUNCTION__,RspFrm.resp);
+ return RspFrm.resp;
+ }
+ return 0;
+}
+
+int AVCReadTPDU(struct firesat*firesat, char *tpdupacket, int *length) {
+ AVCCmdFrm CmdFrm;
+ AVCRspFrm RspFrm;
+
+ if(!length || !tpdupacket)
+ return -EINVAL;
+
+ memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
+
+ CmdFrm.cts = AVC;
+ CmdFrm.ctype = STATUS;
+ CmdFrm.sutyp = 0x05;
+ CmdFrm.suid = firesat->subunit;
+ CmdFrm.opcode = VENDOR;
+
+// CmdFrm.operand[0] = SFE_VENDOR_EL_COMPANYID_0;
+ CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+// CmdFrm.operand[1] = SFE_VENDOR_EL_COMPANYID_1;
+ CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+// CmdFrm.operand[2] = SFE_VENDOR_EL_COMPANYID_2;
+ CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+// CmdFrm.operand[3] = SFE_VENDOR_OPCODE_CI_READ_TPDU;
+
+ CmdFrm.length = 8;
+
+ if(AVCWrite(firesat, &CmdFrm, &RspFrm) < 0)
+ return -EIO;
+
+ if(RspFrm.resp != STABLE) {
+ printk("%s: AVCWrite returned error %d\n",__FUNCTION__,RspFrm.resp);
+ return RspFrm.resp;
+ }
+
+ switch(RspFrm.operand[4]) {
+ case 0x00: {
+ int len = (RspFrm.operand[5] << 8) + RspFrm.operand[6];
+ if(len < *length)
+ *length = len;
+ if(*length > 0)
+ memcpy(tpdupacket, &RspFrm.operand[7], *length);
+ break;
+ }
+ case 0xFF:
+ printk("%s: No CI module present\n",__FUNCTION__);
+ return -EINVAL;
+ case 0xFE:
+ printk("%s: No CI data\n",__FUNCTION__);
+ *length = 0;
+ break;
+ case 0xFD:
+ printk("%s: CI error\n",__FUNCTION__);
+ return -EIO;
+ default:
+ printk("%s: unknown CI error\n",__FUNCTION__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
diff --git a/v4l_experimental/firesat/avc_api.h b/v4l_experimental/firesat/avc_api.h
new file mode 100644
index 000000000..7948a8f9d
--- /dev/null
+++ b/v4l_experimental/firesat/avc_api.h
@@ -0,0 +1,435 @@
+/***************************************************************************
+ avc_api.h - description
+ -------------------
+ begin : Wed May 1 2000
+ copyright : (C) 2000 by Manfred Weihs
+ copyright : (C) 2003 by Philipp Gutgsell
+ email : 0014guph@edu.fh-kaernten.ac.at
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/*
+ This is based on code written by Peter Halwachs, Thomas Groiss and Andreas Monitzer.
+*/
+
+
+#ifndef __AVC_API_H__
+#define __AVC_API_H__
+
+#include <linux/dvb/frontend.h>
+
+#define BYTE unsigned char
+#define WORD unsigned short
+#define DWORD unsigned long
+#define ULONG unsigned long
+#define LONG long
+
+
+/*************************************************************
+
+ FCP Address range
+
+**************************************************************/
+
+#define RESPONSE_REGISTER 0xFFFFF0000D00ULL
+#define COMMAND_REGISTER 0xFFFFF0000B00ULL
+#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
+
+
+/********************** ********************* ***************
+
+ definition of structures
+
+*************************************************************/
+
+typedef struct
+{
+ int Nr_SourcePlugs;
+ int Nr_DestinationPlugs;
+} TunerInfo;
+
+
+/***********************************************
+
+ supported cts
+
+************************************************/
+
+#define AVC 0x0
+
+// FCP command frame with ctype = 0x0 is AVC command frame
+
+#ifdef __LITTLE_ENDIAN
+
+// Definition FCP Command Frame
+typedef struct _AVCCmdFrm
+{
+ // AV/C command frame
+ BYTE ctype : 4 ; // command type
+ BYTE cts : 4 ; // always 0x0 for AVC
+ BYTE suid : 3 ; // subunit ID
+ BYTE sutyp : 5 ; // subunit_typ
+ BYTE opcode : 8 ; // opcode
+ BYTE operand[509] ; // array of operands [1-507]
+ int length; //length of the command frame
+} AVCCmdFrm ;
+
+// Definition FCP Response Frame
+typedef struct _AVCRspFrm
+{
+ // AV/C response frame
+ BYTE resp : 4 ; // response type
+ BYTE cts : 4 ; // always 0x0 for AVC
+ BYTE suid : 3 ; // subunit ID
+ BYTE sutyp : 5 ; // subunit_typ
+ BYTE opcode : 8 ; // opcode
+ BYTE operand[509] ; // array of operands [1-507]
+ int length; //length of the response frame
+} AVCRspFrm ;
+
+#else
+
+typedef struct _AVCCmdFrm
+{
+ BYTE cts:4;
+ BYTE ctype:4;
+ BYTE sutyp:5;
+ BYTE suid:3;
+ BYTE opcode;
+ BYTE operand[509];
+ int length;
+} AVCCmdFrm;
+
+typedef struct _AVCRspFrm
+{
+ BYTE cts:4;
+ BYTE resp:4;
+ BYTE sutyp:5;
+ BYTE suid:3;
+ BYTE opcode;
+ BYTE operand[509];
+ int length;
+} AVCRspFrm;
+
+#endif
+
+/*************************************************************
+
+
+ AVC command types (ctype)
+
+**************************************************************///
+
+
+#define CONTROL 0x00
+#define STATUS 0x01
+#define INQUIRY 0x02
+#define NOTIFY 0x03
+
+/*************************************************************
+
+ AVC respond types
+
+**************************************************************///
+
+#define NOT_IMPLEMENTED 0x8
+#define ACCEPTED 0x9
+#define REJECTED 0xA
+#define STABLE 0xC
+#define CHANGED 0xD
+#define INTERIM 0xF
+
+/*************************************************************
+
+ AVC FW UPDATE Responses
+
+**************************************************************///
+
+#define FW_INVALID_COUNT 0x4
+#define FW_INVALID_CRC 0x5
+#define FW_SUCCESS 0x6
+#define FW_ERROR 0x7
+#define FW_START_BURNING 0x8
+#define FW_INVALID_HW_VERSION 0x9
+
+/*************************************************************
+
+ AVC opcodes
+
+**************************************************************///
+#define CONNECT 0x24
+#define DISCONNECT 0x25
+#define UNIT_INFO 0x30
+#define SUBUNIT_Info 0x31
+#define VENDOR 0x00
+
+#define PLUG_INFO 0x02
+#define OPEN_DESCRIPTOR 0x08
+#define READ_DESCRIPTOR 0x09
+#define OBJECT_NUMBER_SELECT 0x0D
+
+/*************************************************************
+
+ AVCTuner opcodes
+
+**************************************************************/
+
+#define DSIT 0xC8
+#define DSD 0xCB
+#define DESCRIPTOR_TUNER_STATUS 0x80
+#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
+
+/*************************************************************
+
+ AVCTuner list types
+
+**************************************************************/
+
+#define Multiplex_List 0x80
+#define Service_List 0x82
+
+/*************************************************************
+
+ AVCTuner object entries
+
+**************************************************************/
+
+#define Multiplex 0x80
+#define Service 0x82
+#define Service_with_specified_components 0x83
+#define Preferred_components 0x90
+#define Component 0x84
+
+/*************************************************************
+
+ Vendor-specific commands
+
+**************************************************************/
+
+#define SFE_VENDOR_EL_COMPANYID_0 0x00
+#define SFE_VENDOR_EL_COMPANYID_1 0x0C
+#define SFE_VENDOR_EL_COMPANYID_2 0x6C
+#define SFE_VENDOR_DE_COMPANYID_0 0x00
+#define SFE_VENDOR_DE_COMPANYID_1 0x12
+#define SFE_VENDOR_DE_COMPANYID_2 0x87
+
+#define SFE_VENDOR_OPCODE_SET_LNB_PARAMS 0x50
+#define SFE_VENDOR_OPCODE_GET_LNB_PARAMS 0x51
+#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
+
+#define SFE_VENDOR_OPCODE_CI_READ_TPDU 0x54
+#define SFE_VENDOR_OPCODE_CI_WRITE_TPDU 0x53
+#define SFE_VENDOR_OPCODE_CI_RESET 0x55
+
+#define SFE_VENDOR_MAX_NR_COMPONENTS 0x4
+#define SFE_VENDOR_MAX_NR_SERVICES 0x3
+#define SFE_VENDOR_MAX_NR_DSD_ELEMENTS 0x10
+
+#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0A
+
+
+//AVCTuner DVB identifier service_ID
+
+#define DVB 0x20
+
+/*************************************************************
+
+ AVC descriptor types
+
+**************************************************************/
+
+#define Subunit_Identifier_Descriptor 0x00
+#define Tuner_Status_Descriptor 0x80
+
+typedef struct
+{
+ BYTE Subunit_Type;
+ BYTE Max_Subunit_ID;
+} SUBUNIT_INFO;
+
+/*************************************************************
+
+ AVCTuner DVB object IDs are 6 byte long
+
+**************************************************************/
+
+typedef struct
+{
+ BYTE Byte0;
+ BYTE Byte1;
+ BYTE Byte2;
+ BYTE Byte3;
+ BYTE Byte4;
+ BYTE Byte5;
+
+}OBJECT_ID;
+
+/*************************************************************
+
+ MULIPLEX Structs
+
+**************************************************************/
+typedef struct
+{
+#ifdef __LITTLE_ENDIAN
+ BYTE RF_frequency_hByte:6;
+ BYTE raster_Frequency:2;//Bit7,6 raster frequency
+#else
+ BYTE raster_Frequency:2;
+ BYTE RF_frequency_hByte:6;
+#endif
+ BYTE RF_frequency_mByte;
+ BYTE RF_frequency_lByte;
+
+}FREQUENCY;
+
+#ifdef __LITTLE_ENDIAN
+
+typedef struct
+{
+ BYTE Modulation :1;
+ BYTE FEC_inner :1;
+ BYTE FEC_outer :1;
+ BYTE Symbol_Rate :1;
+ BYTE Frequency :1;
+ BYTE Orbital_Pos :1;
+ BYTE Polarisation :1;
+ BYTE reserved_fields :1;
+ BYTE reserved1 :7;
+ BYTE Network_ID :1;
+
+}MULTIPLEX_VALID_FLAGS;
+
+typedef struct
+{
+ BYTE GuardInterval:1;
+ BYTE CodeRateLPStream:1;
+ BYTE CodeRateHPStream:1;
+ BYTE HierarchyInfo:1;
+ BYTE Constellation:1;
+ BYTE Bandwidth:1;
+ BYTE CenterFrequency:1;
+ BYTE reserved1:1;
+ BYTE reserved2:5;
+ BYTE OtherFrequencyFlag:1;
+ BYTE TransmissionMode:1;
+ BYTE NetworkId:1;
+}MULTIPLEX_VALID_FLAGS_DVBT;
+
+#else
+
+typedef struct
+{
+ BYTE reserved_fields:1;
+ BYTE Polarisation:1;
+ BYTE Orbital_Pos:1;
+ BYTE Frequency:1;
+ BYTE Symbol_Rate:1;
+ BYTE FEC_outer:1;
+ BYTE FEC_inner:1;
+ BYTE Modulation:1;
+ BYTE Network_ID:1;
+ BYTE reserved1:7;
+}MULTIPLEX_VALID_FLAGS;
+
+typedef struct
+{
+ BYTE reserved1:1;
+ BYTE CenterFrequency:1;
+ BYTE Bandwidth:1;
+ BYTE Constellation:1;
+ BYTE HierarchyInfo:1;
+ BYTE CodeRateHPStream:1;
+ BYTE CodeRateLPStream:1;
+ BYTE GuardInterval:1;
+ BYTE NetworkId:1;
+ BYTE TransmissionMode:1;
+ BYTE OtherFrequencyFlag:1;
+ BYTE reserved2:5;
+}MULTIPLEX_VALID_FLAGS_DVBT;
+
+#endif
+
+typedef union
+{
+
+ MULTIPLEX_VALID_FLAGS Bits;
+ MULTIPLEX_VALID_FLAGS_DVBT Bits_T;
+ struct
+ {
+ BYTE ByteHi;
+ BYTE ByteLo;
+ } Valid_Word;
+
+} M_VALID_FLAGS;
+
+typedef struct
+{
+#ifdef __LITTLE_ENDIAN
+ BYTE ActiveSystem;
+ BYTE reserved:5;
+ BYTE NoRF:1;
+ BYTE Moving:1;
+ BYTE Searching:1;
+
+ BYTE SelectedAntenna:7;
+ BYTE Input:1;
+
+ BYTE BER[4];
+
+ BYTE SignalStrength;
+ FREQUENCY Frequency;
+
+ BYTE ManDepInfoLength;
+#else
+ BYTE ActiveSystem;
+ BYTE Searching:1;
+ BYTE Moving:1;
+ BYTE NoRF:1;
+ BYTE reserved:5;
+
+ BYTE Input:1;
+ BYTE SelectedAntenna:7;
+
+ BYTE BER[4];
+
+ BYTE SignalStrength;
+ FREQUENCY Frequency;
+
+ BYTE ManDepInfoLength;
+#endif
+} ANTENNA_INPUT_INFO; // 11 Byte
+
+#define LNBCONTROL_DONTCARE 0xff
+
+extern int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm);
+extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
+
+extern int AVCTuner_DSIT(struct firesat *firesat,
+ int Source_Plug,
+ struct dvb_frontend_parameters *params,
+ BYTE *status);
+
+extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info);
+extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status);
+extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]);
+
+extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci);
+extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd);
+extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
+extern int AVCRegisterRemoteControl(struct firesat *firesat);
+
+extern int AVCResetTPDU(struct firesat *firesat);
+extern int AVCWriteTPDU(struct firesat *firesat, const char *tpdupacket, int length);
+extern int AVCReadTPDU(struct firesat *firesat, char *tpdupacket, int *length);
+
+#endif
+
diff --git a/v4l_experimental/firesat/cmp.c b/v4l_experimental/firesat/cmp.c
new file mode 100644
index 000000000..c302a4127
--- /dev/null
+++ b/v4l_experimental/firesat/cmp.c
@@ -0,0 +1,176 @@
+#include "cmp.h"
+#include <ieee1394.h>
+#include <nodemgr.h>
+#include <highlevel.h>
+#include <ohci1394.h>
+#include <hosts.h>
+#include <ieee1394_transactions.h>
+#include "avc_api.h"
+
+typedef struct _OPCR
+{
+ BYTE PTPConnCount : 6 ; // Point to point connect. counter
+ BYTE BrConnCount : 1 ; // Broadcast connection counter
+ BYTE OnLine : 1 ; // On Line
+
+ BYTE ChNr : 6 ; // Channel number
+ BYTE Res : 2 ; // Reserved
+
+ BYTE PayloadHi : 2 ; // Payoad high bits
+ BYTE OvhdID : 4 ; // Overhead ID
+ BYTE DataRate : 2 ; // Data Rate
+
+ BYTE PayloadLo ; // Payoad low byte
+} OPCR ;
+
+#define FIRESAT_SPEED IEEE1394_SPEED_400
+
+static int cmp_read(struct firesat *firesat, void *buffer, u64 addr, size_t length) {
+ int ret;
+ if(down_interruptible(&firesat->avc_sem))
+ return -EINTR;
+
+ ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation,
+ addr, buffer, length);
+
+ up(&firesat->avc_sem);
+ return ret;
+}
+
+static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, quadlet_t arg, int ext_tcode) {
+ int ret;
+ if(down_interruptible(&firesat->avc_sem))
+ return -EINTR;
+
+ ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation,
+ addr, ext_tcode, data, arg);
+
+ up(&firesat->avc_sem);
+ return ret;
+}
+
+//try establishing a point-to-point connection (may be interrupted by a busreset
+int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel) {
+ unsigned int BWU; //bandwidth to allocate
+
+ quadlet_t old_oPCR,test_oPCR = 0x0;
+ u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
+ int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
+
+ printk(KERN_INFO "%s: nodeid = %d\n",__FUNCTION__,firesat->nodeentry->nodeid);
+
+ if (result < 0) {
+ printk("%s: cannot read oPCR\n", __FUNCTION__);
+ return result;
+ } else {
+ printk(KERN_INFO "%s: oPCR = %08x\n",__FUNCTION__,test_oPCR);
+ do {
+ OPCR *hilf= (OPCR*) &test_oPCR;
+
+ if (!hilf->OnLine) {
+ printk("%s: Output offline; oPCR: %08x\n", __FUNCTION__, test_oPCR);
+ return -EBUSY;
+ } else {
+ quadlet_t new_oPCR;
+
+ old_oPCR=test_oPCR;
+ if (hilf->PTPConnCount) {
+ if (hilf->ChNr != iso_channel) {
+ printk("%s: Output plug has already connection on channel %u; cannot change it to channel %u\n",__FUNCTION__,hilf->ChNr,iso_channel);
+ return -EBUSY;
+ } else
+ printk(KERN_INFO "%s: Overlaying existing connection; connection counter was: %u\n",__FUNCTION__, hilf->PTPConnCount);
+ BWU=0; //we allocate no bandwidth (is this necessary?)
+ } else {
+ hilf->ChNr=iso_channel;
+ hilf->DataRate=FIRESAT_SPEED;
+
+ hilf->OvhdID=0; //FIXME: that is for worst case -> optimize
+ BWU=hilf->OvhdID?hilf->OvhdID*32:512;
+ BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
+/* if (allocate_1394_resources(iso_channel,BWU))
+ {
+ cout << "Allocation of resources failed\n";
+ return -2;
+ }*/
+ }
+
+ hilf->PTPConnCount++;
+ new_oPCR=test_oPCR;
+ printk(KERN_INFO "%s: trying compare_swap...\n",__FUNCTION__);
+ printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__FUNCTION__, old_oPCR, new_oPCR);
+ result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
+
+ if (result < 0) {
+ printk("%s: cannot compare_swap oPCR\n",__FUNCTION__);
+ return result;
+ }
+ if ((old_oPCR != test_oPCR) && (!((OPCR*) &old_oPCR)->PTPConnCount))
+ {
+ printk("%s: change of oPCR failed -> freeing resources\n",__FUNCTION__);
+// hilf= (OPCR*) &new_oPCR;
+// unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
+// BWU += (hilf->Payload+3) * (2 << (3-hilf->DataRate));
+/* if (deallocate_1394_resources(iso_channel,BWU))
+ {
+
+ cout << "Deallocation of resources failed\n";
+ return -3;
+ }*/
+ }
+ }
+ }
+ while (old_oPCR != test_oPCR);
+ }
+ return 0;
+}
+
+//try breaking a point-to-point connection (may be interrupted by a busreset
+int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel) {
+ quadlet_t old_oPCR,test_oPCR;
+
+ u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
+ int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
+
+ printk(KERN_INFO "%s\n",__FUNCTION__);
+
+ if (result < 0) {
+ printk("%s: cannot read oPCR\n", __FUNCTION__);
+ return result;
+ } else {
+ do {
+ OPCR *hilf= (OPCR*) &test_oPCR;
+
+ if (!hilf->OnLine || !hilf->PTPConnCount || hilf->ChNr != iso_channel) {
+ printk("%s: Output plug does not have PtP-connection on that channel; oPCR: %08x\n", __FUNCTION__, test_oPCR);
+ return -EINVAL;
+ } else {
+ quadlet_t new_oPCR;
+ old_oPCR=test_oPCR;
+ hilf->PTPConnCount--;
+ new_oPCR=test_oPCR;
+
+// printk(KERN_INFO "%s: trying compare_swap...\n", __FUNCTION__);
+ result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
+ if (result < 0) {
+ printk("%s: cannot compare_swap oPCR\n",__FUNCTION__);
+ return result;
+ }
+ }
+
+ } while (old_oPCR != test_oPCR);
+
+/* hilf = (OPCR*) &old_oPCR;
+ if (hilf->PTPConnCount == 1) { // if we were the last owner of this connection
+ cout << "deallocating 1394 resources\n";
+ unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
+ BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
+ if (deallocate_1394_resources(iso_channel,BWU))
+ {
+ cout << "Deallocation of resources failed\n";
+ return -3;
+ }
+ }*/
+ }
+ return 0;
+}
diff --git a/v4l_experimental/firesat/cmp.h b/v4l_experimental/firesat/cmp.h
new file mode 100644
index 000000000..d43fbc29f
--- /dev/null
+++ b/v4l_experimental/firesat/cmp.h
@@ -0,0 +1,9 @@
+#ifndef __FIRESAT__CMP_H_
+#define __FIRESAT__CMP_H_
+
+#include "firesat.h"
+
+extern int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel);
+extern int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel);
+
+#endif
diff --git a/v4l_experimental/firesat/firesat-ci.c b/v4l_experimental/firesat/firesat-ci.c
new file mode 100644
index 000000000..1fd96cf63
--- /dev/null
+++ b/v4l_experimental/firesat/firesat-ci.c
@@ -0,0 +1,124 @@
+#include "firesat-ci.h"
+#include "firesat.h"
+#include "avc_api.h"
+
+#include <linux/dvb/ca.h>
+
+#include "dvbdev.h"
+
+static int firesat_ca_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) {
+ struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
+ int err;
+
+// printk(KERN_INFO "%s: ioctl %d\n",__FUNCTION__,cmd);
+
+ switch(cmd) {
+ case CA_RESET:
+ err = AVCResetTPDU(firesat);
+// if(err==0)
+ mdelay(3000);
+ break;
+ case CA_GET_CAP: {
+ ca_caps_t *cap=(ca_caps_t*)parg;
+ cap->slot_num = 1;
+ cap->slot_type = CA_CI_LINK;
+ cap->descr_num = 1;
+ cap->descr_type = CA_DSS; // ### peter fragen!
+
+ err = 0;
+ break;
+ }
+ case CA_GET_SLOT_INFO: {
+ ca_slot_info_t *slot=(ca_slot_info_t*)parg;
+ if(slot->num == 0) {
+ slot->type = CA_CI | CA_CI_LINK | CA_DESCR;
+ slot->flags = CA_CI_MODULE_PRESENT | CA_CI_MODULE_READY;
+ } else {
+ slot->type = 0;
+ slot->flags = 0;
+ }
+ err = 0;
+ break;
+ }
+ default:
+ err=-EINVAL;
+ }
+ return err;
+}
+
+static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
+ return dvb_usercopy(inode, file, cmd, arg, firesat_ca_do_ioctl);
+}
+
+static ssize_t firesat_ca_io_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
+ struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
+ char *data=kmalloc(count,GFP_KERNEL);
+// printk(KERN_INFO "%s: count = %d\n",__FUNCTION__, count);
+ copy_from_user(data,buf,count);
+ int r=AVCWriteTPDU(firesat, data, count);
+ kfree(data);
+ if(!r)
+ return count;
+ printk("%s: failed writing data\n",__FUNCTION__);
+ return 0;
+}
+
+static ssize_t firesat_ca_io_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) {
+ struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
+ char *data=kmalloc(count,GFP_KERNEL);
+// printk(KERN_INFO "%s: count = %d\n",__FUNCTION__,count);
+ int r=AVCReadTPDU(firesat, data, &count);
+ if(!r) {
+ copy_to_user(buf,data,count);
+ kfree(data);
+ return count;
+ }
+ kfree(data);
+ return 0;
+}
+
+static int firesat_ca_io_open(struct inode *inode, struct file *file) {
+ printk(KERN_INFO "%s!\n",__FUNCTION__);
+ return dvb_generic_open(inode, file);
+}
+
+static int firesat_ca_io_release(struct inode *inode, struct file *file) {
+ printk(KERN_INFO "%s!\n",__FUNCTION__);
+ return dvb_generic_release(inode, file);
+}
+
+static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) {
+// printk(KERN_INFO "%s!\n",__FUNCTION__);
+ return POLLIN;
+}
+
+static struct file_operations firesat_ca_fops = {
+ .owner = THIS_MODULE,
+ .read = firesat_ca_io_read,
+ .write = firesat_ca_io_write,
+ .ioctl = firesat_ca_ioctl,
+ .open = firesat_ca_io_open,
+ .release = firesat_ca_io_release,
+ .poll = firesat_ca_io_poll,
+};
+
+static struct dvb_device firesat_ca = {
+ .priv = NULL,
+ .users = 1,
+ .readers = 1,
+ .writers = 1,
+ .fops = &firesat_ca_fops,
+};
+
+int firesat_ca_init(struct firesat *firesat) {
+ int ret = dvb_register_device(firesat->adapter, &firesat->cadev, &firesat_ca, firesat, DVB_DEVICE_CA);
+ if(ret) return ret;
+ AVCResetTPDU(firesat);
+ // avoid unnecessary delays, we're not talking to the CI yet anyways
+ return 0;
+}
+
+void firesat_ca_release(struct firesat *firesat) {
+ dvb_unregister_device(firesat->cadev);
+}
+
diff --git a/v4l_experimental/firesat/firesat-ci.h b/v4l_experimental/firesat/firesat-ci.h
new file mode 100644
index 000000000..dafe3f0f0
--- /dev/null
+++ b/v4l_experimental/firesat/firesat-ci.h
@@ -0,0 +1,9 @@
+#ifndef __FIRESAT_CA_H
+#define __FIRESAT_CA_H
+
+#include "firesat.h"
+
+int firesat_ca_init(struct firesat *firesat);
+void firesat_ca_release(struct firesat *firesat);
+
+#endif
diff --git a/v4l_experimental/firesat/firesat-rc.c b/v4l_experimental/firesat/firesat-rc.c
new file mode 100644
index 000000000..8cc57573d
--- /dev/null
+++ b/v4l_experimental/firesat/firesat-rc.c
@@ -0,0 +1,83 @@
+#include "firesat.h"
+#include "firesat-rc.h"
+
+#include <linux/input.h>
+
+static u16 firesat_irtable[] = {
+ KEY_ESC,
+ KEY_F9,
+ KEY_1,
+ KEY_2,
+ KEY_3,
+ KEY_4,
+ KEY_5,
+ KEY_6,
+ KEY_7,
+ KEY_8,
+ KEY_9,
+ KEY_I,
+ KEY_0,
+ KEY_ENTER,
+ KEY_RED,
+ KEY_UP,
+ KEY_GREEN,
+ KEY_F10,
+ KEY_SPACE,
+ KEY_F11,
+ KEY_YELLOW,
+ KEY_DOWN,
+ KEY_BLUE,
+ KEY_Z,
+ KEY_P,
+ KEY_PAGEDOWN,
+ KEY_LEFT,
+ KEY_W,
+ KEY_RIGHT,
+ KEY_P,
+ KEY_M,
+ KEY_R,
+ KEY_V,
+ KEY_C,
+ 0
+};
+
+static struct input_dev firesat_idev;
+
+int firesat_register_rc(void) {
+ int index;
+
+ memset(&firesat_idev, 0, sizeof(firesat_idev));
+
+ firesat_idev.evbit[0] = BIT(EV_KEY);
+
+ for(index=0;firesat_irtable[index] != 0; index++)
+ set_bit(firesat_irtable[index], firesat_idev.keybit);
+
+ input_register_device(&firesat_idev);
+
+ return 0;
+}
+
+int firesat_unregister_rc(void) {
+ input_unregister_device(&firesat_idev);
+ return 0;
+}
+
+int firesat_got_remotecontrolcode(u16 code) {
+ u16 keycode;
+
+ if(code > 0x4500 && code < 0x4520)
+ keycode = firesat_irtable[code - 0x4501];
+ else if(code > 0x453f && code < 0x4543)
+ keycode = firesat_irtable[code - 0x4521];
+ else {
+ printk("%s: invalid key code 0x%04x\n",__FUNCTION__,code);
+ return -EINVAL;
+ }
+
+ input_report_key(&firesat_idev, keycode, 1);
+ input_report_key(&firesat_idev, keycode, 0);
+
+ return 0;
+}
+
diff --git a/v4l_experimental/firesat/firesat-rc.h b/v4l_experimental/firesat/firesat-rc.h
new file mode 100644
index 000000000..e89a8069b
--- /dev/null
+++ b/v4l_experimental/firesat/firesat-rc.h
@@ -0,0 +1,9 @@
+#ifndef __FIRESAT_LIRC_H
+#define __FIRESAT_LIRC_H
+
+extern int firesat_register_rc(void);
+extern int firesat_unregister_rc(void);
+extern int firesat_got_remotecontrolcode(u16 code);
+
+#endif
+
diff --git a/v4l_experimental/firesat/firesat.c b/v4l_experimental/firesat/firesat.c
new file mode 100644
index 000000000..167c5a709
--- /dev/null
+++ b/v4l_experimental/firesat/firesat.c
@@ -0,0 +1,917 @@
+/*
+ * FireSAT DVB driver
+ *
+ * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/errno.h>
+#include <asm/semaphore.h>
+#include <ieee1394_hotplug.h>
+#include <nodemgr.h>
+#include <highlevel.h>
+#include <ohci1394.h>
+#include <hosts.h>
+
+/*#include "dvb_frontend.h"
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/dmx.h>*/
+#include "firesat.h"
+#include "avc_api.h"
+#include "cmp.h"
+#include "firesat-rc.h"
+#include "firesat-ci.h"
+
+#define FIRESAT_Vendor_ID 0x001287
+
+/*** HOTPLUG STUFF **********************************************************/
+/*
+ * Export information about protocols/devices supported by this driver.
+ */
+static struct ieee1394_device_id firesat_id_table[] = {
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+ .model_id = 0x11,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+ .model_id = 0x12,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x13,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x14,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x21,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x22,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x23,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x24,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x25,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x26,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x27,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x34,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x35,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ {
+ .match_flags = /*IEEE1394_MATCH_VENDOR_ID |*/ IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+// .vendor_id = FIRESAT_Vendor_ID & 0xffffff,
+// .vendor_id = 0x000000,
+ .model_id = 0x36,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff
+ },
+ { }
+};
+
+MODULE_DEVICE_TABLE(ieee1394, firesat_id_table);
+
+/* list of all firesat devices */
+LIST_HEAD(firesat_list);
+spinlock_t firesat_list_lock = SPIN_LOCK_UNLOCKED;
+
+static void firesat_add_host (struct hpsb_host *host);
+static void firesat_remove_host (struct hpsb_host *host);
+static void firesat_host_reset(struct hpsb_host *host);
+static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
+ size_t length);
+static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
+ int cts, u8 *data, size_t length);
+
+static struct hpsb_highlevel firesat_highlevel = {
+ .name = "FireSAT",
+ .add_host = firesat_add_host,
+ .remove_host = firesat_remove_host,
+ .host_reset = firesat_host_reset,
+ .iso_receive = iso_receive,
+ .fcp_request = fcp_request,
+};
+
+
+static struct dvb_frontend_info firesat_S_frontend_info = {
+ .name = "FireSAT DVB-S Frontend",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 125,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 40000000,
+ .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO | FE_CAN_QPSK,
+};
+
+static struct dvb_frontend_info firesat_C_frontend_info = {
+ .name = "FireSAT DVB-C Frontend",
+ .type = FE_QAM,
+ .frequency_min = 47000000,
+ .frequency_max = 866000000,
+ .frequency_stepsize = 62500,
+ .symbol_rate_min = 870000,
+ .symbol_rate_max = 6900000,
+ .caps = FE_CAN_INVERSION_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
+ FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 |
+ FE_CAN_QAM_AUTO,
+};
+
+static struct dvb_frontend_info firesat_T_frontend_info = {
+ .name = "FireSAT DVB-T Frontend",
+ .type = FE_OFDM,
+ .frequency_min = 49000000,
+ .frequency_max = 861000000,
+ .frequency_stepsize = 62500,
+ .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_2_3 |
+ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO,
+};
+
+static void firesat_add_host (struct hpsb_host *host) {
+ struct ti_ohci *ohci;
+// printk(KERN_INFO "FireSAT add_host (nodeid = 0x%x)\n",host->node_id);
+
+ /* We only work with the OHCI-1394 driver */
+ if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
+ return;
+
+ ohci = (struct ti_ohci *)host->hostdata;
+
+ if (!hpsb_create_hostinfo(&firesat_highlevel, host, 0)) {
+ printk(KERN_ERR "Cannot allocate hostinfo\n");
+ return;
+ }
+
+ hpsb_set_hostinfo(&firesat_highlevel, host, ohci);
+ hpsb_set_hostinfo_key(&firesat_highlevel, host, ohci->host->id);
+}
+
+static void firesat_remove_host (struct hpsb_host *host) {
+// printk(KERN_INFO "FireSAT remove_host (nodeid = 0x%x)\n",host->node_id);
+}
+
+static void firesat_host_reset(struct hpsb_host *host) {
+ printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active);
+}
+
+struct firewireheader {
+ union {
+ struct {
+ unsigned char tcode:4;
+ unsigned char sy:4;
+ unsigned char tag:2;
+ unsigned char channel:6;
+
+ unsigned char length_l;
+ unsigned char length_h;
+ } hdr;
+ unsigned long val;
+ };
+};
+
+struct CIPHeader {
+ union {
+ struct {
+ unsigned char syncbits:2;
+ unsigned char sid:6;
+ unsigned char dbs;
+ unsigned char fn:2;
+ unsigned char qpc:3;
+ unsigned char sph:1;
+ unsigned char rsv:2;
+ unsigned char dbc;
+ unsigned char syncbits2:2;
+ unsigned char fmt:6;
+ unsigned long fdf:24;
+ } cip;
+ unsigned long long val;
+ };
+};
+
+struct MPEG2Header {
+ union {
+ struct {
+ unsigned char sync; // must be 0x47
+ unsigned char transport_error_indicator:1;
+ unsigned char payload_unit_start_indicator:1;
+ unsigned char transport_priority:1;
+ unsigned short pid:13;
+ unsigned char transport_scrambling_control:2;
+ unsigned char adaption_field_control:2;
+ unsigned char continuity_counter:4;
+ } hdr;
+ unsigned long val;
+ };
+};
+
+static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
+ size_t length) {
+// printk(KERN_INFO "FireSAT iso_receive: channel %d, length = %d\n", channel, length);
+
+ if(length <= 12)
+ return; // ignore empty packets
+ else {
+ struct firesat *firesat=NULL;
+ struct firesat *firesat_entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_for_each_entry(firesat_entry,&firesat_list,list) {
+ if(firesat_entry->host == host && firesat_entry->isochannel == channel) {
+ firesat=firesat_entry;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+
+ if(firesat) {
+ char *buf=((char*)data) + sizeof(struct firewireheader)+sizeof(struct CIPHeader);
+ int count = (length-sizeof(struct CIPHeader)) / 192;
+
+// printk(KERN_INFO "%s: length = %u\n data[0] = %08x\n data[1] = %08x\n data[2] = %08x\n data[3] = %08x\n data[4] = %08x\n",__FUNCTION__, length, data[0],data[1],data[2],data[3],data[4]);
+
+ while (count--) {
+
+ if(buf[sizeof(quadlet_t) /*timestamp*/] == 0x47)
+ dvb_dmx_swfilter_packet(&firesat->demux, &buf[sizeof(quadlet_t)]);
+ else
+ printk("%s: invalid packet, skipping\n", __FUNCTION__);
+ buf += 188 + sizeof(quadlet_t) /* timestamp */;
+ }
+ }
+ }
+}
+
+static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
+ int cts, u8 *data, size_t length) {
+// printk(KERN_INFO "FireSAT fcp_request length=%d\n",length);
+ if(length>0 && ((data[0] & 0xF0) >> 4) == 0) {
+ struct firesat *firesat=NULL;
+ struct firesat *firesat_entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_for_each_entry(firesat_entry,&firesat_list,list) {
+ if(firesat_entry->host == host && firesat_entry->nodeentry->nodeid == nodeid && (firesat_entry->subunit == (data[1]&0x7) || (firesat_entry->subunit == 0 && (data[1]&0x7) == 0x7))) {
+ firesat=firesat_entry;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+
+ if(firesat)
+ AVCRecv(firesat,data,length);
+ else
+ printk("%s: received fcp request from unknown source, ignored\n",__FUNCTION__);
+ } // else ignore
+}
+
+static int firesat_frontend_ioctl(struct dvb_frontend *frontend,
+ unsigned int cmd, void *arg) {
+ struct firesat *firesat=frontend->data;
+
+ switch(cmd) {
+ case FE_INIT:
+ firesat->isochannel = firesat->adapter->num << 1 | (firesat->subunit & 0x1); // ### ask IRM
+ try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel);
+ hpsb_listen_channel(&firesat_highlevel, firesat->host, firesat->isochannel);
+ break;
+ case FE_SLEEP:
+ hpsb_unlisten_channel(&firesat_highlevel, firesat->host, firesat->isochannel);
+ try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel);
+ firesat->isochannel = -1;
+ break;
+ case FE_GET_INFO:
+// printk(KERN_INFO "FE_GET_INFO\n");
+ memcpy(arg, firesat->frontend_info,
+ sizeof (struct dvb_frontend_info));
+ break;
+ case FE_DISEQC_RESET_OVERLOAD:
+ case FE_DISEQC_RECV_SLAVE_REPLY:
+ return -EOPNOTSUPP;
+ case FE_DISEQC_SEND_MASTER_CMD:
+ return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, (struct dvb_diseqc_master_cmd *)arg);
+ return 0;
+ case FE_DISEQC_SEND_BURST:
+ return 0;
+// return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, (((fe_sec_mini_cmd_t)arg)==SEC_MINI_A)?0:1, LNBCONTROL_DONTCARE, 0, NULL);
+ case FE_SET_TONE:
+// return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, (((fe_sec_tone_mode_t) arg)==SEC_TONE_ON)?1:0, 0, NULL);
+ firesat->tone = (fe_sec_tone_mode_t)arg;
+ return 0;
+ case FE_SET_VOLTAGE:
+// printk(KERN_INFO "FE_SET_VOLTAGE\n");
+ firesat->voltage=(fe_sec_voltage_t) arg;
+ return 0;
+// return AVCLNBControl(firesat, ((fe_sec_voltage_t) arg, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 0, NULL);
+ case FE_ENABLE_HIGH_LNB_VOLTAGE:
+ return -EOPNOTSUPP;
+ case FE_READ_STATUS: {
+ ANTENNA_INPUT_INFO info;
+ fe_status_t *status = (fe_status_t *)arg;
+// printk(KERN_INFO "%s: FE_READ_STATUS\n", __FUNCTION__);
+
+ if(AVCTunerStatus(firesat,&info)) {
+ return -EINVAL;
+ }
+// printk(KERN_INFO "%s: NoRF=%c\n",__FUNCTION__,info.NoRF?'y':'n');
+ if(info.NoRF)
+ *status = 0;
+ else
+ *status = *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
+ FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
+
+ break;
+ }
+ case FE_READ_BER: {
+ ANTENNA_INPUT_INFO info;
+ u32 *ber = (u32 *)arg;
+// printk(KERN_INFO "%s: FE_READ_BER\n", __FUNCTION__);
+
+ if(AVCTunerStatus(firesat,&info)) {
+ return -EINVAL;
+ }
+
+// *ber = *(u32*)info.BER; /* might need some byte ordering correction */
+ *ber = ((info.BER[0] << 24) & 0xFF) | ((info.BER[1] << 16) & 0xFF) | ((info.BER[2] << 8) & 0xFF) | (info.BER[3] & 0xFF);
+
+ break;
+ }
+ case FE_READ_SIGNAL_STRENGTH: {
+ ANTENNA_INPUT_INFO info;
+ u16 *signal = (u16 *)arg;
+// printk(KERN_INFO "%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__);
+
+ if(AVCTunerStatus(firesat,&info)) {
+ return -EINVAL;
+ }
+
+ *signal = info.SignalStrength;
+
+ break;
+ }
+ case FE_READ_SNR:
+ case FE_READ_UNCORRECTED_BLOCKS:
+ return -EOPNOTSUPP;
+ case FE_SET_FRONTEND: {
+ struct dvb_frontend_parameters *p =
+ (struct dvb_frontend_parameters *)arg;
+// printk(KERN_INFO "FE_GET_INFO\n");
+
+// printk(KERN_INFO "%s: FE_SET_FRONTEND\n", __FUNCTION__);
+
+// printk(KERN_INFO " frequency->%d\n", p->frequency);
+// printk(KERN_INFO " symbol_rate->%d\n",p->u.qam.symbol_rate);
+// printk(KERN_INFO " inversion->%d\n", p->inversion);
+
+// if(AVCTuner_DSIT(firesat, 0/*###*/, p, NULL))
+// return -EINVAL;
+ if(AVCTuner_DSD(firesat, p, NULL) != ACCEPTED)
+ return -EINVAL;
+
+ break;
+ }
+ case FE_GET_FRONTEND:
+ case FE_GET_EVENT:
+ return -EOPNOTSUPP;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) {
+ int k;
+
+ printk(KERN_INFO "%s\n",__FUNCTION__);
+
+ if(down_interruptible(&firesat->demux_sem))
+ return NULL;
+
+ for(k=0;k<16;k++) {
+ printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__FUNCTION__,k,firesat->channel[k].active,firesat->channel[k].pid);
+ if(firesat->channel[k].active == 0) {
+ firesat->channel[k].active = 1;
+ up(&firesat->demux_sem);
+ return &firesat->channel[k];
+ }
+ }
+
+ up(&firesat->demux_sem);
+ return NULL; // no more channels available
+}
+
+static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]) {
+ int k, l=0;
+
+ if(down_interruptible(&firesat->demux_sem))
+ return -EINTR;
+
+ for(k=0;k<16;k++)
+ if(firesat->channel[k].active == 1)
+ pid[l++] = firesat->channel[k].pid;
+
+ up(&firesat->demux_sem);
+
+ *pidc = l;
+
+ return 0;
+}
+
+static int firesat_channel_release(struct firesat *firesat, struct firesat_channel *channel) {
+ if(down_interruptible(&firesat->demux_sem))
+ return -EINTR;
+
+ channel->active = 0;
+
+ up(&firesat->demux_sem);
+ return 0;
+}
+
+static int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) {
+ struct firesat *firesat=(struct firesat*)dvbdmxfeed->demux->priv;
+ struct firesat_channel *channel;
+ int pidc,k;
+ u16 pids[16];
+
+ printk(KERN_INFO "%s (pid %u)\n",__FUNCTION__,dvbdmxfeed->pid);
+
+ switch (dvbdmxfeed->type) {
+ case DMX_TYPE_TS:
+ case DMX_TYPE_SEC:
+ break;
+ default:
+ printk("%s: invalid type %u\n",__FUNCTION__,dvbdmxfeed->type);
+ return -EINVAL;
+ }
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS) {
+ switch (dvbdmxfeed->pes_type) {
+ case DMX_TS_PES_VIDEO:
+ case DMX_TS_PES_AUDIO:
+ case DMX_TS_PES_TELETEXT:
+ case DMX_TS_PES_PCR:
+ case DMX_TS_PES_OTHER:
+ channel = firesat_channel_allocate(firesat);
+ break;
+ default:
+ printk("%s: invalid pes type %u\n",__FUNCTION__,dvbdmxfeed->pes_type);
+ return -EINVAL;
+ }
+ } else {
+ channel = firesat_channel_allocate(firesat);
+ }
+
+ if(!channel) {
+ printk("%s: busy!\n",__FUNCTION__);
+ return -EBUSY;
+ }
+
+ dvbdmxfeed->priv = channel;
+
+ channel->dvbdmxfeed = dvbdmxfeed;
+ channel->pid = dvbdmxfeed->pid;
+ channel->type = dvbdmxfeed->type;
+ channel->firesat = firesat;
+
+ if(firesat_channel_collect(firesat, &pidc, pids)) {
+ firesat_channel_release(firesat, channel);
+ return -EINTR;
+ }
+
+ if((k=AVCTuner_SetPIDs(firesat, pidc, pids))) {
+ firesat_channel_release(firesat, channel);
+ printk("%s: AVCTuner failed with error %d\n",__FUNCTION__,k);
+ return k;
+ }
+
+ return 0;
+}
+
+static int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) {
+ struct dvb_demux *demux = dvbdmxfeed->demux;
+ struct firesat *firesat=(struct firesat*)demux->priv;
+ int k, l=0;
+ u16 pids[16];
+
+ printk(KERN_INFO "%s (pid %u)\n",__FUNCTION__,dvbdmxfeed->pid);
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
+ (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
+ if (dvbdmxfeed->ts_type & TS_DECODER) {
+ if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
+ !demux->pesfilter[dvbdmxfeed->pes_type])
+ return -EINVAL;
+ demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
+ demux->pesfilter[dvbdmxfeed->pes_type] = 0;
+ }
+ if (!(dvbdmxfeed->ts_type & TS_DECODER &&
+ dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) {
+ return 0;
+ }
+ }
+
+ if(down_interruptible(&firesat->demux_sem))
+ return -EINTR;
+
+ // list except channel to be removed
+ for(k=0;k<16;k++)
+ if(firesat->channel[k].active == 1 && &firesat->channel[k] != (struct firesat_channel*)dvbdmxfeed->priv)
+ pids[l++] = firesat->channel[k].pid;
+
+ if((k=AVCTuner_SetPIDs(firesat, l, pids))) {
+ up(&firesat->demux_sem);
+ return k;
+ }
+
+ ((struct firesat_channel*)dvbdmxfeed->priv)->active = 0;
+
+ up(&firesat->demux_sem);
+
+ return 0;
+}
+
+static int firesat_probe(struct device *dev) {
+ struct unit_directory *ud=container_of(dev, struct unit_directory, device);
+ struct firesat *firesat;
+ unsigned long flags;
+ int result;
+ unsigned char subunitcount=0xff,subunit;
+ struct firesat **firesats=kmalloc(sizeof(void*)*2,GFP_KERNEL);
+
+ if(!firesats) {
+ printk("%s: couldn't allocate memory.\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+// printk(KERN_INFO "FireSAT: Detected device with GUID %08lx%04lx%04lx\n",(unsigned long)((ud->ne->guid)>>32),(unsigned long)(ud->ne->guid & 0xFFFF),(unsigned long)ud->ne->guid_vendor_id);
+ printk(KERN_INFO "%s: loading device\n", __FUNCTION__);
+
+ firesats[0]=NULL;
+ firesats[1]=NULL;
+
+ ud->device.driver_data = firesats;
+
+ for(subunit=0;subunit<subunitcount;subunit++) {
+ if (!(firesat = kmalloc(sizeof(struct firesat), GFP_KERNEL))) {
+ printk("%s: couldn't allocate memory.\n", __FUNCTION__);
+ kfree(firesats);
+ return -ENOMEM;
+ }
+
+ memset(firesat, 0, sizeof(struct firesat));
+ firesat->host=ud->ne->host;
+ firesat->guid=ud->ne->guid;
+ firesat->guid_vendor_id=ud->ne->guid_vendor_id;
+ firesat->nodeentry=ud->ne;
+ firesat->isochannel=-1;
+ firesat->tone = 0xff;
+ firesat->voltage = 0xff;
+ if(!(firesat->respfrm = kmalloc(sizeof(AVCRspFrm), GFP_KERNEL))) {
+ printk("%s: couldn't allocate memory.\n", __FUNCTION__);
+ kfree(firesat);
+ return -ENOMEM;
+ }
+
+ sema_init(&firesat->avc_sem, 1);
+ atomic_set(&firesat->avc_reply_received, 1);
+ sema_init(&firesat->demux_sem, 1);
+ atomic_set(&firesat->reschedule_remotecontrol, 0);
+
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ INIT_LIST_HEAD(&firesat->list);
+ list_add_tail(&firesat->list, &firesat_list);
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+
+ if(subunit == 0) {
+ firesat->subunit = 0x7; // 0x7 = don't care
+ if(AVCSubUnitInfo(firesat, &subunitcount)) {
+ printk("%s: AVC subunit info command failed.\n",__FUNCTION__);
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_del(&firesat->list);
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+ kfree(firesat);
+ return -EIO;
+ }
+ }
+
+ printk(KERN_INFO "%s: subunit count = %d\n",__FUNCTION__,subunitcount);
+
+ firesat->subunit=subunit;
+
+ if(AVCIdentifySubunit(firesat,NULL,(int*)&firesat->type,&firesat->has_ci)) {
+ printk("%s: cannot identify subunit %d\n",__FUNCTION__,subunit);
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_del(&firesat->list);
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+ kfree(firesat);
+ continue;
+ }
+ firesat->has_ci=1; // TEMP workaround
+
+ switch(firesat->type) {
+ case FireSAT_DVB_S:
+ firesat->model_name="FireSAT DVB-S";
+ firesat->frontend_info=&firesat_S_frontend_info;
+ break;
+ case FireSAT_DVB_C:
+ firesat->model_name="FireSAT DVB-C";
+ firesat->frontend_info=&firesat_C_frontend_info;
+ break;
+ case FireSAT_DVB_T:
+ firesat->model_name="FireSAT DVB-T";
+ firesat->frontend_info=&firesat_T_frontend_info;
+ break;
+ default:
+ printk("%s: unknown model type 0x%x on subunit %d!\n",__FUNCTION__,firesat->type,subunit);
+ firesat->model_name="Unknown";
+ firesat->frontend_info=NULL;
+ }
+ if(!firesat->frontend_info) {
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_del(&firesat->list);
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+ kfree(firesat);
+ continue;
+ }
+
+ if ((result = dvb_register_adapter(&firesat->adapter,
+ firesat->model_name, THIS_MODULE)) < 0) {
+ printk("%s: dvb_register_adapter failed: error %d\n",
+ __FUNCTION__, result);
+
+ /* ### cleanup */
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_del(&firesat->list);
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+ kfree(firesat);
+
+ return result;
+ }
+
+ firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
+
+ firesat->demux.priv = (void *)firesat;
+ firesat->demux.filternum = 16;
+ firesat->demux.feednum = 16;
+ firesat->demux.start_feed = firesat_start_feed;
+ firesat->demux.stop_feed = firesat_stop_feed;
+
+ firesat->demux.write_to_decoder = NULL;
+
+ if ((result = dvb_dmx_init(&firesat->demux)) < 0) {
+ printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
+ result);
+
+ dvb_unregister_adapter(firesat->adapter);
+
+ return result;
+ }
+
+ firesat->dmxdev.filternum = 16;
+ firesat->dmxdev.demux = &firesat->demux.dmx;
+ firesat->dmxdev.capabilities = 0;
+
+ if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) {
+ printk("%s: dvb_dmxdev_init failed: error %d\n",
+ __FUNCTION__, result);
+
+ dvb_dmx_release(&firesat->demux);
+ dvb_unregister_adapter(firesat->adapter);
+
+ return result;
+ }
+
+ firesat->frontend.source = DMX_FRONTEND_0;
+
+ if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx,
+ &firesat->frontend)) < 0) {
+ printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
+ result);
+
+ dvb_dmxdev_release(&firesat->dmxdev);
+ dvb_dmx_release(&firesat->demux);
+ dvb_unregister_adapter(firesat->adapter);
+
+ return result;
+ }
+
+ if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx,
+ &firesat->frontend)) < 0) {
+ printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
+ result);
+
+ firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend);
+ dvb_dmxdev_release(&firesat->dmxdev);
+ dvb_dmx_release(&firesat->demux);
+ dvb_unregister_adapter(firesat->adapter);
+
+ return result;
+ }
+
+ dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx);
+
+ if((result= dvb_register_frontend(firesat_frontend_ioctl,firesat->adapter,firesat,firesat->frontend_info,THIS_MODULE)) < 0) {
+ printk("%s: dvb_register_frontend_new failed: error %d\n", __FUNCTION__, result);
+ /* ### cleanup */
+
+ return result;
+ }
+
+ if(firesat->has_ci)
+ firesat_ca_init(firesat);
+
+ firesats[subunit] = firesat;
+ } // loop fuer alle tuner am board
+
+ if(firesats[0])
+ AVCRegisterRemoteControl(firesats[0]);
+
+ return 0;
+}
+
+static int firesat_remove(struct device *dev) {
+ struct unit_directory *ud=container_of(dev, struct unit_directory, device);
+ struct firesat **firesats=ud->device.driver_data;
+
+ if(firesats) {
+ int k;
+ for(k=0;k<2;k++)
+ if(firesats[k]) {
+ unsigned long flags;
+ if(firesats[k]->has_ci)
+ firesat_ca_release(firesats[k]);
+ dvb_unregister_frontend(firesat_frontend_ioctl,firesats[k]->adapter);
+
+ dvb_net_release(&firesats[k]->dvbnet);
+ firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx);
+ firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend);
+ dvb_dmxdev_release(&firesats[k]->dmxdev);
+ dvb_dmx_release(&firesats[k]->demux);
+ dvb_unregister_adapter(firesats[k]->adapter);
+
+ spin_lock_irqsave(&firesat_list_lock, flags);
+ list_del(&firesats[k]->list);
+ spin_unlock_irqrestore(&firesat_list_lock, flags);
+
+ kfree(firesats[k]->respfrm);
+ kfree(firesats[k]);
+ }
+ kfree(firesats);
+ } else
+ printk("%s: can't get firesat handle\n",__FUNCTION__);
+
+ printk(KERN_INFO "FireSAT: Removing device with vendor id 0x%x, model id 0x%x.\n",ud->vendor_id,ud->model_id);
+ return 0;
+}
+
+static int firesat_update(struct unit_directory *ud) {
+// printk(KERN_INFO "FireSAT: Found device with vendor id 0x%x, model id 0x%x\n", ud->vendor_id,ud->model_id);
+ struct firesat **firesats=ud->device.driver_data;
+ int k;
+ // loop over subunits
+
+ for(k=0;k<2;k++)
+ if(firesats[k]) {
+ firesats[k]->nodeentry=ud->ne;
+
+ if(firesats[k]->isochannel >= 0)
+ try_CMPEstablishPPconnection(firesats[k], firesats[k]->subunit, firesats[k]->isochannel);
+ }
+
+ return 0;
+}
+
+static struct hpsb_protocol_driver firesat_driver = {
+ .name = "FireSAT DVB",
+ .id_table = firesat_id_table,
+ .update = firesat_update,
+ .driver = {
+ .name = "firesat",
+ .bus = &ieee1394_bus_type,
+ .probe = firesat_probe,
+ .remove = firesat_remove,
+ },
+};
+
+static int __init firesat_init(void)
+{
+ int ret;
+ printk("FireSAT loaded\n");
+ hpsb_register_highlevel(&firesat_highlevel);
+ ret = hpsb_register_protocol(&firesat_driver);
+ if(ret) {
+ printk(KERN_ERR "FireSAT: failed to register protocol\n");
+ hpsb_unregister_highlevel(&firesat_highlevel);
+ return ret;
+ }
+
+ if((ret=firesat_register_rc()))
+ printk("%s: firesat_register_rc return error code %d (ignored)\n",__FUNCTION__,ret);
+
+ return 0;
+}
+
+static void __exit firesat_exit(void){
+ firesat_unregister_rc();
+
+ hpsb_unregister_protocol(&firesat_driver);
+ hpsb_unregister_highlevel(&firesat_highlevel);
+ printk("FireSAT quit\n");
+}
+
+module_init(firesat_init);
+module_exit(firesat_exit);
+
+MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
+MODULE_DESCRIPTION("FireSAT DVB Driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("FireSAT DVB");
diff --git a/v4l_experimental/firesat/firesat.h b/v4l_experimental/firesat/firesat.h
new file mode 100644
index 000000000..c3a614b2a
--- /dev/null
+++ b/v4l_experimental/firesat/firesat.h
@@ -0,0 +1,72 @@
+#ifndef __FIRESAT_H
+#define __FIRESAT_H
+
+#include "dvb_frontend.h"
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/dmx.h>
+
+enum model_type {
+ FireSAT_DVB_S = 1,
+ FireSAT_DVB_C = 2,
+ FireSAT_DVB_T = 3
+};
+
+struct firesat {
+ struct dvb_demux dvb_demux;
+ char *model_name;
+
+ /* DVB bits */
+ struct dvb_adapter *adapter;
+ struct dmxdev dmxdev;
+ struct dvb_demux demux;
+ struct dmx_frontend frontend;
+ struct dvb_net dvbnet;
+ struct dvb_frontend_info *frontend_info;
+
+ struct dvb_device *cadev;
+ int has_ci;
+
+ struct semaphore avc_sem;
+ atomic_t avc_reply_received;
+
+ atomic_t reschedule_remotecontrol;
+
+ struct firesat_channel {
+ struct firesat *firesat;
+ struct dvb_demux_feed *dvbdmxfeed;
+
+ int active;
+ int id;
+ int pid;
+ int type; /* 1 - TS, 2 - Filter */
+ } channel[16];
+ struct semaphore demux_sem;
+
+ /* needed by avc_api */
+ void *respfrm;
+ int resp_length;
+
+// nodeid_t nodeid;
+ struct hpsb_host *host;
+ u64 guid; /* GUID of this node */
+ u32 guid_vendor_id; /* Top 24bits of guid */
+ struct node_entry *nodeentry;
+
+ enum model_type type;
+ char subunit;
+ fe_sec_voltage_t voltage;
+ fe_sec_tone_mode_t tone;
+
+ int isochannel;
+
+ struct list_head list;
+};
+
+extern struct list_head firesat_list;
+extern spinlock_t firesat_list_lock;
+
+#endif
diff --git a/v4l_experimental/xc3028/convert.c b/v4l_experimental/xc3028/convert.c
index 00b1f7d9d..2559bba5e 100644
--- a/v4l_experimental/xc3028/convert.c
+++ b/v4l_experimental/xc3028/convert.c
@@ -3,13 +3,14 @@
#include <stdlib.h>
#define ARRAY_SIZE(fw) sizeof(fw)/sizeof(fw[0])
+
struct{
char *fwname;
char *fwstart;
char *fwstart2;
int length1;
int length2;
-} xc_firmware[]={{"Terratec","\x2a\x03\xe5\xe0\x00\x07\xf4\xd0\x01\xc0\x70\xe0\x00\x07","\x2a\x00\xc3\xe0\x00\x07\xb9\xf1\x05\x01\x6e\x82\x02\x82",2480,3876},
+} xc_firmware[]={{"Terratec","\x2a\x03\xe5\xe0\x00\x07\xf4\xd0\x01\xc0\x70\xe0\x00\x07","\x2a\x00\xbc\xe0\x00\x07\xb0\xf1\x05\x01\x67\x82\x02\x82",2480,3890},
{"Hauppauge","\x2a\x03\xcc\xe0\x00\x07\xf4\xd0\x01\xc0\x70\xe0\x00\x07","\x2a\x00\xbe\xe0\x00\x07\xb9\xf1\x05\x01\x69\x82\x02\x82",2532,3886}};
int main(int argc, char **argv){
@@ -29,6 +30,10 @@ int main(int argc, char **argv){
exit(1);
}
file=fopen(argv[1],"r");
+ if(!file){
+ printf("unable to open file\n");
+ exit(1);
+ }
fprintf(stderr,"Firmware extractor 0.1\n");
while((len=fread(buffer,1,1024,file))){
fleng+=len;