aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 15:36:37 +0100
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 15:36:37 +0100
commit2fc2991175bf77395e6b15fe6b2304d3bf72da40 (patch)
treeb0ff38c09240e7c00e1577d447ebe89143d752dc /drivers/media/dvb
parent[MTD] mtdchar: Return EINVAL for bad seeks instead of fixing up to valid byte (diff)
parent[PATCH] nvidiafb: Geforce 7800 series support added (diff)
downloadlinux-dev-2fc2991175bf77395e6b15fe6b2304d3bf72da40.tar.xz
linux-dev-2fc2991175bf77395e6b15fe6b2304d3bf72da40.zip
Merge branch 'master' of /home/tglx/work/mtd/git/linux-2.6.git/
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c102
-rw-r--r--drivers/media/dvb/b2c2/flexcop-i2c.c3
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig6
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c4
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h2
-rw-r--r--drivers/media/dvb/bt8xx/dst.c763
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c554
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h8
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c282
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h2
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig2
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c178
-rw-r--r--drivers/media/dvb/dvb-core/demux.h36
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c20
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c532
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h116
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c9
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig23
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c2
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c68
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h27
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c21
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c20
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c2
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c42
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c25
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c5
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h10
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c20
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c50
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h7
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c2
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c339
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c290
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.h109
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c9
-rw-r--r--drivers/media/dvb/frontends/Kconfig2
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c3
-rw-r--r--drivers/media/dvb/frontends/cx24110.c22
-rw-r--r--drivers/media/dvb/frontends/cx24110.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c3
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c3
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c16
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h1
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c2
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c530
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h16
-rw-r--r--drivers/media/dvb/frontends/lgdt330x_priv.h8
-rw-r--r--drivers/media/dvb/frontends/mt312.c2
-rw-r--r--drivers/media/dvb/frontends/mt352.c8
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c2
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c9
-rw-r--r--drivers/media/dvb/frontends/or51132.c29
-rw-r--r--drivers/media/dvb/frontends/or51211.c2
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c164
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h3
-rw-r--r--drivers/media/dvb/frontends/sp8870.c2
-rw-r--r--drivers/media/dvb/frontends/sp887x.c2
-rw-r--r--drivers/media/dvb/frontends/stv0297.c131
-rw-r--r--drivers/media/dvb/frontends/stv0297.h8
-rw-r--r--drivers/media/dvb/frontends/stv0299.c20
-rw-r--r--drivers/media/dvb/frontends/stv0299.h4
-rw-r--r--drivers/media/dvb/frontends/tda10021.c4
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c7
-rw-r--r--drivers/media/dvb/frontends/tda8083.c1
-rw-r--r--drivers/media/dvb/frontends/tda80xx.c1
-rw-r--r--drivers/media/dvb/frontends/ves1820.c15
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c1
-rw-r--r--drivers/media/dvb/ttpci/Kconfig3
-rw-r--r--drivers/media/dvb/ttpci/av7110.c201
-rw-r--r--drivers/media/dvb/ttpci/av7110.h11
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c8
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c165
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c74
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c9
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c221
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c5
-rw-r--r--drivers/media/dvb/ttpci/budget.c6
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c13
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c52
86 files changed, 3379 insertions, 2117 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 0410cc96a48e..47e28b0ee951 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -164,12 +164,11 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate,
return 0;
}
-static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
u8 buf[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- struct flexcop_device *fc = fe->dvb->priv;
div = params->frequency / 125;
@@ -180,7 +179,7 @@ static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_fronten
if (params->frequency < 1500000) buf[3] |= 0x10;
- if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -335,8 +334,103 @@ static struct mt312_config skystar23_samsung_tbdu18132_config = {
.pll_set = skystar23_samsung_tbdu18132_pll_set,
};
+
+static u8 alps_tdee4_stv0297_inittab[] = {
+ 0x80, 0x01,
+ 0x80, 0x00,
+ 0x81, 0x01,
+ 0x81, 0x00,
+ 0x00, 0x09,
+ 0x01, 0x69,
+ 0x03, 0x00,
+ 0x04, 0x00,
+ 0x07, 0x00,
+ 0x08, 0x00,
+ 0x20, 0x00,
+ 0x21, 0x40,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x40,
+ 0x25, 0x88,
+ 0x30, 0xff,
+ 0x31, 0x00,
+ 0x32, 0xff,
+ 0x33, 0x00,
+ 0x34, 0x50,
+ 0x35, 0x7f,
+ 0x36, 0x00,
+ 0x37, 0x20,
+ 0x38, 0x00,
+ 0x40, 0x1c,
+ 0x41, 0xff,
+ 0x42, 0x29,
+ 0x43, 0x00,
+ 0x44, 0xff,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x49, 0x04,
+ 0x4a, 0x00,
+ 0x4b, 0xf8,
+ 0x52, 0x30,
+ 0x55, 0xae,
+ 0x56, 0x47,
+ 0x57, 0xe1,
+ 0x58, 0x3a,
+ 0x5a, 0x1e,
+ 0x5b, 0x34,
+ 0x60, 0x00,
+ 0x63, 0x00,
+ 0x64, 0x00,
+ 0x65, 0x00,
+ 0x66, 0x00,
+ 0x67, 0x00,
+ 0x68, 0x00,
+ 0x69, 0x00,
+ 0x6a, 0x02,
+ 0x6b, 0x00,
+ 0x70, 0xff,
+ 0x71, 0x00,
+ 0x72, 0x00,
+ 0x73, 0x00,
+ 0x74, 0x0c,
+ 0x80, 0x00,
+ 0x81, 0x00,
+ 0x82, 0x00,
+ 0x83, 0x00,
+ 0x84, 0x04,
+ 0x85, 0x80,
+ 0x86, 0x24,
+ 0x87, 0x78,
+ 0x88, 0x10,
+ 0x89, 0x00,
+ 0x90, 0x01,
+ 0x91, 0x01,
+ 0xa0, 0x04,
+ 0xa1, 0x00,
+ 0xa2, 0x00,
+ 0xb0, 0x91,
+ 0xb1, 0x0b,
+ 0xc0, 0x53,
+ 0xc1, 0x70,
+ 0xc2, 0x12,
+ 0xd0, 0x00,
+ 0xd1, 0x00,
+ 0xd2, 0x00,
+ 0xd3, 0x00,
+ 0xd4, 0x00,
+ 0xd5, 0x00,
+ 0xde, 0x00,
+ 0xdf, 0x00,
+ 0x61, 0x49,
+ 0x62, 0x0b,
+ 0x53, 0x08,
+ 0x59, 0x08,
+ 0xff, 0xff,
+};
+
static struct stv0297_config alps_tdee4_stv0297_config = {
.demod_address = 0x1c,
+ .inittab = alps_tdee4_stv0297_inittab,
// .invert = 1,
// .pll_set = alps_tdee4_stv0297_pll_set,
};
@@ -370,7 +464,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
} else
/* try the cable dvb (stv0297) */
- if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) {
+ if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_CABLE;
info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
} else
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
index be4266d4ae91..56495cb6cd02 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -172,8 +172,6 @@ static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
}
static struct i2c_algorithm flexcop_algo = {
- .name = "FlexCop I2C algorithm",
- .id = I2C_ALGO_BIT,
.master_xfer = flexcop_master_xfer,
.functionality = flexcop_i2c_func,
};
@@ -192,7 +190,6 @@ int flexcop_i2c_init(struct flexcop_device *fc)
fc->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
fc->i2c_adap.algo = &flexcop_algo;
fc->i2c_adap.algo_data = NULL;
- fc->i2c_adap.id = I2C_ALGO_BIT;
if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0)
return ret;
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index b12545f093f8..1e85d16491b0 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -1,5 +1,5 @@
config DVB_BT8XX
- tristate "Nebula/Pinnacle PCTV/Twinhan PCI cards"
+ tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && VIDEO_BT848
select DVB_MT352
select DVB_SP887X
@@ -8,8 +8,8 @@ config DVB_BT8XX
select DVB_OR51211
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
- the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and
- pcHDTV HD2000 cards.
+ the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
+ the pcHDTV HD2000 cards, and certain AVerMedia cards.
Since these cards have no MPEG decoder onboard, they transmit
only compressed MPEG data over the PCI bus, so you need
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index 3c5a8e273c4a..f29571450038 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -1,7 +1,7 @@
/*
* bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
*
- * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
+ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
*
* large parts based on the bttv driver
* Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de)
@@ -219,7 +219,7 @@ void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
controlreg &= ~0x1f;
controlreg |= 0x1b;
- btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START);
+ btwrite(bt->risc_dma, BT878_ARISC_START);
/* original int mask had :
* 6 2 8 4 0
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index 837623f7fcdf..a73baf00ca39 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -1,7 +1,7 @@
/*
bt878.h - Bt878 audio module (register offsets)
- Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
+ Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
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
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 07a0b0a968a6..34a837a1abf4 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1,5 +1,4 @@
/*
-
Frontend/Card driver for TwinHan DST Frontend
Copyright (C) 2003 Jamie Honan
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
@@ -19,7 +18,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -28,31 +26,45 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <asm/div64.h>
-
#include "dvb_frontend.h"
#include "dst_priv.h"
#include "dst_common.h"
-
static unsigned int verbose = 1;
module_param(verbose, int, 0644);
MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
-static unsigned int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)");
-
static unsigned int dst_addons;
module_param(dst_addons, int, 0644);
MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
-#define dprintk if (debug) printk
-
-#define HAS_LOCK 1
-#define ATTEMPT_TUNE 2
-#define HAS_POWER 4
-
-static void dst_packsize(struct dst_state* state, int psize)
+#define HAS_LOCK 1
+#define ATTEMPT_TUNE 2
+#define HAS_POWER 4
+
+#define DST_ERROR 0
+#define DST_NOTICE 1
+#define DST_INFO 2
+#define DST_DEBUG 3
+
+#define dprintk(x, y, z, format, arg...) do { \
+ if (z) { \
+ if ((x > DST_ERROR) && (x > y)) \
+ printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_NOTICE) && (x > y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_INFO) && (x > y)) \
+ printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_DEBUG) && (x > y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \
+ } else { \
+ if (x > y) \
+ printk(format, ##arg); \
+ } \
+} while(0)
+
+
+static void dst_packsize(struct dst_state *state, int psize)
{
union dst_gpio_packet bits;
@@ -60,7 +72,7 @@ static void dst_packsize(struct dst_state* state, int psize)
bt878_device_control(state->bt, DST_IG_TS, &bits);
}
-int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay)
+int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, u32 outhigh, int delay)
{
union dst_gpio_packet enb;
union dst_gpio_packet bits;
@@ -68,63 +80,55 @@ int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int
enb.enb.mask = mask;
enb.enb.enable = enbb;
- if (verbose > 4)
- dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh);
+ dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh);
if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
- dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb);
+ dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb);
return -EREMOTEIO;
}
udelay(1000);
/* because complete disabling means no output, no need to do output packet */
if (enbb == 0)
return 0;
-
if (delay)
msleep(10);
-
bits.outp.mask = enbb;
bits.outp.highvals = outhigh;
-
if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
- dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh);
+ dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh);
return -EREMOTEIO;
}
+
return 0;
}
EXPORT_SYMBOL(dst_gpio_outb);
-int dst_gpio_inb(struct dst_state *state, u8 * result)
+int dst_gpio_inb(struct dst_state *state, u8 *result)
{
union dst_gpio_packet rd_packet;
int err;
*result = 0;
-
if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
- dprintk("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err);
return -EREMOTEIO;
}
-
*result = (u8) rd_packet.rd.value;
+
return 0;
}
EXPORT_SYMBOL(dst_gpio_inb);
int rdc_reset_state(struct dst_state *state)
{
- if (verbose > 1)
- dprintk("%s: Resetting state machine\n", __FUNCTION__);
-
+ dprintk(verbose, DST_INFO, 1, "Resetting state machine");
if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
-
msleep(10);
-
if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
msleep(10);
return -1;
}
@@ -135,16 +139,14 @@ EXPORT_SYMBOL(rdc_reset_state);
int rdc_8820_reset(struct dst_state *state)
{
- if (verbose > 1)
- dprintk("%s: Resetting DST\n", __FUNCTION__);
-
+ dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
udelay(1000);
if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
@@ -155,10 +157,11 @@ EXPORT_SYMBOL(rdc_8820_reset);
int dst_pio_enable(struct dst_state *state)
{
if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
udelay(1000);
+
return 0;
}
EXPORT_SYMBOL(dst_pio_enable);
@@ -166,7 +169,7 @@ EXPORT_SYMBOL(dst_pio_enable);
int dst_pio_disable(struct dst_state *state)
{
if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
- dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
return -1;
}
if (state->type_flags & DST_TYPE_HAS_FW_1)
@@ -183,19 +186,16 @@ int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
for (i = 0; i < 200; i++) {
if (dst_gpio_inb(state, &reply) < 0) {
- dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !");
return -1;
}
-
if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
- if (verbose > 4)
- dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
+ dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i);
return 1;
}
msleep(10);
}
- if (verbose > 1)
- dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
+ dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i);
return 0;
}
@@ -203,7 +203,7 @@ EXPORT_SYMBOL(dst_wait_dst_ready);
int dst_error_recovery(struct dst_state *state)
{
- dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__);
+ dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors.");
dst_pio_disable(state);
msleep(10);
dst_pio_enable(state);
@@ -215,7 +215,7 @@ EXPORT_SYMBOL(dst_error_recovery);
int dst_error_bailout(struct dst_state *state)
{
- dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error.");
rdc_8820_reset(state);
dst_pio_disable(state);
msleep(10);
@@ -224,17 +224,15 @@ int dst_error_bailout(struct dst_state *state)
}
EXPORT_SYMBOL(dst_error_bailout);
-
-int dst_comm_init(struct dst_state* state)
+int dst_comm_init(struct dst_state *state)
{
- if (verbose > 1)
- dprintk ("%s: Initializing DST..\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Initializing DST.");
if ((dst_pio_enable(state)) < 0) {
- dprintk("%s: PIO Enable Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed");
return -1;
}
if ((rdc_reset_state(state)) < 0) {
- dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed.");
return -1;
}
if (state->type_flags & DST_TYPE_HAS_FW_1)
@@ -246,36 +244,33 @@ int dst_comm_init(struct dst_state* state)
}
EXPORT_SYMBOL(dst_comm_init);
-
int write_dst(struct dst_state *state, u8 *data, u8 len)
{
struct i2c_msg msg = {
- .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = data,
+ .len = len
};
int err;
- int cnt;
- if (debug && (verbose > 4)) {
- u8 i;
- if (verbose > 4) {
- dprintk("%s writing [ ", __FUNCTION__);
- for (i = 0; i < len; i++)
- dprintk("%02x ", data[i]);
- dprintk("]\n");
- }
- }
+ u8 cnt, i;
+
+ dprintk(verbose, DST_NOTICE, 0, "writing [ ");
+ for (i = 0; i < len; i++)
+ dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]);
+ dprintk(verbose, DST_NOTICE, 0, "]\n");
+
for (cnt = 0; cnt < 2; cnt++) {
if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
- dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
+ dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]);
dst_error_recovery(state);
continue;
} else
break;
}
-
if (cnt >= 2) {
- if (verbose > 1)
- printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
dst_error_bailout(state);
return -1;
@@ -285,36 +280,37 @@ int write_dst(struct dst_state *state, u8 *data, u8 len)
}
EXPORT_SYMBOL(write_dst);
-int read_dst(struct dst_state *state, u8 * ret, u8 len)
+int read_dst(struct dst_state *state, u8 *ret, u8 len)
{
- struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
+ struct i2c_msg msg = {
+ .addr = state->config->demod_address,
+ .flags = I2C_M_RD,
+ .buf = ret,
+ .len = len
+ };
+
int err;
int cnt;
for (cnt = 0; cnt < 2; cnt++) {
if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
-
- dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
+ dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]);
dst_error_recovery(state);
-
continue;
} else
break;
}
if (cnt >= 2) {
- if (verbose > 1)
- printk("%s: RDC 8820 RESET...\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
dst_error_bailout(state);
return -1;
}
- if (debug && (verbose > 4)) {
- dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
- for (err = 1; err < len; err++)
- dprintk(" 0x%x", ret[err]);
- if (err > 1)
- dprintk("\n");
- }
+ dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]);
+ for (err = 1; err < len; err++)
+ dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]);
+ if (err > 1)
+ dprintk(verbose, DST_DEBUG, 0, "\n");
return 0;
}
@@ -323,19 +319,16 @@ EXPORT_SYMBOL(read_dst);
static int dst_set_polarization(struct dst_state *state)
{
switch (state->voltage) {
- case SEC_VOLTAGE_13: // vertical
- printk("%s: Polarization=[Vertical]\n", __FUNCTION__);
- state->tx_tuna[8] &= ~0x40; //1
- break;
-
- case SEC_VOLTAGE_18: // horizontal
- printk("%s: Polarization=[Horizontal]\n", __FUNCTION__);
- state->tx_tuna[8] |= 0x40; // 0
- break;
-
- case SEC_VOLTAGE_OFF:
-
- break;
+ case SEC_VOLTAGE_13: /* Vertical */
+ dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]");
+ state->tx_tuna[8] &= ~0x40;
+ break;
+ case SEC_VOLTAGE_18: /* Horizontal */
+ dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]");
+ state->tx_tuna[8] |= 0x40;
+ break;
+ case SEC_VOLTAGE_OFF:
+ break;
}
return 0;
@@ -344,14 +337,12 @@ static int dst_set_polarization(struct dst_state *state)
static int dst_set_freq(struct dst_state *state, u32 freq)
{
state->frequency = freq;
- if (debug > 4)
- dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
+ dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq);
if (state->dst_type == DST_TYPE_IS_SAT) {
freq = freq / 1000;
if (freq < 950 || freq > 2150)
return -EINVAL;
-
state->tx_tuna[2] = (freq >> 8);
state->tx_tuna[3] = (u8) freq;
state->tx_tuna[4] = 0x01;
@@ -360,27 +351,25 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
if (freq < 1531)
state->tx_tuna[8] |= 0x04;
}
-
} else if (state->dst_type == DST_TYPE_IS_TERR) {
freq = freq / 1000;
if (freq < 137000 || freq > 858000)
return -EINVAL;
-
state->tx_tuna[2] = (freq >> 16) & 0xff;
state->tx_tuna[3] = (freq >> 8) & 0xff;
state->tx_tuna[4] = (u8) freq;
-
} else if (state->dst_type == DST_TYPE_IS_CABLE) {
+ freq = freq / 1000;
state->tx_tuna[2] = (freq >> 16) & 0xff;
state->tx_tuna[3] = (freq >> 8) & 0xff;
state->tx_tuna[4] = (u8) freq;
-
} else
return -EINVAL;
+
return 0;
}
-static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
+static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth)
{
state->bandwidth = bandwidth;
@@ -388,103 +377,95 @@ static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
return 0;
switch (bandwidth) {
- case BANDWIDTH_6_MHZ:
- if (state->dst_hw_cap & DST_TYPE_HAS_CA)
- state->tx_tuna[7] = 0x06;
- else {
- state->tx_tuna[6] = 0x06;
- state->tx_tuna[7] = 0x00;
- }
- break;
-
- case BANDWIDTH_7_MHZ:
- if (state->dst_hw_cap & DST_TYPE_HAS_CA)
- state->tx_tuna[7] = 0x07;
- else {
- state->tx_tuna[6] = 0x07;
- state->tx_tuna[7] = 0x00;
- }
- break;
-
- case BANDWIDTH_8_MHZ:
- if (state->dst_hw_cap & DST_TYPE_HAS_CA)
- state->tx_tuna[7] = 0x08;
- else {
- state->tx_tuna[6] = 0x08;
- state->tx_tuna[7] = 0x00;
- }
- break;
-
- default:
- return -EINVAL;
+ case BANDWIDTH_6_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x06;
+ else {
+ state->tx_tuna[6] = 0x06;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
+ case BANDWIDTH_7_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x07;
+ else {
+ state->tx_tuna[6] = 0x07;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
+ case BANDWIDTH_8_MHZ:
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+ state->tx_tuna[7] = 0x08;
+ else {
+ state->tx_tuna[6] = 0x08;
+ state->tx_tuna[7] = 0x00;
+ }
+ break;
+ default:
+ return -EINVAL;
}
+
return 0;
}
-static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
+static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion)
{
state->inversion = inversion;
switch (inversion) {
- case INVERSION_OFF: // Inversion = Normal
- state->tx_tuna[8] &= ~0x80;
- break;
-
- case INVERSION_ON:
- state->tx_tuna[8] |= 0x80;
- break;
- default:
- return -EINVAL;
+ case INVERSION_OFF: /* Inversion = Normal */
+ state->tx_tuna[8] &= ~0x80;
+ break;
+ case INVERSION_ON:
+ state->tx_tuna[8] |= 0x80;
+ break;
+ default:
+ return -EINVAL;
}
+
return 0;
}
-static int dst_set_fec(struct dst_state* state, fe_code_rate_t fec)
+static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
{
state->fec = fec;
return 0;
}
-static fe_code_rate_t dst_get_fec(struct dst_state* state)
+static fe_code_rate_t dst_get_fec(struct dst_state *state)
{
return state->fec;
}
-static int dst_set_symbolrate(struct dst_state* state, u32 srate)
+static int dst_set_symbolrate(struct dst_state *state, u32 srate)
{
- u8 *val;
u32 symcalc;
u64 sval;
state->symbol_rate = srate;
-
if (state->dst_type == DST_TYPE_IS_TERR) {
return 0;
}
- if (debug > 4)
- dprintk("%s: set symrate %u\n", __FUNCTION__, srate);
+ dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
srate /= 1000;
- val = &state->tx_tuna[0];
-
if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
sval = srate;
sval <<= 20;
do_div(sval, 88000);
symcalc = (u32) sval;
-
- if (debug > 4)
- dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
-
- val[5] = (u8) (symcalc >> 12);
- val[6] = (u8) (symcalc >> 4);
- val[7] = (u8) (symcalc << 4);
+ dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
+ state->tx_tuna[5] = (u8) (symcalc >> 12);
+ state->tx_tuna[6] = (u8) (symcalc >> 4);
+ state->tx_tuna[7] = (u8) (symcalc << 4);
} else {
- val[5] = (u8) (srate >> 16) & 0x7f;
- val[6] = (u8) (srate >> 8);
- val[7] = (u8) srate;
+ state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
+ state->tx_tuna[6] = (u8) (srate >> 8);
+ state->tx_tuna[7] = (u8) srate;
+ }
+ state->tx_tuna[8] &= ~0x20;
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
+ if (srate > 8000)
+ state->tx_tuna[8] |= 0x20;
}
- val[8] &= ~0x20;
- if (srate > 8000)
- val[8] |= 0x20;
return 0;
}
@@ -496,32 +477,27 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio
state->modulation = modulation;
switch (modulation) {
- case QAM_16:
- state->tx_tuna[8] = 0x10;
- break;
-
- case QAM_32:
- state->tx_tuna[8] = 0x20;
- break;
-
- case QAM_64:
- state->tx_tuna[8] = 0x40;
- break;
-
- case QAM_128:
- state->tx_tuna[8] = 0x80;
- break;
-
- case QAM_256:
- state->tx_tuna[8] = 0x00;
- break;
-
- case QPSK:
- case QAM_AUTO:
- case VSB_8:
- case VSB_16:
- default:
- return -EINVAL;
+ case QAM_16:
+ state->tx_tuna[8] = 0x10;
+ break;
+ case QAM_32:
+ state->tx_tuna[8] = 0x20;
+ break;
+ case QAM_64:
+ state->tx_tuna[8] = 0x40;
+ break;
+ case QAM_128:
+ state->tx_tuna[8] = 0x80;
+ break;
+ case QAM_256:
+ state->tx_tuna[8] = 0x00;
+ break;
+ case QPSK:
+ case QAM_AUTO:
+ case VSB_8:
+ case VSB_16:
+ default:
+ return -EINVAL;
}
@@ -534,7 +510,7 @@ static fe_modulation_t dst_get_modulation(struct dst_state *state)
}
-u8 dst_check_sum(u8 * buf, u32 len)
+u8 dst_check_sum(u8 *buf, u32 len)
{
u32 i;
u8 val = 0;
@@ -549,26 +525,24 @@ EXPORT_SYMBOL(dst_check_sum);
static void dst_type_flags_print(u32 type_flags)
{
- printk("DST type flags :");
+ dprintk(verbose, DST_ERROR, 0, "DST type flags :");
if (type_flags & DST_TYPE_HAS_NEWTUNE)
- printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
if (type_flags & DST_TYPE_HAS_TS204)
- printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
if (type_flags & DST_TYPE_HAS_SYMDIV)
- printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
if (type_flags & DST_TYPE_HAS_FW_1)
- printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
if (type_flags & DST_TYPE_HAS_FW_2)
- printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
+ dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
if (type_flags & DST_TYPE_HAS_FW_3)
- printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
-// if ((type_flags & DST_TYPE_HAS_FW_BUILD) && new_fw)
-
- printk("\n");
+ dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
+ dprintk(verbose, DST_ERROR, 0, "\n");
}
-static int dst_type_print (u8 type)
+static int dst_type_print(u8 type)
{
char *otype;
switch (type) {
@@ -585,10 +559,10 @@ static int dst_type_print (u8 type)
break;
default:
- printk("%s: invalid dst type %d\n", __FUNCTION__, type);
+ dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
return -EINVAL;
}
- printk("DST type : %s\n", otype);
+ dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
return 0;
}
@@ -700,7 +674,7 @@ struct dst_types dst_tlist[] = {
.offset = 1,
.dst_type = DST_TYPE_IS_CABLE,
.type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1
- | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+ | DST_TYPE_HAS_FW_2,
.dst_feature = DST_TYPE_HAS_CA
},
@@ -708,7 +682,7 @@ struct dst_types dst_tlist[] = {
.device_id = "DCTNEW",
.offset = 1,
.dst_type = DST_TYPE_IS_CABLE,
- .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3,
+ .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD,
.dst_feature = 0
},
@@ -716,7 +690,7 @@ struct dst_types dst_tlist[] = {
.device_id = "DTT-CI",
.offset = 1,
.dst_type = DST_TYPE_IS_TERR,
- .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+ .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
.dst_feature = 0
},
@@ -756,6 +730,71 @@ struct dst_types dst_tlist[] = {
};
+static int dst_get_mac(struct dst_state *state)
+{
+ u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_mac[7] = dst_check_sum(get_mac, 7);
+ if (dst_command(state, get_mac, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->mac_address, '\0', 8);
+ memcpy(&state->mac_address, &state->rxbuffer, 6);
+ dprintk(verbose, DST_ERROR, 1, "MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]",
+ state->mac_address[0], state->mac_address[1], state->mac_address[2],
+ state->mac_address[4], state->mac_address[5], state->mac_address[6]);
+
+ return 0;
+}
+
+static int dst_fw_ver(struct dst_state *state)
+{
+ u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_ver[7] = dst_check_sum(get_ver, 7);
+ if (dst_command(state, get_ver, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->fw_version, '\0', 8);
+ memcpy(&state->fw_version, &state->rxbuffer, 8);
+ dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
+ state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
+ state->fw_version[1],
+ state->fw_version[5], state->fw_version[6],
+ state->fw_version[4], state->fw_version[3], state->fw_version[2]);
+
+ return 0;
+}
+
+static int dst_card_type(struct dst_state *state)
+{
+ u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_type[7] = dst_check_sum(get_type, 7);
+ if (dst_command(state, get_type, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->card_info, '\0', 8);
+ memcpy(&state->card_info, &state->rxbuffer, 8);
+ dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
+
+ return 0;
+}
+
+static int dst_get_vendor(struct dst_state *state)
+{
+ u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ get_vendor[7] = dst_check_sum(get_vendor, 7);
+ if (dst_command(state, get_vendor, 8) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Unsupported Command");
+ return -1;
+ }
+ memset(&state->vendor, '\0', 8);
+ memcpy(&state->vendor, &state->rxbuffer, 8);
+ dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
+
+ return 0;
+}
static int dst_get_device_id(struct dst_state *state)
{
@@ -772,53 +811,45 @@ static int dst_get_device_id(struct dst_state *state)
if (write_dst(state, device_type, FIXED_COMM))
return -1; /* Write failed */
-
if ((dst_pio_disable(state)) < 0)
return -1;
-
if (read_dst(state, &reply, GET_ACK))
return -1; /* Read failure */
-
if (reply != ACK) {
- dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply);
+ dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
return -1; /* Unack'd write */
}
-
if (!dst_wait_dst_ready(state, DEVICE_INIT))
return -1; /* DST not ready yet */
-
if (read_dst(state, state->rxbuffer, FIXED_COMM))
return -1;
dst_pio_disable(state);
-
if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
- dprintk("%s: Checksum failure! \n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Checksum failure!");
return -1; /* Checksum failure */
}
-
state->rxbuffer[7] = '\0';
- for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) {
+ for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
use_type_flags = p_dst_type->type_flags;
use_dst_type = p_dst_type->dst_type;
/* Card capabilities */
state->dst_hw_cap = p_dst_type->dst_feature;
- printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id);
+ dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id);
break;
}
}
if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
- printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]);
- printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
+ dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
use_dst_type = DST_TYPE_IS_SAT;
use_type_flags = DST_TYPE_HAS_SYMDIV;
}
-
dst_type_print(use_dst_type);
state->type_flags = use_type_flags;
state->dst_type = use_dst_type;
@@ -834,7 +865,7 @@ static int dst_get_device_id(struct dst_state *state)
static int dst_probe(struct dst_state *state)
{
if ((rdc_8820_reset(state)) < 0) {
- dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
return -1;
}
if (dst_addons & DST_TYPE_HAS_CA)
@@ -843,80 +874,87 @@ static int dst_probe(struct dst_state *state)
msleep(100);
if ((dst_comm_init(state)) < 0) {
- dprintk("%s: DST Initialization Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
return -1;
}
msleep(100);
if (dst_get_device_id(state) < 0) {
- dprintk("%s: unknown device.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "unknown device.");
return -1;
}
+ if (dst_get_mac(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
+ return 0;
+ }
+ if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
+ if (dst_fw_ver(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
+ return 0;
+ }
+ if (dst_card_type(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
+ return 0;
+ }
+ if (dst_get_vendor(state) < 0) {
+ dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
+ return 0;
+ }
+ }
return 0;
}
-int dst_command(struct dst_state* state, u8 * data, u8 len)
+int dst_command(struct dst_state *state, u8 *data, u8 len)
{
u8 reply;
if ((dst_comm_init(state)) < 0) {
- dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
return -1;
}
-
if (write_dst(state, data, len)) {
- if (verbose > 1)
- dprintk("%s: Tring to recover.. \n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
if ((dst_error_recovery(state)) < 0) {
- dprintk("%s: Recovery Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
return -1;
}
return -1;
}
if ((dst_pio_disable(state)) < 0) {
- dprintk("%s: PIO Disable Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
return -1;
}
if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000);
-
if (read_dst(state, &reply, GET_ACK)) {
- if (verbose > 1)
- dprintk("%s: Trying to recover.. \n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) {
- dprintk("%s: Recovery Failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
return -1;
}
return -1;
}
-
if (reply != ACK) {
- dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
+ dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
return -1;
}
if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
return 0;
-
-// udelay(3000);
if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000);
else
udelay(2000);
-
if (!dst_wait_dst_ready(state, NO_DELAY))
return -1;
-
if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
- if (verbose > 1)
- dprintk("%s: Trying to recover.. \n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) {
- dprintk("%s: Recovery failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "Recovery failed.");
return -1;
}
return -1;
}
-
if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
- dprintk("%s: checksum failure\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "checksum failure");
return -1;
}
@@ -924,11 +962,11 @@ int dst_command(struct dst_state* state, u8 * data, u8 len)
}
EXPORT_SYMBOL(dst_command);
-static int dst_get_signal(struct dst_state* state)
+static int dst_get_signal(struct dst_state *state)
{
int retval;
u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
- dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
+ //dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
state->decode_lock = state->decode_strength = state->decode_snr = 0;
return 0;
@@ -955,13 +993,12 @@ static int dst_get_signal(struct dst_state* state)
return 0;
}
-static int dst_tone_power_cmd(struct dst_state* state)
+static int dst_tone_power_cmd(struct dst_state *state)
{
u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
if (state->dst_type == DST_TYPE_IS_TERR)
return 0;
-
paket[4] = state->tx_tuna[4];
paket[2] = state->tx_tuna[2];
paket[3] = state->tx_tuna[3];
@@ -971,61 +1008,53 @@ static int dst_tone_power_cmd(struct dst_state* state)
return 0;
}
-static int dst_get_tuna(struct dst_state* state)
+static int dst_get_tuna(struct dst_state *state)
{
int retval;
if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
return 0;
-
state->diseq_flags &= ~(HAS_LOCK);
if (!dst_wait_dst_ready(state, NO_DELAY))
return 0;
-
- if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
+ if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
/* how to get variable length reply ???? */
retval = read_dst(state, state->rx_tuna, 10);
- } else {
+ else
retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
- }
-
if (retval < 0) {
- dprintk("%s: read not successful\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "read not successful");
return 0;
}
-
if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
- dprintk("%s: checksum failure?\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
return 0;
}
} else {
if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
- dprintk("%s: checksum failure?\n", __FUNCTION__);
+ dprintk(verbose, DST_INFO, 1, "checksum failure? ");
return 0;
}
}
if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
return 0;
state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
-
state->decode_lock = 1;
state->diseq_flags |= HAS_LOCK;
return 1;
}
-static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
+static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
-static int dst_write_tuna(struct dvb_frontend* fe)
+static int dst_write_tuna(struct dvb_frontend *fe)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
int retval;
u8 reply;
- if (debug > 4)
- dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
-
+ dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
state->decode_freq = 0;
state->decode_lock = state->decode_strength = state->decode_snr = 0;
if (state->dst_type == DST_TYPE_IS_SAT) {
@@ -1035,35 +1064,31 @@ static int dst_write_tuna(struct dvb_frontend* fe)
state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
if ((dst_comm_init(state)) < 0) {
- dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
return -1;
}
-
if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
retval = write_dst(state, &state->tx_tuna[0], 10);
-
} else {
state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
}
if (retval < 0) {
dst_pio_disable(state);
- dprintk("%s: write not successful\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "write not successful");
return retval;
}
-
if ((dst_pio_disable(state)) < 0) {
- dprintk("%s: DST PIO disable failed !\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
return -1;
}
-
if ((read_dst(state, &reply, GET_ACK) < 0)) {
- dprintk("%s: read verify not successful.\n", __FUNCTION__);
+ dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
return -1;
}
if (reply != ACK) {
- dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply);
+ dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
return 0;
}
state->diseq_flags |= ATTEMPT_TUNE;
@@ -1085,14 +1110,13 @@ static int dst_write_tuna(struct dvb_frontend* fe)
* Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
*/
-static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
-
if (cmd->msg_len == 0 || cmd->msg_len > 4)
return -EINVAL;
memcpy(&paket[3], cmd->msg, cmd->msg_len);
@@ -1101,65 +1125,61 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd*
return 0;
}
-static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
int need_cmd;
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
state->voltage = voltage;
-
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
need_cmd = 0;
- switch (voltage) {
- case SEC_VOLTAGE_13:
- case SEC_VOLTAGE_18:
- if ((state->diseq_flags & HAS_POWER) == 0)
- need_cmd = 1;
- state->diseq_flags |= HAS_POWER;
- state->tx_tuna[4] = 0x01;
- break;
- case SEC_VOLTAGE_OFF:
+ switch (voltage) {
+ case SEC_VOLTAGE_13:
+ case SEC_VOLTAGE_18:
+ if ((state->diseq_flags & HAS_POWER) == 0)
need_cmd = 1;
- state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
- state->tx_tuna[4] = 0x00;
- break;
-
- default:
- return -EINVAL;
+ state->diseq_flags |= HAS_POWER;
+ state->tx_tuna[4] = 0x01;
+ break;
+ case SEC_VOLTAGE_OFF:
+ need_cmd = 1;
+ state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
+ state->tx_tuna[4] = 0x00;
+ break;
+ default:
+ return -EINVAL;
}
+
if (need_cmd)
dst_tone_power_cmd(state);
return 0;
}
-static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
state->tone = tone;
-
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
switch (tone) {
- case SEC_TONE_OFF:
- if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
- state->tx_tuna[2] = 0x00;
- else
- state->tx_tuna[2] = 0xff;
-
- break;
-
- case SEC_TONE_ON:
- state->tx_tuna[2] = 0x02;
- break;
+ case SEC_TONE_OFF:
+ if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+ state->tx_tuna[2] = 0x00;
+ else
+ state->tx_tuna[2] = 0xff;
+ break;
- default:
- return -EINVAL;
+ case SEC_TONE_ON:
+ state->tx_tuna[2] = 0x02;
+ break;
+ default:
+ return -EINVAL;
}
dst_tone_power_cmd(state);
@@ -1172,16 +1192,14 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
if (state->dst_type != DST_TYPE_IS_SAT)
return 0;
-
state->minicmd = minicmd;
-
switch (minicmd) {
- case SEC_MINI_A:
- state->tx_tuna[3] = 0x02;
- break;
- case SEC_MINI_B:
- state->tx_tuna[3] = 0xff;
- break;
+ case SEC_MINI_A:
+ state->tx_tuna[3] = 0x02;
+ break;
+ case SEC_MINI_B:
+ state->tx_tuna[3] = 0xff;
+ break;
}
dst_tone_power_cmd(state);
@@ -1189,42 +1207,37 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
}
-static int dst_init(struct dvb_frontend* fe)
+static int dst_init(struct dvb_frontend *fe)
{
- struct dst_state* state = fe->demodulator_priv;
- static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 };
- static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
- static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
- static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
- static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
- static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
-// state->inversion = INVERSION_ON;
+ struct dst_state *state = fe->demodulator_priv;
+
+ static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
+ static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
+ static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
+
state->inversion = INVERSION_OFF;
state->voltage = SEC_VOLTAGE_13;
state->tone = SEC_TONE_OFF;
- state->symbol_rate = 29473000;
- state->fec = FEC_AUTO;
state->diseq_flags = 0;
state->k22 = 0x02;
state->bandwidth = BANDWIDTH_7_MHZ;
state->cur_jiff = jiffies;
- if (state->dst_type == DST_TYPE_IS_SAT) {
- state->frequency = 950000;
- memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_satci_tuna : ini_satfta_tuna), sizeof(ini_satfta_tuna));
- } else if (state->dst_type == DST_TYPE_IS_TERR) {
- state->frequency = 137000000;
- memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_tvci_tuna : ini_tvfta_tuna), sizeof(ini_tvfta_tuna));
- } else if (state->dst_type == DST_TYPE_IS_CABLE) {
- state->frequency = 51000000;
- memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_cabci_tuna : ini_cabfta_tuna), sizeof(ini_cabfta_tuna));
- }
+ if (state->dst_type == DST_TYPE_IS_SAT)
+ memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
+ else if (state->dst_type == DST_TYPE_IS_TERR)
+ memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
+ else if (state->dst_type == DST_TYPE_IS_CABLE)
+ memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
return 0;
}
-static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
*status = 0;
if (state->diseq_flags & HAS_LOCK) {
@@ -1236,9 +1249,9 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
return 0;
}
-static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
dst_get_signal(state);
*strength = state->decode_strength;
@@ -1246,9 +1259,9 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
return 0;
}
-static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
+static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
dst_get_signal(state);
*snr = state->decode_snr;
@@ -1256,28 +1269,24 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
return 0;
}
-static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
dst_set_freq(state, p->frequency);
- if (verbose > 4)
- dprintk("Set Frequency=[%d]\n", p->frequency);
+ dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
-// dst_set_inversion(state, p->inversion);
if (state->dst_type == DST_TYPE_IS_SAT) {
if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
dst_set_inversion(state, p->inversion);
-
dst_set_fec(state, p->u.qpsk.fec_inner);
dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
dst_set_polarization(state);
- if (verbose > 4)
- dprintk("Set Symbolrate=[%d]\n", p->u.qpsk.symbol_rate);
+ dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
- } else if (state->dst_type == DST_TYPE_IS_TERR) {
+ } else if (state->dst_type == DST_TYPE_IS_TERR)
dst_set_bandwidth(state, p->u.ofdm.bandwidth);
- } else if (state->dst_type == DST_TYPE_IS_CABLE) {
+ else if (state->dst_type == DST_TYPE_IS_CABLE) {
dst_set_fec(state, p->u.qam.fec_inner);
dst_set_symbolrate(state, p->u.qam.symbol_rate);
dst_set_modulation(state, p->u.qam.modulation);
@@ -1287,16 +1296,14 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
return 0;
}
-static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
p->frequency = state->decode_freq;
-// p->inversion = state->inversion;
if (state->dst_type == DST_TYPE_IS_SAT) {
if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
p->inversion = state->inversion;
-
p->u.qpsk.symbol_rate = state->symbol_rate;
p->u.qpsk.fec_inner = dst_get_fec(state);
} else if (state->dst_type == DST_TYPE_IS_TERR) {
@@ -1304,16 +1311,15 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
} else if (state->dst_type == DST_TYPE_IS_CABLE) {
p->u.qam.symbol_rate = state->symbol_rate;
p->u.qam.fec_inner = dst_get_fec(state);
-// p->u.qam.modulation = QAM_AUTO;
p->u.qam.modulation = dst_get_modulation(state);
}
return 0;
}
-static void dst_release(struct dvb_frontend* fe)
+static void dst_release(struct dvb_frontend *fe)
{
- struct dst_state* state = fe->demodulator_priv;
+ struct dst_state *state = fe->demodulator_priv;
kfree(state);
}
@@ -1321,9 +1327,8 @@ static struct dvb_frontend_ops dst_dvbt_ops;
static struct dvb_frontend_ops dst_dvbs_ops;
static struct dvb_frontend_ops dst_dvbc_ops;
-struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
+struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
{
-
/* check if the ASIC is there */
if (dst_probe(state) < 0) {
if (state)
@@ -1336,17 +1341,14 @@ struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
case DST_TYPE_IS_TERR:
memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
break;
-
case DST_TYPE_IS_CABLE:
memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
break;
-
case DST_TYPE_IS_SAT:
memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
break;
-
default:
- printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__);
+ dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
if (state)
kfree(state);
@@ -1374,12 +1376,9 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
},
.release = dst_release,
-
.init = dst_init,
-
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
-
.read_status = dst_read_status,
.read_signal_strength = dst_read_signal_strength,
.read_snr = dst_read_snr,
@@ -1401,16 +1400,12 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
},
.release = dst_release,
-
.init = dst_init,
-
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
-
.read_status = dst_read_status,
.read_signal_strength = dst_read_signal_strength,
.read_snr = dst_read_snr,
-
.diseqc_send_burst = dst_send_burst,
.diseqc_send_master_cmd = dst_set_diseqc,
.set_voltage = dst_set_voltage,
@@ -1432,18 +1427,14 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
},
.release = dst_release,
-
.init = dst_init,
-
.set_frontend = dst_set_frontend,
.get_frontend = dst_get_frontend,
-
.read_status = dst_read_status,
.read_signal_strength = dst_read_signal_strength,
.read_snr = dst_read_snr,
};
-
MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
MODULE_AUTHOR("Jamie Honan, Manu Abraham");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index bfaacd5fc20f..6776a592045f 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -18,30 +18,42 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
-
#include <linux/dvb/ca.h>
#include "dvbdev.h"
#include "dvb_frontend.h"
-
#include "dst_ca.h"
#include "dst_common.h"
+#define DST_CA_ERROR 0
+#define DST_CA_NOTICE 1
+#define DST_CA_INFO 2
+#define DST_CA_DEBUG 3
+
+#define dprintk(x, y, z, format, arg...) do { \
+ if (z) { \
+ if ((x > DST_CA_ERROR) && (x > y)) \
+ printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_CA_NOTICE) && (x > y)) \
+ printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_CA_INFO) && (x > y)) \
+ printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \
+ else if ((x > DST_CA_DEBUG) && (x > y)) \
+ printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \
+ } else { \
+ if (x > y) \
+ printk(format, ## arg); \
+ } \
+} while(0)
+
+
static unsigned int verbose = 5;
module_param(verbose, int, 0644);
MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
-static unsigned int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug messages, default is 1 (yes)");
-
-#define dprintk if (debug) printk
-
/* Need some more work */
static int ca_set_slot_descr(void)
{
@@ -61,27 +73,20 @@ static int put_checksum(u8 *check_string, int length)
{
u8 i = 0, checksum = 0;
- if (verbose > 3) {
- dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__);
- dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ===========================");
+ dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
- dprintk("%s: String=[", __FUNCTION__);
- }
while (i < length) {
- if (verbose > 3)
- dprintk(" %02x", check_string[i]);
+ dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
checksum += check_string[i];
i++;
}
- if (verbose > 3) {
- dprintk(" ]\n");
- dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum);
- }
+ dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
+ dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
check_string[length] = ~checksum + 1;
- if (verbose > 3) {
- dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]);
- dprintk("%s: ==========================================================================\n", __FUNCTION__);
- }
+ dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
+ dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
return 0;
}
@@ -94,30 +99,26 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
msleep(65);
if (write_dst(state, data, len)) {
- dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
dst_error_recovery(state);
return -1;
}
-
if ((dst_pio_disable(state)) < 0) {
- dprintk("%s: DST PIO disable failed.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
return -1;
}
-
if (read_dst(state, &reply, GET_ACK) < 0) {
- dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state);
return -1;
}
-
if (read) {
if (! dst_wait_dst_ready(state, LONG_DELAY)) {
- dprintk("%s: 8820 not ready\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
return -1;
}
-
if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
- dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state);
return -1;
}
@@ -133,8 +134,7 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string,
while (dst_ca_comm_err < RETRIES) {
dst_comm_init(state);
- if (verbose > 2)
- dprintk("%s: Put Command\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " Put Command");
if (dst_ci_command(state, data, ca_string, len, read)) { // If error
dst_error_recovery(state);
dst_ca_comm_err++; // work required here.
@@ -153,18 +153,15 @@ static int ca_get_app_info(struct dst_state *state)
put_checksum(&command[0], command[0]);
if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) {
- dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
return -1;
}
- if (verbose > 1) {
- dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
-
- dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__);
- dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n",
- __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9],
- (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
- dprintk("%s: ==================================================================================================\n", __FUNCTION__);
- }
+ dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
+ dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================");
+ dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
+ state->messages[7], (state->messages[8] << 8) | state->messages[9],
+ (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
+ dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
return 0;
}
@@ -177,31 +174,26 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
put_checksum(&slot_command[0], slot_command[0]);
if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) {
- dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
return -1;
}
- if (verbose > 1)
- dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !");
/* Will implement the rest soon */
- if (verbose > 1) {
- dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]);
- dprintk("===================================\n");
- for (i = 0; i < 8; i++)
- dprintk(" %d", slot_cap[i]);
- dprintk("\n");
- }
+ dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]);
+ dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
+ for (i = 0; i < 8; i++)
+ dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]);
+ dprintk(verbose, DST_CA_INFO, 0, "\n");
p_ca_caps->slot_num = 1;
p_ca_caps->slot_type = 1;
p_ca_caps->descr_num = slot_cap[7];
p_ca_caps->descr_type = 1;
-
- if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) {
+ if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps)))
return -EFAULT;
- }
return 0;
}
@@ -222,46 +214,37 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
put_checksum(&slot_command[0], 7);
if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
- dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !");
return -1;
}
- if (verbose > 1)
- dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !");
/* Will implement the rest soon */
- if (verbose > 1) {
- dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]);
- dprintk("===================================\n");
- for (i = 0; i < 8; i++)
- dprintk(" %d", slot_info[i]);
- dprintk("\n");
- }
+ dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]);
+ dprintk(verbose, DST_CA_INFO, 0, "===================================\n");
+ for (i = 0; i < 8; i++)
+ dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]);
+ dprintk(verbose, DST_CA_INFO, 0, "\n");
if (slot_info[4] & 0x80) {
p_ca_slot_info->flags = CA_CI_MODULE_PRESENT;
p_ca_slot_info->num = 1;
p_ca_slot_info->type = CA_CI;
- }
- else if (slot_info[4] & 0x40) {
+ } else if (slot_info[4] & 0x40) {
p_ca_slot_info->flags = CA_CI_MODULE_READY;
p_ca_slot_info->num = 1;
p_ca_slot_info->type = CA_CI;
- }
- else {
+ } else
p_ca_slot_info->flags = 0;
- }
- if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) {
+ if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
return -EFAULT;
- }
return 0;
}
-
-
static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg)
{
u8 i = 0;
@@ -270,24 +253,21 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
return -EFAULT;
-
if (p_ca_message->msg) {
- if (verbose > 3)
- dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
+ dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%02x %02x %02x]", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]);
for (i = 0; i < 3; i++) {
command = command | p_ca_message->msg[i];
if (i < 2)
command = command << 8;
}
- if (verbose > 3)
- dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
+ dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command);
switch (command) {
- case CA_APP_INFO:
- memcpy(p_ca_message->msg, state->messages, 128);
- if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
- return -EFAULT;
+ case CA_APP_INFO:
+ memcpy(p_ca_message->msg, state->messages, 128);
+ if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) )
+ return -EFAULT;
break;
}
}
@@ -298,10 +278,13 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
{
if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
- hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
- hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
- }
- else {
+ hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
+ hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
+ } else {
+ if (length > 247) {
+ dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !");
+ return -1;
+ }
hw_buffer->msg[0] = (length & 0xff) + 7;
hw_buffer->msg[1] = 0x40;
hw_buffer->msg[2] = 0x03;
@@ -309,6 +292,11 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
hw_buffer->msg[4] = 0x03;
hw_buffer->msg[5] = length & 0xff;
hw_buffer->msg[6] = 0x00;
+ /*
+ * Need to compute length for EN50221 section 8.3.2, for the time being
+ * assuming 8.3.2 is not applicable
+ */
+ memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
}
return 0;
}
@@ -317,13 +305,12 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message,
static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
{
if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
- dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
- dprintk("%s: Resetting DST.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed.");
+ dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST.");
rdc_reset_state(state);
return -1;
}
- if (verbose > 2)
- dprintk("%s: DST-CI Command succes.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command succes.");
return 0;
}
@@ -334,130 +321,47 @@ u32 asn_1_decode(u8 *asn_1_array)
u32 length = 0;
length_field = asn_1_array[0];
- dprintk("%s: Length field=[%02x]\n", __FUNCTION__, length_field);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field);
if (length_field < 0x80) {
length = length_field & 0x7f;
- dprintk("%s: Length=[%02x]\n", __FUNCTION__, length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length);
} else {
word_count = length_field & 0x7f;
for (count = 0; count < word_count; count++) {
length = (length | asn_1_array[count + 1]) << 8;
- dprintk("%s: Length=[%04x]\n", __FUNCTION__, length);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
}
}
return length;
}
-static int init_buffer(u8 *buffer, u32 length)
-{
- u32 i;
- for (i = 0; i < length; i++)
- buffer[i] = 0;
-
- return 0;
-}
-
static int debug_string(u8 *msg, u32 length, u32 offset)
{
u32 i;
- dprintk(" String=[ ");
+ dprintk(verbose, DST_CA_DEBUG, 0, " String=[ ");
for (i = offset; i < length; i++)
- dprintk("%02x ", msg[i]);
- dprintk("]\n");
-
- return 0;
-}
-
-static int copy_string(u8 *destination, u8 *source, u32 dest_offset, u32 source_offset, u32 length)
-{
- u32 i;
- dprintk("%s: Copying [", __FUNCTION__);
- for (i = 0; i < length; i++) {
- destination[i + dest_offset] = source[i + source_offset];
- dprintk(" %02x", source[i + source_offset]);
- }
- dprintk("]\n");
-
- return i;
-}
-
-static int modify_4_bits(u8 *message, u32 pos)
-{
- message[pos] &= 0x0f;
+ dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]);
+ dprintk(verbose, DST_CA_DEBUG, 0, "]\n");
return 0;
}
-
-
static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
{
- u32 length = 0, count = 0;
- u8 asn_1_words, program_header_length;
- u16 program_info_length = 0, es_info_length = 0;
- u32 hw_offset = 0, buf_offset = 0, i;
- u8 dst_tag_length;
+ u32 length = 0;
+ u8 tag_length = 8;
length = asn_1_decode(&p_ca_message->msg[3]);
- dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length);
- dprintk("%s: ASN.1 ", __FUNCTION__);
- debug_string(&p_ca_message->msg[4], length, 0); // length does not include tag and length
+ dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length);
+ debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */
- init_buffer(hw_buffer->msg, length);
+ memset(hw_buffer->msg, '\0', length);
handle_dst_tag(state, p_ca_message, hw_buffer, length);
+ put_checksum(hw_buffer->msg, hw_buffer->msg[0]);
- hw_offset = 7;
- asn_1_words = 1; // just a hack to test, should compute this one
- buf_offset = 3;
- program_header_length = 6;
- dst_tag_length = 7;
-
-// debug_twinhan_ca_params(state, p_ca_message, hw_buffer, reply, query, length, hw_offset, buf_offset);
-// dprintk("%s: Program Header(BUF)", __FUNCTION__);
-// debug_string(&p_ca_message->msg[4], program_header_length, 0);
-// dprintk("%s: Copying Program header\n", __FUNCTION__);
- copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + asn_1_words), program_header_length);
- buf_offset += program_header_length, hw_offset += program_header_length;
- modify_4_bits(hw_buffer->msg, (hw_offset - 2));
- if (state->type_flags & DST_TYPE_HAS_INC_COUNT) { // workaround
- dprintk("%s: Probably an ASIC bug !!!\n", __FUNCTION__);
- debug_string(hw_buffer->msg, (hw_offset + program_header_length), 0);
- hw_buffer->msg[hw_offset - 1] += 1;
- }
-
-// dprintk("%s: Program Header(HW), Count=[%d]", __FUNCTION__, count);
-// debug_string(hw_buffer->msg, hw_offset, 0);
-
- program_info_length = ((program_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
- dprintk("%s: Program info length=[%02x]\n", __FUNCTION__, program_info_length);
- if (program_info_length) {
- count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + 1), (program_info_length + 1) ); // copy next elem, not current
- buf_offset += count, hw_offset += count;
-// dprintk("%s: Program level ", __FUNCTION__);
-// debug_string(hw_buffer->msg, hw_offset, 0);
- }
-
- buf_offset += 1;// hw_offset += 1;
- for (i = buf_offset; i < length; i++) {
-// dprintk("%s: Stream Header ", __FUNCTION__);
- count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, buf_offset, 5);
- modify_4_bits(hw_buffer->msg, (hw_offset + 3));
-
- hw_offset += 5, buf_offset += 5, i += 4;
-// debug_string(hw_buffer->msg, hw_offset, (hw_offset - 5));
- es_info_length = ((es_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
- dprintk("%s: ES info length=[%02x]\n", __FUNCTION__, es_info_length);
- if (es_info_length) {
- // copy descriptors @ STREAM level
- dprintk("%s: Descriptors @ STREAM level...!!! \n", __FUNCTION__);
- }
-
- }
- hw_buffer->msg[length + dst_tag_length] = dst_check_sum(hw_buffer->msg, (length + dst_tag_length));
-// dprintk("%s: Total length=[%d], Checksum=[%02x]\n", __FUNCTION__, (length + dst_tag_length), hw_buffer->msg[length + dst_tag_length]);
- debug_string(hw_buffer->msg, (length + dst_tag_length + 1), 0); // dst tags also
- write_to_8820(state, hw_buffer, (length + dst_tag_length + 1), reply); // checksum
+ debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */
+ write_to_8820(state, hw_buffer, (length + tag_length), reply);
return 0;
}
@@ -471,26 +375,24 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
/* Do test board */
/* Not there yet but soon */
-
/* CA PMT Reply capable */
if (ca_pmt_reply_test) {
if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) {
- dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
return -1;
}
/* Process CA PMT Reply */
/* will implement soon */
- dprintk("%s: Not there yet\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Not there yet");
}
/* CA PMT Reply not capable */
if (!ca_pmt_reply_test) {
if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) {
- dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !");
return -1;
}
- if (verbose > 3)
- dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !");
/* put a dummy message */
}
@@ -506,11 +408,10 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
struct ca_msg *hw_buffer;
if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
- if (verbose > 3)
- dprintk("%s\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " ");
if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg)))
return -EFAULT;
@@ -525,51 +426,35 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
if (i < 2)
command = command << 8;
}
- if (verbose > 3)
- dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command);
switch (command) {
- case CA_PMT:
- if (verbose > 3)
-// dprintk("Command = SEND_CA_PMT\n");
- dprintk("Command = SEND_CA_PMT\n");
-// if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
- if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
- dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 3)
- dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__);
-// retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0);
-
- break;
-
- case CA_PMT_REPLY:
- if (verbose > 3)
- dprintk("Command = CA_PMT_REPLY\n");
- /* Have to handle the 2 basic types of cards here */
- if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
- dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 3)
- dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__);
-
- /* Certain boards do behave different ? */
-// retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1);
-
- case CA_APP_INFO_ENQUIRY: // only for debugging
- if (verbose > 3)
- dprintk("%s: Getting Cam Application information\n", __FUNCTION__);
-
- if ((ca_get_app_info(state)) < 0) {
- dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 3)
- dprintk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
-
- break;
+ case CA_PMT:
+ dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
+ if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
+ break;
+ case CA_PMT_REPLY:
+ dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY");
+ /* Have to handle the 2 basic types of cards here */
+ if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
+ break;
+ case CA_APP_INFO_ENQUIRY: // only for debugging
+ dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information");
+
+ if ((ca_get_app_info(state)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
+ break;
}
}
return 0;
@@ -584,121 +469,88 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct ca_msg *p_ca_message;
if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
-
if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
-
if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
- dprintk("%s: Memory allocation failure\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
return -ENOMEM;
}
-
/* We have now only the standard ioctl's, the driver is upposed to handle internals. */
switch (cmd) {
- case CA_SEND_MSG:
- if (verbose > 1)
- dprintk("%s: Sending message\n", __FUNCTION__);
- if ((ca_send_message(state, p_ca_message, arg)) < 0) {
- dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__);
- return -1;
- }
-
- break;
-
- case CA_GET_MSG:
- if (verbose > 1)
- dprintk("%s: Getting message\n", __FUNCTION__);
- if ((ca_get_message(state, p_ca_message, arg)) < 0) {
- dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__);
-
- break;
-
- case CA_RESET:
- if (verbose > 1)
- dprintk("%s: Resetting DST\n", __FUNCTION__);
- dst_error_bailout(state);
- msleep(4000);
-
- break;
-
- case CA_GET_SLOT_INFO:
- if (verbose > 1)
- dprintk("%s: Getting Slot info\n", __FUNCTION__);
- if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
- dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__);
-
- break;
-
- case CA_GET_CAP:
- if (verbose > 1)
- dprintk("%s: Getting Slot capabilities\n", __FUNCTION__);
- if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
- dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__);
-
- break;
-
- case CA_GET_DESCR_INFO:
- if (verbose > 1)
- dprintk("%s: Getting descrambler description\n", __FUNCTION__);
- if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
- dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__);
-
- break;
-
- case CA_SET_DESCR:
- if (verbose > 1)
- dprintk("%s: Setting descrambler\n", __FUNCTION__);
- if ((ca_set_slot_descr()) < 0) {
- dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__);
-
- break;
-
- case CA_SET_PID:
- if (verbose > 1)
- dprintk("%s: Setting PID\n", __FUNCTION__);
- if ((ca_set_pid()) < 0) {
- dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__);
- return -1;
- }
- if (verbose > 1)
- dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__);
-
- default:
- return -EOPNOTSUPP;
- };
+ case CA_SEND_MSG:
+ dprintk(verbose, DST_CA_INFO, 1, " Sending message");
+ if ((ca_send_message(state, p_ca_message, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
+ return -1;
+ }
+ break;
+ case CA_GET_MSG:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting message");
+ if ((ca_get_message(state, p_ca_message, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
+ break;
+ case CA_RESET:
+ dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST");
+ dst_error_bailout(state);
+ msleep(4000);
+ break;
+ case CA_GET_SLOT_INFO:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
+ if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
+ break;
+ case CA_GET_CAP:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
+ if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
+ break;
+ case CA_GET_DESCR_INFO:
+ dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
+ if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
+ break;
+ case CA_SET_DESCR:
+ dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
+ if ((ca_set_slot_descr()) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
+ break;
+ case CA_SET_PID:
+ dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
+ if ((ca_set_pid()) < 0) {
+ dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
+ return -1;
+ }
+ dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
+ default:
+ return -EOPNOTSUPP;
+ };
return 0;
}
static int dst_ca_open(struct inode *inode, struct file *file)
{
- if (verbose > 4)
- dprintk("%s:Device opened [%p]\n", __FUNCTION__, file);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file);
try_module_get(THIS_MODULE);
return 0;
@@ -706,27 +558,24 @@ static int dst_ca_open(struct inode *inode, struct file *file)
static int dst_ca_release(struct inode *inode, struct file *file)
{
- if (verbose > 4)
- dprintk("%s:Device closed.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device closed.");
module_put(THIS_MODULE);
return 0;
}
-static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset)
+static int dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
{
int bytes_read = 0;
- if (verbose > 4)
- dprintk("%s:Device read.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
return bytes_read;
}
-static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset)
+static int dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
{
- if (verbose > 4)
- dprintk("%s:Device write.\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
return 0;
}
@@ -751,8 +600,7 @@ static struct dvb_device dvbdev_ca = {
int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
{
struct dvb_device *dvbdev;
- if (verbose > 4)
- dprintk("%s:registering DST-CA device\n", __FUNCTION__);
+ dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
return 0;
}
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index ef532a6aceaa..3281a6ca3685 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -61,7 +61,6 @@
#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */
#define DST_TYPE_HAS_SESSION 128
-
#define RDC_8820_PIO_0_DISABLE 0
#define RDC_8820_PIO_0_ENABLE 1
#define RDC_8820_INT 2
@@ -114,6 +113,10 @@ struct dst_state {
fe_sec_mini_cmd_t minicmd;
fe_modulation_t modulation;
u8 messages[256];
+ u8 mac_address[8];
+ u8 fw_version[8];
+ u8 card_info[8];
+ u8 vendor[8];
};
struct dst_types {
@@ -124,15 +127,12 @@ struct dst_types {
u32 dst_feature;
};
-
-
struct dst_config
{
/* the ASIC i2c address */
u8 demod_address;
};
-
int rdc_reset_state(struct dst_state *state);
int rdc_8820_reset(struct dst_state *state);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 6f857c6091f3..c5c7672cd538 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -32,9 +32,7 @@
#include "dvbdev.h"
#include "dvb_demux.h"
#include "dvb_frontend.h"
-
#include "dvb-bt8xx.h"
-
#include "bt878.h"
static int debug;
@@ -43,9 +41,11 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
#define dprintk( args... ) \
- do { \
+ do \
if (debug) printk(KERN_DEBUG args); \
- } while (0)
+ while (0)
+
+#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
static void dvb_bt8xx_task(unsigned long data)
{
@@ -119,14 +119,12 @@ static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci
unsigned int card_nr;
/* Hmm, n squared. Hope n is small */
- for (card_nr = 0; card_nr < bt878_num; card_nr++) {
+ for (card_nr = 0; card_nr < bt878_num; card_nr++)
if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
return &bt878[card_nr];
- }
return NULL;
}
-
static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
{
static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
@@ -154,16 +152,21 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
unsigned char bs = 0;
unsigned char cp = 0;
- #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
- if (params->frequency < 542000000) cp = 0xb4;
- else if (params->frequency < 771000000) cp = 0xbc;
- else cp = 0xf4;
+ if (params->frequency < 542000000)
+ cp = 0xb4;
+ else if (params->frequency < 771000000)
+ cp = 0xbc;
+ else
+ cp = 0xf4;
- if (params->frequency == 0) bs = 0x03;
- else if (params->frequency < 443250000) bs = 0x02;
- else bs = 0x08;
+ if (params->frequency == 0)
+ bs = 0x03;
+ else if (params->frequency < 443250000)
+ bs = 0x02;
+ else
+ bs = 0x08;
pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
pllbuf[1] = div >> 8;
@@ -175,7 +178,6 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
}
static struct mt352_config thomson_dtt7579_config = {
-
.demod_address = 0x0f,
.demod_init = thomson_dtt7579_demod_init,
.pll_set = thomson_dtt7579_pll_set,
@@ -183,25 +185,26 @@ static struct mt352_config thomson_dtt7579_config = {
static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
- u32 freq = params->frequency;
-
- int i, a, n, pump;
- u32 band, pll;
+ u32 freq = params->frequency;
+ int i, a, n, pump;
+ u32 band, pll;
- u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
- 1576000,1718000,1856000,2036000,2150000};
- u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
- 0x00102000,0x00104000,0x00108000,0x00110000,
- 0x00120000,0x00140000};
+ u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
+ 1576000,1718000,1856000,2036000,2150000};
+ u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
+ 0x00102000,0x00104000,0x00108000,0x00110000,
+ 0x00120000,0x00140000};
-#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
+ #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
/* This is really the bit driving the tuner chip cx24108 */
- if(freq<950000) freq=950000; /* kHz */
- if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
+ if (freq<950000)
+ freq = 950000; /* kHz */
+ else if (freq>2150000)
+ freq = 2150000; /* satellite IF is 950..2150MHz */
/* decide which VCO to use for the input frequency */
for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
@@ -228,25 +231,22 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
cx24110_pll_write(fe,0x500c0000);
cx24110_pll_write(fe,0x83f1f800);
cx24110_pll_write(fe,pll);
-/* writereg(client,0x56,0x7f);*/
+ //writereg(client,0x56,0x7f);
return 0;
}
static int pinnsat_pll_init(struct dvb_frontend* fe)
{
- return 0;
+ return 0;
}
-
static struct cx24110_config pctvsat_config = {
-
.demod_address = 0x55,
.pll_init = pinnsat_pll_init,
.pll_set = cx24108_pll_set,
};
-
static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
@@ -258,15 +258,23 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
div = (36000000 + params->frequency + 83333) / 166666;
cfg = 0x88;
- if (params->frequency < 175000000) cpump = 2;
- else if (params->frequency < 390000000) cpump = 1;
- else if (params->frequency < 470000000) cpump = 2;
- else if (params->frequency < 750000000) cpump = 2;
- else cpump = 3;
+ if (params->frequency < 175000000)
+ cpump = 2;
+ else if (params->frequency < 390000000)
+ cpump = 1;
+ else if (params->frequency < 470000000)
+ cpump = 2;
+ else if (params->frequency < 750000000)
+ cpump = 2;
+ else
+ cpump = 3;
- if (params->frequency < 175000000) band_select = 0x0e;
- else if (params->frequency < 470000000) band_select = 0x05;
- else band_select = 0x03;
+ if (params->frequency < 175000000)
+ band_select = 0x0e;
+ else if (params->frequency < 470000000)
+ band_select = 0x05;
+ else
+ band_select = 0x03;
data[0] = (div >> 8) & 0x7f;
data[1] = div & 0xff;
@@ -285,14 +293,11 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s
}
static struct sp887x_config microtune_mt7202dtf_config = {
-
.demod_address = 0x70,
.pll_set = microtune_mt7202dtf_pll_set,
.request_firmware = microtune_mt7202dtf_request_firmware,
};
-
-
static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
{
static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
@@ -303,7 +308,6 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
udelay(2000);
mt352_write(fe, mt352_reset, sizeof(mt352_reset));
@@ -323,28 +327,45 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
unsigned char bs = 0;
unsigned char cp = 0;
- #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
- if (params->frequency < 150000000) cp = 0xB4;
- else if (params->frequency < 173000000) cp = 0xBC;
- else if (params->frequency < 250000000) cp = 0xB4;
- else if (params->frequency < 400000000) cp = 0xBC;
- else if (params->frequency < 420000000) cp = 0xF4;
- else if (params->frequency < 470000000) cp = 0xFC;
- else if (params->frequency < 600000000) cp = 0xBC;
- else if (params->frequency < 730000000) cp = 0xF4;
- else cp = 0xFC;
-
- if (params->frequency < 150000000) bs = 0x01;
- else if (params->frequency < 173000000) bs = 0x01;
- else if (params->frequency < 250000000) bs = 0x02;
- else if (params->frequency < 400000000) bs = 0x02;
- else if (params->frequency < 420000000) bs = 0x02;
- else if (params->frequency < 470000000) bs = 0x02;
- else if (params->frequency < 600000000) bs = 0x08;
- else if (params->frequency < 730000000) bs = 0x08;
- else bs = 0x08;
+ if (params->frequency < 150000000)
+ cp = 0xB4;
+ else if (params->frequency < 173000000)
+ cp = 0xBC;
+ else if (params->frequency < 250000000)
+ cp = 0xB4;
+ else if (params->frequency < 400000000)
+ cp = 0xBC;
+ else if (params->frequency < 420000000)
+ cp = 0xF4;
+ else if (params->frequency < 470000000)
+ cp = 0xFC;
+ else if (params->frequency < 600000000)
+ cp = 0xBC;
+ else if (params->frequency < 730000000)
+ cp = 0xF4;
+ else
+ cp = 0xFC;
+
+ if (params->frequency < 150000000)
+ bs = 0x01;
+ else if (params->frequency < 173000000)
+ bs = 0x01;
+ else if (params->frequency < 250000000)
+ bs = 0x02;
+ else if (params->frequency < 400000000)
+ bs = 0x02;
+ else if (params->frequency < 420000000)
+ bs = 0x02;
+ else if (params->frequency < 470000000)
+ bs = 0x02;
+ else if (params->frequency < 600000000)
+ bs = 0x08;
+ else if (params->frequency < 730000000)
+ bs = 0x08;
+ else
+ bs = 0x08;
pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
pllbuf[1] = div >> 8;
@@ -356,19 +377,15 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct
}
static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
-
.demod_address = 0x0f,
.demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
.pll_set = advbt771_samsung_tdtc9251dh0_pll_set,
};
-
static struct dst_config dst_config = {
-
.demod_address = 0x55,
};
-
static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{
struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
@@ -398,10 +415,8 @@ static void or51211_reset(struct dvb_frontend * fe)
*/
/* reset & PRM1,2&4 are outputs */
int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
- if (ret != 0) {
- printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR "
- "(%i)\n", ret);
- }
+ if (ret != 0)
+ printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret);
bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
msleep(20);
/* Now set for normal operation */
@@ -417,7 +432,6 @@ static void or51211_sleep(struct dvb_frontend * fe)
}
static struct or51211_config or51211_config = {
-
.demod_address = 0x15,
.request_firmware = or51211_request_firmware,
.setmode = or51211_setmode,
@@ -425,7 +439,6 @@ static struct or51211_config or51211_config = {
.sleep = or51211_sleep,
};
-
static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
@@ -454,12 +467,84 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten
}
static struct nxt6000_config vp3021_alps_tded4_config = {
-
.demod_address = 0x0a,
.clock_inversion = 1,
.pll_set = vp3021_alps_tded4_pll_set,
};
+static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe)
+{
+ static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
+ static u8 mt352_reset [] = { 0x50, 0x80 };
+ static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+ static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 };
+ static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
+
+ mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+ udelay(2000);
+ mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+ mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+ mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
+ mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
+
+ return 0;
+}
+
+static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
+{
+ u32 div;
+ struct dvb_ofdm_parameters *op = &params->u.ofdm;
+
+ div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
+
+ pllbuf[0] = 0xc2;
+ pllbuf[1] = (div >> 8) & 0x7F;
+ pllbuf[2] = div & 0xFF;
+ pllbuf[3] = 0x85;
+
+ dprintk("frequency %u, div %u\n", params->frequency, div);
+
+ if (params->frequency < 470000000)
+ pllbuf[4] = 0x02;
+ else if (params->frequency > 823000000)
+ pllbuf[4] = 0x88;
+ else
+ pllbuf[4] = 0x08;
+
+ if (op->bandwidth == 8)
+ pllbuf[4] |= 0x04;
+
+ return 0;
+}
+
+static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
+{
+ /*
+ * Reset the frontend, must be called before trying
+ * to initialise the MT352 or mt352_attach
+ * will fail.
+ *
+ * Presumably not required for the NXT6000 frontend.
+ *
+ */
+
+ int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08);
+ if (ret != 0)
+ printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret);
+
+ /* Pulse the reset line */
+ bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
+ bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */
+ msleep(100);
+
+ bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */
+}
+
+static struct mt352_config digitv_alps_tded4_config = {
+ .demod_address = 0x0a,
+ .demod_init = digitv_alps_tded4_demod_init,
+ .pll_set = digitv_alps_tded4_pll_set,
+};
static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
{
@@ -473,7 +558,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
if (card->fe != NULL) {
card->fe->ops->info.frequency_min = 174000000;
card->fe->ops->info.frequency_max = 862000000;
- break;
}
break;
#endif
@@ -483,17 +567,28 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
#else
case BTTV_NEBULA_DIGITV:
#endif
+ /*
+ * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
+ * this would be a cleaner solution than trying each frontend in turn.
+ */
+
+ /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
if (card->fe != NULL) {
+ dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
break;
}
+
+ /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
+ digitv_alps_tded4_reset(card);
+ card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter);
+
+ if (card->fe != NULL)
+ dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
break;
case BTTV_AVDVBT_761:
card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
- if (card->fe != NULL) {
- break;
- }
break;
case BTTV_AVDVBT_771:
@@ -501,7 +596,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
if (card->fe != NULL) {
card->fe->ops->info.frequency_min = 174000000;
card->fe->ops->info.frequency_max = 862000000;
- break;
}
break;
@@ -522,54 +616,41 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
/* Attach other DST peripherals if any */
/* Conditional Access device */
- if (state->dst_hw_cap & DST_TYPE_HAS_CA) {
+ if (state->dst_hw_cap & DST_TYPE_HAS_CA)
ret = dst_ca_attach(state, &card->dvb_adapter);
- }
- if (card->fe != NULL) {
- break;
- }
break;
case BTTV_PINNACLESAT:
card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
- if (card->fe != NULL) {
- break;
- }
break;
case BTTV_PC_HDTV:
card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
- if (card->fe != NULL) {
- break;
- }
break;
}
- if (card->fe == NULL) {
+ if (card->fe == NULL)
printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
card->bt->dev->vendor,
card->bt->dev->device,
card->bt->dev->subsystem_vendor,
card->bt->dev->subsystem_device);
- } else {
+ else
if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
printk("dvb-bt8xx: Frontend registration failed!\n");
if (card->fe->ops->release)
card->fe->ops->release(card->fe);
card->fe = NULL;
}
- }
}
static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
{
int result;
- if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
- THIS_MODULE)) < 0) {
+ if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) {
printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
return result;
-
}
card->dvb_adapter.priv = card;
@@ -664,8 +745,7 @@ static int dvb_bt8xx_probe(struct device *dev)
strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
card->i2c_adapter = &sub->core->i2c_adap;
- switch(sub->core->type)
- {
+ switch(sub->core->type) {
case BTTV_PINNACLESAT:
card->gpio_mode = 0x0400c060;
/* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
@@ -751,7 +831,6 @@ static int dvb_bt8xx_probe(struct device *dev)
kfree(card);
return -EFAULT;
-
}
init_MUTEX(&card->bt->gpio_lock);
@@ -779,7 +858,8 @@ static int dvb_bt8xx_remove(struct device *dev)
card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
dvb_dmxdev_release(&card->dmxdev);
dvb_dmx_release(&card->demux);
- if (card->fe) dvb_unregister_frontend(card->fe);
+ if (card->fe)
+ dvb_unregister_frontend(card->fe);
dvb_unregister_adapter(&card->dvb_adapter);
kfree(card);
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 2923b3b0dd3c..9ec8e5bd6c1f 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -2,7 +2,7 @@
* Bt8xx based DVB adapter driver
*
* Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
- * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
+ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de>
* Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH
* Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
*
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 226714085f58..7cf4c4a888ec 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
config DVB_CINERGYT2_RC_QUERY_INTERVAL
int "Infrared Remote Controller update interval [milliseconds]"
depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
- default "100"
+ default "50"
help
If you have a very fast-repeating remote control you can try lower
values, for normal consumer receivers the default value should be
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 7d8b3cad350b..a1607e7d6d6b 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -25,7 +25,6 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/pci.h>
@@ -36,7 +35,6 @@
#include "dvb_demux.h"
#include "dvb_net.h"
-
#ifdef CONFIG_DVB_CINERGYT2_TUNING
#define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
#define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
@@ -49,7 +47,7 @@
#define STREAM_URB_COUNT (32)
#define STREAM_BUF_SIZE (512) /* bytes */
#define ENABLE_RC (1)
- #define RC_QUERY_INTERVAL (100) /* milliseconds */
+ #define RC_QUERY_INTERVAL (50) /* milliseconds */
#define QUERY_INTERVAL (333) /* milliseconds */
#endif
@@ -139,9 +137,12 @@ struct cinergyt2 {
struct urb *stream_urb [STREAM_URB_COUNT];
#ifdef ENABLE_RC
- struct input_dev rc_input_dev;
+ struct input_dev *rc_input_dev;
+ char phys[64];
struct work_struct rc_query_work;
int rc_input_event;
+ u32 rc_last_code;
+ unsigned long last_event_jiffies;
#endif
};
@@ -156,7 +157,7 @@ struct cinergyt2_rc_event {
uint32_t value;
} __attribute__((packed));
-static const uint32_t rc_keys [] = {
+static const uint32_t rc_keys[] = {
CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
@@ -683,60 +684,129 @@ static struct dvb_device cinergyt2_fe_template = {
};
#ifdef ENABLE_RC
+
static void cinergyt2_query_rc (void *data)
{
- struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
- char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS };
+ struct cinergyt2 *cinergyt2 = data;
+ char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS };
struct cinergyt2_rc_event rc_events[12];
- int n, len;
+ int n, len, i;
if (down_interruptible(&cinergyt2->sem))
return;
len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
- (char *) rc_events, sizeof(rc_events));
-
- for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
- int i;
+ (char *) rc_events, sizeof(rc_events));
+ if (len < 0)
+ goto out;
+ if (len == 0) {
+ if (time_after(jiffies, cinergyt2->last_event_jiffies +
+ msecs_to_jiffies(150))) {
+ /* stop key repeat */
+ if (cinergyt2->rc_input_event != KEY_MAX) {
+ dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
+ input_report_key(cinergyt2->rc_input_dev,
+ cinergyt2->rc_input_event, 0);
+ cinergyt2->rc_input_event = KEY_MAX;
+ }
+ cinergyt2->rc_last_code = ~0;
+ }
+ goto out;
+ }
+ cinergyt2->last_event_jiffies = jiffies;
-/* dprintk(1,"rc_events[%d].value = %x, type=%x\n",n,le32_to_cpu(rc_events[n].value),rc_events[n].type);*/
+ for (n = 0; n < (len / sizeof(rc_events[0])); n++) {
+ dprintk(1, "rc_events[%d].value = %x, type=%x\n",
+ n, le32_to_cpu(rc_events[n].value), rc_events[n].type);
if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
- rc_events[n].value == ~0)
- {
- /**
- * keyrepeat bit. If we would handle this properly
- * we would need to emit down events as long the
- * keyrepeat goes, a up event if no further
- * repeat bits occur. Would need a timer to implement
- * and no other driver does this, so we simply
- * emit the last key up/down sequence again.
- */
+ rc_events[n].value == ~0) {
+ /* keyrepeat bit -> just repeat last rc_input_event */
} else {
cinergyt2->rc_input_event = KEY_MAX;
- for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
- if (rc_keys[i+0] == rc_events[n].type &&
- rc_keys[i+1] == le32_to_cpu(rc_events[n].value))
- {
- cinergyt2->rc_input_event = rc_keys[i+2];
+ for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) {
+ if (rc_keys[i + 0] == rc_events[n].type &&
+ rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
+ cinergyt2->rc_input_event = rc_keys[i + 2];
break;
}
}
}
if (cinergyt2->rc_input_event != KEY_MAX) {
- input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1);
- input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0);
- input_sync(&cinergyt2->rc_input_dev);
+ if (rc_events[n].value == cinergyt2->rc_last_code &&
+ cinergyt2->rc_last_code != ~0) {
+ /* emit a key-up so the double event is recognized */
+ dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
+ input_report_key(cinergyt2->rc_input_dev,
+ cinergyt2->rc_input_event, 0);
+ }
+ dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
+ input_report_key(cinergyt2->rc_input_dev,
+ cinergyt2->rc_input_event, 1);
+ cinergyt2->rc_last_code = rc_events[n].value;
}
}
+out:
schedule_delayed_work(&cinergyt2->rc_query_work,
msecs_to_jiffies(RC_QUERY_INTERVAL));
up(&cinergyt2->sem);
}
-#endif
+
+static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
+{
+ struct input_dev *input_dev;
+ int i;
+
+ cinergyt2->rc_input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys));
+ strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys));
+ cinergyt2->rc_input_event = KEY_MAX;
+ cinergyt2->rc_last_code = ~0;
+ INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
+
+ input_dev->name = DRIVER_NAME " remote control";
+ input_dev->phys = cinergyt2->phys;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ for (i = 0; ARRAY_SIZE(rc_keys); i += 3)
+ set_bit(rc_keys[i + 2], input_dev->keybit);
+ input_dev->keycodesize = 0;
+ input_dev->keycodemax = 0;
+
+ input_register_device(cinergyt2->rc_input_dev);
+ schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+}
+
+static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
+{
+ cancel_delayed_work(&cinergyt2->rc_query_work);
+ flush_scheduled_work();
+ input_unregister_device(cinergyt2->rc_input_dev);
+}
+
+static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2)
+{
+ cancel_delayed_work(&cinergyt2->rc_query_work);
+}
+
+static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2)
+{
+ schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+}
+
+#else
+
+static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; }
+static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { }
+static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { }
+static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { }
+
+#endif /* ENABLE_RC */
static void cinergyt2_query (void *data)
{
@@ -772,7 +842,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
const struct usb_device_id *id)
{
struct cinergyt2 *cinergyt2;
- int i, err;
+ int err;
if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
dprintk(1, "out of memory?!?\n");
@@ -827,31 +897,17 @@ static int cinergyt2_probe (struct usb_interface *intf,
&cinergyt2_fe_template, cinergyt2,
DVB_DEVICE_FRONTEND);
-#ifdef ENABLE_RC
- init_input_dev(&cinergyt2->rc_input_dev);
-
- cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY);
- cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
- cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
- cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
-
- for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3)
- set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit);
-
- input_register_device(&cinergyt2->rc_input_dev);
-
- cinergyt2->rc_input_event = KEY_MAX;
+ err = cinergyt2_register_rc(cinergyt2);
+ if (err)
+ goto bailout;
- INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
- schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
-#endif
return 0;
bailout:
dvb_dmxdev_release(&cinergyt2->dmxdev);
dvb_dmx_release(&cinergyt2->demux);
- dvb_unregister_adapter (&cinergyt2->adapter);
- cinergyt2_free_stream_urbs (cinergyt2);
+ dvb_unregister_adapter(&cinergyt2->adapter);
+ cinergyt2_free_stream_urbs(cinergyt2);
kfree(cinergyt2);
return -ENOMEM;
}
@@ -863,11 +919,7 @@ static void cinergyt2_disconnect (struct usb_interface *intf)
if (down_interruptible(&cinergyt2->sem))
return;
-#ifdef ENABLE_RC
- cancel_delayed_work(&cinergyt2->rc_query_work);
- flush_scheduled_work();
- input_unregister_device(&cinergyt2->rc_input_dev);
-#endif
+ cinergyt2_unregister_rc(cinergyt2);
cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
dvb_net_release(&cinergyt2->dvbnet);
@@ -888,11 +940,10 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
if (down_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
- if (state > 0) { /* state 0 seems to mean DEVICE_PM_ON */
+ if (state.event > PM_EVENT_ON) {
struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
-#ifdef ENABLE_RC
- cancel_delayed_work(&cinergyt2->rc_query_work);
-#endif
+
+ cinergyt2_suspend_rc(cinergyt2);
cancel_delayed_work(&cinergyt2->query_work);
if (cinergyt2->streaming)
cinergyt2_stop_stream_xfer(cinergyt2);
@@ -920,9 +971,8 @@ static int cinergyt2_resume (struct usb_interface *intf)
schedule_delayed_work(&cinergyt2->query_work, HZ/2);
}
-#ifdef ENABLE_RC
- schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
-#endif
+ cinergyt2_resume_rc(cinergyt2);
+
up(&cinergyt2->sem);
return 0;
}
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index fb55eaa5c8e7..9719a3b30f78 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -30,6 +30,7 @@
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/time.h>
+#include <linux/dvb/dmx.h>
/*--------------------------------------------------------------------------*/
/* Common definitions */
@@ -124,9 +125,7 @@ struct dmx_ts_feed {
u16 pid,
int type,
enum dmx_ts_pes pes_type,
- size_t callback_length,
size_t circular_buffer_size,
- int descramble,
struct timespec timeout);
int (*start_filtering) (struct dmx_ts_feed* feed);
int (*stop_filtering) (struct dmx_ts_feed* feed);
@@ -159,7 +158,6 @@ struct dmx_section_feed {
int (*set) (struct dmx_section_feed* feed,
u16 pid,
size_t circular_buffer_size,
- int descramble,
int check_crc);
int (*allocate_filter) (struct dmx_section_feed* feed,
struct dmx_section_filter** filter);
@@ -207,7 +205,6 @@ struct dmx_frontend {
struct list_head connectivity_list; /* List of front-ends that can
be connected to a particular
demux */
- void* priv; /* Pointer to private data of the API client */
enum dmx_frontend_source source;
};
@@ -225,8 +222,6 @@ struct dmx_frontend {
#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
#define DMX_CRC_CHECKING 16
#define DMX_TS_DESCRAMBLING 32
-#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
-#define DMX_MAC_ADDRESS_DESCRAMBLING 128
/*
* Demux resource type identifier.
@@ -244,9 +239,7 @@ struct dmx_frontend {
struct dmx_demux {
u32 capabilities; /* Bitfield of capability flags */
struct dmx_frontend* frontend; /* Front-end connected to the demux */
- struct list_head reg_list; /* List of registered demuxes */
void* priv; /* Pointer to private data of the API client */
- int users; /* Number of users */
int (*open) (struct dmx_demux* demux);
int (*close) (struct dmx_demux* demux);
int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
@@ -260,17 +253,6 @@ struct dmx_demux {
dmx_section_cb callback);
int (*release_section_feed) (struct dmx_demux* demux,
struct dmx_section_feed* feed);
- int (*descramble_mac_address) (struct dmx_demux* demux,
- u8* buffer1,
- size_t buffer1_length,
- u8* buffer2,
- size_t buffer2_length,
- u16 pid);
- int (*descramble_section_payload) (struct dmx_demux* demux,
- u8* buffer1,
- size_t buffer1_length,
- u8* buffer2, size_t buffer2_length,
- u16 pid);
int (*add_frontend) (struct dmx_demux* demux,
struct dmx_frontend* frontend);
int (*remove_frontend) (struct dmx_demux* demux,
@@ -282,20 +264,12 @@ struct dmx_demux {
int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
+ int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
+
+ int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src);
+
int (*get_stc) (struct dmx_demux* demux, unsigned int num,
u64 *stc, unsigned int *base);
};
-/*--------------------------------------------------------------------------*/
-/* Demux directory */
-/*--------------------------------------------------------------------------*/
-
-/*
- * DMX_DIR_ENTRY(): Casts elements in the list of registered
- * demuxes from the generic type struct list_head* to the type struct dmx_demux
- *.
- */
-
-#define DMX_DIR_ENTRY(list) list_entry(list, struct dmx_demux, reg_list)
-
#endif /* #ifndef __DEMUX_H */
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 68050cd527cb..8028c3a5e287 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -571,7 +571,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
return ret;
}
- ret=(*secfeed)->set(*secfeed, para->pid, 32768, 0,
+ ret=(*secfeed)->set(*secfeed, para->pid, 32768,
(para->flags & DMX_CHECK_CRC) ? 1 : 0);
if (ret<0) {
@@ -654,7 +654,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
(*tsfeed)->priv = (void *) filter;
ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
- 188, 32768, 0, timeout);
+ 32768, timeout);
if (ret < 0) {
dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
@@ -929,6 +929,22 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg);
break;
+ case DMX_GET_CAPS:
+ if (!dmxdev->demux->get_caps) {
+ ret = -EINVAL;
+ break;
+ }
+ ret = dmxdev->demux->get_caps(dmxdev->demux, parg);
+ break;
+
+ case DMX_SET_SOURCE:
+ if (!dmxdev->demux->set_source) {
+ ret = -EINVAL;
+ break;
+ }
+ ret = dmxdev->demux->set_source(dmxdev->demux, parg);
+ break;
+
case DMX_GET_STC:
if (!dmxdev->demux->get_stc) {
ret=-EINVAL;
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 0eb9aa711fb0..2aa767f9bd7d 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -36,6 +36,7 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/rwsem.h>
+#include <linux/sched.h>
#include "dvb_ca_en50221.h"
#include "dvb_ringbuffer.h"
@@ -47,7 +48,7 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
#define dprintk if (dvb_ca_en50221_debug) printk
-#define INIT_TIMEOUT_SECS 5
+#define INIT_TIMEOUT_SECS 10
#define HOST_LINK_BUF_SIZE 0x200
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index ac9889d22288..dc476dda2b71 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -38,82 +38,52 @@
*/
// #define DVB_DEMUX_SECTION_LOSS_LOG
-
-static LIST_HEAD(dmx_muxs);
-
-
-static int dmx_register_demux(struct dmx_demux *demux)
-{
- demux->users = 0;
- list_add(&demux->reg_list, &dmx_muxs);
- return 0;
-}
-
-static int dmx_unregister_demux(struct dmx_demux* demux)
-{
- struct list_head *pos, *n, *head=&dmx_muxs;
-
- list_for_each_safe (pos, n, head) {
- if (DMX_DIR_ENTRY(pos) == demux) {
- if (demux->users>0)
- return -EINVAL;
- list_del(pos);
- return 0;
- }
- }
-
- return -ENODEV;
-}
-
-
/******************************************************************************
* static inlined helper functions
******************************************************************************/
-
static inline u16 section_length(const u8 *buf)
{
- return 3+((buf[1]&0x0f)<<8)+buf[2];
+ return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
}
-
static inline u16 ts_pid(const u8 *buf)
{
- return ((buf[1]&0x1f)<<8)+buf[2];
+ return ((buf[1] & 0x1f) << 8) + buf[2];
}
-
static inline u8 payload(const u8 *tsp)
{
- if (!(tsp[3] & 0x10)) // no payload?
+ if (!(tsp[3] & 0x10)) // no payload?
return 0;
- if (tsp[3] & 0x20) { // adaptation field?
- if (tsp[4] > 183) // corrupted data?
+
+ if (tsp[3] & 0x20) { // adaptation field?
+ if (tsp[4] > 183) // corrupted data?
return 0;
else
- return 184-1-tsp[4];
+ return 184 - 1 - tsp[4];
}
+
return 184;
}
-
-static u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len)
+static u32 dvb_dmx_crc32(struct dvb_demux_feed *f, const u8 *src, size_t len)
{
- return (f->feed.sec.crc_val = crc32_be (f->feed.sec.crc_val, src, len));
+ return (f->feed.sec.crc_val = crc32_be(f->feed.sec.crc_val, src, len));
}
-
-static void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len)
+static void dvb_dmx_memcopy(struct dvb_demux_feed *f, u8 *d, const u8 *s,
+ size_t len)
{
- memcpy (d, s, len);
+ memcpy(d, s, len);
}
-
/******************************************************************************
* Software filter functions
******************************************************************************/
-static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf)
+static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
+ const u8 *buf)
{
int count = payload(buf);
int p;
@@ -123,32 +93,31 @@ static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u
if (count == 0)
return -1;
- p = 188-count;
+ p = 188 - count;
/*
- cc=buf[3]&0x0f;
- ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
- dvbdmxfeed->cc=cc;
+ cc = buf[3] & 0x0f;
+ ccok = ((feed->cc + 1) & 0x0f) == cc;
+ feed->cc = cc;
if (!ccok)
printk("missed packet!\n");
*/
- if (buf[1] & 0x40) // PUSI ?
+ if (buf[1] & 0x40) // PUSI ?
feed->peslen = 0xfffa;
feed->peslen += count;
- return feed->cb.ts (&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
+ return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
}
-
-static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
- struct dvb_demux_filter *f)
+static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
+ struct dvb_demux_filter *f)
{
u8 neq = 0;
int i;
- for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
+ for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i];
if (f->maskandmode[i] & xor)
@@ -160,12 +129,11 @@ static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
if (f->doneq && !neq)
return 0;
- return feed->cb.sec (feed->feed.sec.secbuf, feed->feed.sec.seclen,
- NULL, 0, &f->filter, DMX_OK);
+ return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
+ NULL, 0, &f->filter, DMX_OK);
}
-
-static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
+static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
struct dvb_demux_filter *f = feed->filter;
@@ -195,26 +163,24 @@ static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
return 0;
}
-
static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
{
struct dmx_section_feed *sec = &feed->feed.sec;
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
- if(sec->secbufp < sec->tsfeedp)
- {
+ if (sec->secbufp < sec->tsfeedp) {
int i, n = sec->tsfeedp - sec->secbufp;
- /* section padding is done with 0xff bytes entirely.
- ** due to speed reasons, we won't check all of them
- ** but just first and last
- */
- if(sec->secbuf[0] != 0xff || sec->secbuf[n-1] != 0xff)
- {
+ /*
+ * Section padding is done with 0xff bytes entirely.
+ * Due to speed reasons, we won't check all of them
+ * but just first and last.
+ */
+ if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
printk("dvb_demux.c section ts padding loss: %d/%d\n",
n, sec->tsfeedp);
printk("dvb_demux.c pad data:");
- for(i = 0; i < n; i++)
+ for (i = 0; i < n; i++)
printk(" %02x", sec->secbuf[i]);
printk("\n");
}
@@ -226,82 +192,81 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
}
/*
-** Losless Section Demux 1.4.1 by Emard
-** Valsecchi Patrick:
-** - middle of section A (no PUSI)
-** - end of section A and start of section B
-** (with PUSI pointing to the start of the second section)
-**
-** In this case, without feed->pusi_seen you'll receive a garbage section
-** consisting of the end of section A. Basically because tsfeedp
-** is incemented and the use=0 condition is not raised
-** when the second packet arrives.
-**
-** Fix:
-** when demux is started, let feed->pusi_seen = 0 to
-** prevent initial feeding of garbage from the end of
-** previous section. When you for the first time see PUSI=1
-** then set feed->pusi_seen = 1
-*/
-static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
+ * Losless Section Demux 1.4.1 by Emard
+ * Valsecchi Patrick:
+ * - middle of section A (no PUSI)
+ * - end of section A and start of section B
+ * (with PUSI pointing to the start of the second section)
+ *
+ * In this case, without feed->pusi_seen you'll receive a garbage section
+ * consisting of the end of section A. Basically because tsfeedp
+ * is incemented and the use=0 condition is not raised
+ * when the second packet arrives.
+ *
+ * Fix:
+ * when demux is started, let feed->pusi_seen = 0 to
+ * prevent initial feeding of garbage from the end of
+ * previous section. When you for the first time see PUSI=1
+ * then set feed->pusi_seen = 1
+ */
+static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
+ const u8 *buf, u8 len)
{
struct dvb_demux *demux = feed->demux;
struct dmx_section_feed *sec = &feed->feed.sec;
u16 limit, seclen, n;
- if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
+ if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
return 0;
- if(sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE)
- {
+ if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
printk("dvb_demux.c section buffer full loss: %d/%d\n",
- sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE);
+ sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
+ DMX_MAX_SECFEED_SIZE);
#endif
len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
}
- if(len <= 0)
+ if (len <= 0)
return 0;
demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
sec->tsfeedp += len;
- /* -----------------------------------------------------
- ** Dump all the sections we can find in the data (Emard)
- */
-
+ /*
+ * Dump all the sections we can find in the data (Emard)
+ */
limit = sec->tsfeedp;
- if(limit > DMX_MAX_SECFEED_SIZE)
- return -1; /* internal error should never happen */
+ if (limit > DMX_MAX_SECFEED_SIZE)
+ return -1; /* internal error should never happen */
/* to be sure always set secbuf */
sec->secbuf = sec->secbuf_base + sec->secbufp;
- for(n = 0; sec->secbufp + 2 < limit; n++)
- {
+ for (n = 0; sec->secbufp + 2 < limit; n++) {
seclen = section_length(sec->secbuf);
- if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
- || seclen + sec->secbufp > limit)
+ if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
+ || seclen + sec->secbufp > limit)
return 0;
sec->seclen = seclen;
sec->crc_val = ~0;
/* dump [secbuf .. secbuf+seclen) */
- if(feed->pusi_seen)
+ if (feed->pusi_seen)
dvb_dmx_swfilter_section_feed(feed);
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
else
printk("dvb_demux.c pusi not seen, discarding section data\n");
#endif
- sec->secbufp += seclen; /* secbufp and secbuf moving together is */
- sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
+ sec->secbufp += seclen; /* secbufp and secbuf moving together is */
+ sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
}
return 0;
}
-
-static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf)
+static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
+ const u8 *buf)
{
u8 p, count;
int ccok, dc_i = 0;
@@ -309,10 +274,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
count = payload(buf);
- if (count == 0) /* count == 0 if no payload or out of range */
+ if (count == 0) /* count == 0 if no payload or out of range */
return -1;
- p = 188 - count; /* payload start */
+ p = 188 - count; /* payload start */
cc = buf[3] & 0x0f;
ccok = ((feed->cc + 1) & 0x0f) == cc;
@@ -326,52 +291,53 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8
if (!ccok || dc_i) {
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
- printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
- /* those bytes under sume circumstances will again be reported
- ** in the following dvb_dmx_swfilter_section_new
- */
+ printk("dvb_demux.c discontinuity detected %d bytes lost\n",
+ count);
+ /*
+ * those bytes under sume circumstances will again be reported
+ * in the following dvb_dmx_swfilter_section_new
+ */
#endif
- /* Discontinuity detected. Reset pusi_seen = 0 to
- ** stop feeding of suspicious data until next PUSI=1 arrives
- */
+ /*
+ * Discontinuity detected. Reset pusi_seen = 0 to
+ * stop feeding of suspicious data until next PUSI=1 arrives
+ */
feed->pusi_seen = 0;
dvb_dmx_swfilter_section_new(feed);
- return 0;
}
if (buf[1] & 0x40) {
- // PUSI=1 (is set), section boundary is here
+ /* PUSI=1 (is set), section boundary is here */
if (count > 1 && buf[p] < count) {
- const u8 *before = buf+p+1;
+ const u8 *before = &buf[p + 1];
u8 before_len = buf[p];
- const u8 *after = before+before_len;
- u8 after_len = count-1-before_len;
+ const u8 *after = &before[before_len];
+ u8 after_len = count - 1 - before_len;
- dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
+ dvb_dmx_swfilter_section_copy_dump(feed, before,
+ before_len);
/* before start of new section, set pusi_seen = 1 */
feed->pusi_seen = 1;
dvb_dmx_swfilter_section_new(feed);
- dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
+ dvb_dmx_swfilter_section_copy_dump(feed, after,
+ after_len);
}
#ifdef DVB_DEMUX_SECTION_LOSS_LOG
- else
- if (count > 0)
- printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
+ else if (count > 0)
+ printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
#endif
} else {
- // PUSI=0 (is not set), no section boundary
- const u8 *entire = buf+p;
- u8 entire_len = count;
-
- dvb_dmx_swfilter_section_copy_dump(feed, entire, entire_len);
+ /* PUSI=0 (is not set), no section boundary */
+ dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
}
+
return 0;
}
-
-static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf)
+static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
+ const u8 *buf)
{
- switch(feed->type) {
+ switch (feed->type) {
case DMX_TYPE_TS:
if (!feed->feed.ts.is_filtering)
break;
@@ -379,7 +345,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
if (feed->ts_type & TS_PAYLOAD_ONLY)
dvb_dmx_swfilter_payload(feed, buf);
else
- feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
+ feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
+ DMX_OK);
}
if (feed->ts_type & TS_DECODER)
if (feed->demux->write_to_decoder)
@@ -390,7 +357,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
if (!feed->feed.sec.is_filtering)
break;
if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
- feed->feed.sec.seclen = feed->feed.sec.secbufp=0;
+ feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
break;
default:
@@ -406,7 +373,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, con
static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
{
struct dvb_demux_feed *feed;
- struct list_head *pos, *head=&demux->feed_list;
+ struct list_head *pos, *head = &demux->feed_list;
u16 pid = ts_pid(buf);
int dvr_done = 0;
@@ -432,21 +399,21 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
}
}
-void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)
+void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
+ size_t count)
{
spin_lock(&demux->lock);
while (count--) {
- if(buf[0] == 0x47) {
- dvb_dmx_swfilter_packet(demux, buf);
- }
+ if (buf[0] == 0x47)
+ dvb_dmx_swfilter_packet(demux, buf);
buf += 188;
}
spin_unlock(&demux->lock);
}
-EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
+EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
@@ -454,8 +421,10 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
spin_lock(&demux->lock);
- if ((i = demux->tsbufp)) {
- if (count < (j=188-i)) {
+ if (demux->tsbufp) {
+ i = demux->tsbufp;
+ j = 188 - i;
+ if (count < j) {
memcpy(&demux->tsbuf[i], buf, count);
demux->tsbufp += count;
goto bailout;
@@ -469,13 +438,13 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
while (p < count) {
if (buf[p] == 0x47) {
- if (count-p >= 188) {
- dvb_dmx_swfilter_packet(demux, buf+p);
+ if (count - p >= 188) {
+ dvb_dmx_swfilter_packet(demux, &buf[p]);
p += 188;
} else {
- i = count-p;
- memcpy(demux->tsbuf, buf+p, i);
- demux->tsbufp=i;
+ i = count - p;
+ memcpy(demux->tsbuf, &buf[p], i);
+ demux->tsbufp = i;
goto bailout;
}
} else
@@ -485,24 +454,29 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
bailout:
spin_unlock(&demux->lock);
}
+
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- int p = 0,i, j;
+ int p = 0, i, j;
u8 tmppack[188];
+
spin_lock(&demux->lock);
- if ((i = demux->tsbufp)) {
- if (count < (j=204-i)) {
+ if (demux->tsbufp) {
+ i = demux->tsbufp;
+ j = 204 - i;
+ if (count < j) {
memcpy(&demux->tsbuf[i], buf, count);
demux->tsbufp += count;
goto bailout;
}
memcpy(&demux->tsbuf[i], buf, j);
- if ((demux->tsbuf[0] == 0x47)|(demux->tsbuf[0]==0xB8)) {
+ if ((demux->tsbuf[0] == 0x47) | (demux->tsbuf[0] == 0xB8)) {
memcpy(tmppack, demux->tsbuf, 188);
- if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
+ if (tmppack[0] == 0xB8)
+ tmppack[0] = 0x47;
dvb_dmx_swfilter_packet(demux, tmppack);
}
demux->tsbufp = 0;
@@ -510,16 +484,17 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
}
while (p < count) {
- if ((buf[p] == 0x47)|(buf[p] == 0xB8)) {
- if (count-p >= 204) {
- memcpy(tmppack, buf+p, 188);
- if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
+ if ((buf[p] == 0x47) | (buf[p] == 0xB8)) {
+ if (count - p >= 204) {
+ memcpy(tmppack, &buf[p], 188);
+ if (tmppack[0] == 0xB8)
+ tmppack[0] = 0x47;
dvb_dmx_swfilter_packet(demux, tmppack);
p += 204;
} else {
- i = count-p;
- memcpy(demux->tsbuf, buf+p, i);
- demux->tsbufp=i;
+ i = count - p;
+ memcpy(demux->tsbuf, &buf[p], i);
+ demux->tsbufp = i;
goto bailout;
}
} else {
@@ -530,14 +505,14 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
bailout:
spin_unlock(&demux->lock);
}
-EXPORT_SYMBOL(dvb_dmx_swfilter_204);
+EXPORT_SYMBOL(dvb_dmx_swfilter_204);
-static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
+static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
{
int i;
- for (i=0; i<demux->filternum; i++)
+ for (i = 0; i < demux->filternum; i++)
if (demux->filter[i].state == DMX_STATE_FREE)
break;
@@ -549,11 +524,11 @@ static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
return &demux->filter[i];
}
-static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux)
+static struct dvb_demux_feed *dvb_dmx_feed_alloc(struct dvb_demux *demux)
{
int i;
- for (i=0; i<demux->feednum; i++)
+ for (i = 0; i < demux->feednum; i++)
if (demux->feed[i].state == DMX_STATE_FREE)
break;
@@ -581,7 +556,7 @@ static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
spin_lock_irq(&feed->demux->lock);
if (dvb_demux_feed_find(feed)) {
printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
- __FUNCTION__, feed->type, feed->state, feed->pid);
+ __FUNCTION__, feed->type, feed->state, feed->pid);
goto out;
}
@@ -595,7 +570,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
spin_lock_irq(&feed->demux->lock);
if (!(dvb_demux_feed_find(feed))) {
printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
- __FUNCTION__, feed->type, feed->state, feed->pid);
+ __FUNCTION__, feed->type, feed->state, feed->pid);
goto out;
}
@@ -604,18 +579,17 @@ out:
spin_unlock_irq(&feed->demux->lock);
}
-static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
- enum dmx_ts_pes pes_type, size_t callback_length,
- size_t circular_buffer_size, int descramble,
- struct timespec timeout)
+static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
+ enum dmx_ts_pes pes_type,
+ size_t circular_buffer_size, struct timespec timeout)
{
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
struct dvb_demux *demux = feed->demux;
if (pid > DMX_MAX_PID)
return -EINVAL;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (ts_type & TS_DECODER) {
@@ -638,20 +612,13 @@ static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
feed->pid = pid;
feed->buffer_size = circular_buffer_size;
- feed->descramble = descramble;
feed->timeout = timeout;
- feed->cb_length = callback_length;
feed->ts_type = ts_type;
feed->pes_type = pes_type;
- if (feed->descramble) {
- up(&demux->mutex);
- return -ENOSYS;
- }
-
if (feed->buffer_size) {
#ifdef NOBUFS
- feed->buffer=NULL;
+ feed->buffer = NULL;
#else
feed->buffer = vmalloc(feed->buffer_size);
if (!feed->buffer) {
@@ -667,14 +634,13 @@ static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
return 0;
}
-
-static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
+static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed)
{
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
struct dvb_demux *demux = feed->demux;
int ret;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
@@ -701,13 +667,13 @@ static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
return 0;
}
-static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
+static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
{
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
struct dvb_demux *demux = feed->demux;
int ret;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state < DMX_STATE_GO) {
@@ -731,13 +697,14 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
return ret;
}
-static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed,
- dmx_ts_cb callback)
+static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
+ struct dmx_ts_feed **ts_feed,
+ dmx_ts_cb callback)
{
- struct dvb_demux *demux = (struct dvb_demux *) dmx;
+ struct dvb_demux *demux = (struct dvb_demux *)dmx;
struct dvb_demux_feed *feed;
- if (down_interruptible (&demux->mutex))
+ if (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (!(feed = dvb_dmx_feed_alloc(demux))) {
@@ -760,7 +727,6 @@ static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **
(*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
(*ts_feed)->set = dmx_ts_feed_set;
-
if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
feed->state = DMX_STATE_FREE;
up(&demux->mutex);
@@ -776,22 +742,22 @@ static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **
return 0;
}
-static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed)
+static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
+ struct dmx_ts_feed *ts_feed)
{
- struct dvb_demux *demux = (struct dvb_demux *) dmx;
- struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
+ 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 (down_interruptible(&demux->mutex))
return -ERESTARTSYS;
if (feed->state == DMX_STATE_FREE) {
up(&demux->mutex);
return -EINVAL;
}
-
#ifndef NOBUFS
vfree(feed->buffer);
- feed->buffer=0;
+ feed->buffer = NULL;
#endif
feed->state = DMX_STATE_FREE;
@@ -808,19 +774,18 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_
return 0;
}
-
/******************************************************************************
* dmx_section_feed API calls
******************************************************************************/
-static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed,
- struct dmx_section_filter** filter)
+static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed,
+ struct dmx_section_filter **filter)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
struct dvb_demux_filter *dvbdmxfilter;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
@@ -844,36 +809,29 @@ static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed,
return 0;
}
-
-static int dmx_section_feed_set(struct dmx_section_feed* feed,
- u16 pid, size_t circular_buffer_size,
- int descramble, int check_crc)
+static int dmx_section_feed_set(struct dmx_section_feed *feed,
+ u16 pid, size_t circular_buffer_size,
+ int check_crc)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
if (pid > 0x1fff)
return -EINVAL;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
dvb_demux_feed_add(dvbdmxfeed);
dvbdmxfeed->pid = pid;
dvbdmxfeed->buffer_size = circular_buffer_size;
- dvbdmxfeed->descramble = descramble;
- if (dvbdmxfeed->descramble) {
- up(&dvbdmx->mutex);
- return -ENOSYS;
- }
-
dvbdmxfeed->feed.sec.check_crc = check_crc;
#ifdef NOBUFS
dvbdmxfeed->buffer = NULL;
#else
- dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);
+ dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size);
if (!dvbdmxfeed->buffer) {
up(&dvbdmx->mutex);
return -ENOMEM;
@@ -885,7 +843,6 @@ static int dmx_section_feed_set(struct dmx_section_feed* feed,
return 0;
}
-
static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
{
int i;
@@ -893,12 +850,12 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
struct dmx_section_filter *sf;
u8 mask, mode, doneq;
- if (!(f=dvbdmxfeed->filter))
+ if (!(f = dvbdmxfeed->filter))
return;
do {
sf = &f->filter;
doneq = 0;
- for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
+ for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
mode = sf->filter_mode[i];
mask = sf->filter_mask[i];
f->maskandmode[i] = mask & mode;
@@ -908,14 +865,13 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
} while ((f = f->next));
}
-
static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
int ret;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (feed->is_filtering) {
@@ -954,14 +910,13 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
return 0;
}
-
-static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
+static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
int ret;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (!dvbdmx->stop_feed) {
@@ -980,15 +935,14 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
return ret;
}
-
static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
- struct dmx_section_filter* filter)
+ struct dmx_section_filter *filter)
{
- struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *) filter, *f;
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
+ struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *)filter, *f;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (dvbdmxfilter->feed != dvbdmxfeed) {
@@ -1005,7 +959,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
if (f == dvbdmxfilter) {
dvbdmxfeed->filter = dvbdmxfilter->next;
} else {
- while(f->next != dvbdmxfilter)
+ while (f->next != dvbdmxfilter)
f = f->next;
f->next = f->next->next;
}
@@ -1020,10 +974,10 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
struct dmx_section_feed **feed,
dmx_section_cb callback)
{
- struct dvb_demux *dvbdmx = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
struct dvb_demux_feed *dvbdmxfeed;
- if (down_interruptible (&dvbdmx->mutex))
+ if (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
@@ -1041,7 +995,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
dvbdmxfeed->filter = NULL;
dvbdmxfeed->buffer = NULL;
- (*feed)=&dvbdmxfeed->feed.sec;
+ (*feed) = &dvbdmxfeed->feed.sec;
(*feed)->is_filtering = 0;
(*feed)->parent = demux;
(*feed)->priv = NULL;
@@ -1059,21 +1013,21 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
static int dvbdmx_release_section_feed(struct dmx_demux *demux,
struct dmx_section_feed *feed)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
- struct dvb_demux *dvbdmx = (struct dvb_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 (down_interruptible(&dvbdmx->mutex))
return -ERESTARTSYS;
- if (dvbdmxfeed->state==DMX_STATE_FREE) {
+ if (dvbdmxfeed->state == DMX_STATE_FREE) {
up(&dvbdmx->mutex);
return -EINVAL;
}
#ifndef NOBUFS
vfree(dvbdmxfeed->buffer);
- dvbdmxfeed->buffer=0;
+ dvbdmxfeed->buffer = NULL;
#endif
- dvbdmxfeed->state=DMX_STATE_FREE;
+ dvbdmxfeed->state = DMX_STATE_FREE;
dvb_demux_feed_del(dvbdmxfeed);
@@ -1083,14 +1037,13 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
return 0;
}
-
/******************************************************************************
* dvb_demux kernel data API calls
******************************************************************************/
static int dvbdmx_open(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (dvbdemux->users >= MAX_DVB_DEMUX_USERS)
return -EUSERS;
@@ -1099,10 +1052,9 @@ static int dvbdmx_open(struct dmx_demux *demux)
return 0;
}
-
static int dvbdmx_close(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (dvbdemux->users == 0)
return -ENODEV;
@@ -1112,15 +1064,14 @@ static int dvbdmx_close(struct dmx_demux *demux)
return 0;
}
-
static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
{
- struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
return -EINVAL;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
dvb_dmx_swfilter(dvbdemux, buf, count);
up(&dvbdemux->mutex);
@@ -1130,10 +1081,10 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
return count;
}
-
-static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
+static int dvbdmx_add_frontend(struct dmx_demux *demux,
+ struct dmx_frontend *frontend)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
struct list_head *head = &dvbdemux->frontend_list;
list_add(&(frontend->connectivity_list), head);
@@ -1141,13 +1092,13 @@ static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *fro
return 0;
}
-
-static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
+static int dvbdmx_remove_frontend(struct dmx_demux *demux,
+ struct dmx_frontend *frontend)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
struct list_head *pos, *n, *head = &dvbdemux->frontend_list;
- list_for_each_safe (pos, n, head) {
+ list_for_each_safe(pos, n, head) {
if (DMX_FE_ENTRY(pos) == frontend) {
list_del(pos);
return 0;
@@ -1157,25 +1108,25 @@ static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *
return -ENODEV;
}
-
-static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux)
+static struct list_head *dvbdmx_get_frontends(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (list_empty(&dvbdemux->frontend_list))
return NULL;
+
return &dvbdemux->frontend_list;
}
-
-static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
+static int dvbdmx_connect_frontend(struct dmx_demux *demux,
+ struct dmx_frontend *frontend)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
if (demux->frontend)
return -EINVAL;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
demux->frontend = frontend;
@@ -1183,12 +1134,11 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend
return 0;
}
-
static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
- if (down_interruptible (&dvbdemux->mutex))
+ if (down_interruptible(&dvbdemux->mutex))
return -ERESTARTSYS;
demux->frontend = NULL;
@@ -1196,44 +1146,42 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
return 0;
}
-
-static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids)
+static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 * pids)
{
- struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
+ struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
- memcpy(pids, dvbdemux->pids, 5*sizeof(u16));
+ memcpy(pids, dvbdemux->pids, 5 * sizeof(u16));
return 0;
}
-
int dvb_dmx_init(struct dvb_demux *dvbdemux)
{
- int i, err;
+ int i;
struct dmx_demux *dmx = &dvbdemux->dmx;
dvbdemux->users = 0;
- dvbdemux->filter = vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter));
+ dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter));
if (!dvbdemux->filter)
return -ENOMEM;
- dvbdemux->feed = vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed));
+ dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed));
if (!dvbdemux->feed) {
vfree(dvbdemux->filter);
return -ENOMEM;
}
- for (i=0; i<dvbdemux->filternum; i++) {
+ for (i = 0; i < dvbdemux->filternum; i++) {
dvbdemux->filter[i].state = DMX_STATE_FREE;
dvbdemux->filter[i].index = i;
}
- for (i=0; i<dvbdemux->feednum; i++) {
+ for (i = 0; i < dvbdemux->feednum; i++) {
dvbdemux->feed[i].state = DMX_STATE_FREE;
dvbdemux->feed[i].index = i;
}
- dvbdemux->frontend_list.next=
- dvbdemux->frontend_list.prev=
- &dvbdemux->frontend_list;
- for (i=0; i<DMX_TS_PES_OTHER; i++) {
+
+ INIT_LIST_HEAD(&dvbdemux->frontend_list);
+
+ for (i = 0; i < DMX_TS_PES_OTHER; i++) {
dvbdemux->pesfilter[i] = NULL;
dvbdemux->pids[i] = 0xffff;
}
@@ -1247,12 +1195,11 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
if (!dvbdemux->check_crc32)
dvbdemux->check_crc32 = dvb_dmx_crc32;
- if (!dvbdemux->memcopy)
- dvbdemux->memcopy = dvb_dmx_memcopy;
+ if (!dvbdemux->memcopy)
+ dvbdemux->memcopy = dvb_dmx_memcopy;
dmx->frontend = NULL;
- dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list;
- dmx->priv = (void *) dvbdemux;
+ dmx->priv = dvbdemux;
dmx->open = dvbdmx_open;
dmx->close = dvbdmx_close;
dmx->write = dvbdmx_write;
@@ -1261,9 +1208,6 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
dmx->allocate_section_feed = dvbdmx_allocate_section_feed;
dmx->release_section_feed = dvbdmx_release_section_feed;
- dmx->descramble_mac_address = NULL;
- dmx->descramble_section_payload = NULL;
-
dmx->add_frontend = dvbdmx_add_frontend;
dmx->remove_frontend = dvbdmx_remove_frontend;
dmx->get_frontends = dvbdmx_get_frontends;
@@ -1274,21 +1218,15 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
sema_init(&dvbdemux->mutex, 1);
spin_lock_init(&dvbdemux->lock);
- if ((err = dmx_register_demux(dmx)) < 0)
- return err;
-
return 0;
}
-EXPORT_SYMBOL(dvb_dmx_init);
+EXPORT_SYMBOL(dvb_dmx_init);
-int dvb_dmx_release(struct dvb_demux *dvbdemux)
+void dvb_dmx_release(struct dvb_demux *dvbdemux)
{
- struct dmx_demux *dmx = &dvbdemux->dmx;
-
- dmx_unregister_demux(dmx);
vfree(dvbdemux->filter);
vfree(dvbdemux->feed);
- return 0;
}
+
EXPORT_SYMBOL(dvb_dmx_release);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index c09beb391622..0cc888339d52 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -20,7 +20,6 @@
*
*/
-
#ifndef _DVB_DEMUX_H_
#define _DVB_DEMUX_H_
@@ -44,103 +43,98 @@
#define DVB_DEMUX_MASK_MAX 18
struct dvb_demux_filter {
- struct dmx_section_filter filter;
- u8 maskandmode [DMX_MAX_FILTER_SIZE];
- u8 maskandnotmode [DMX_MAX_FILTER_SIZE];
+ struct dmx_section_filter filter;
+ u8 maskandmode[DMX_MAX_FILTER_SIZE];
+ u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
int doneq;
- struct dvb_demux_filter *next;
- struct dvb_demux_feed *feed;
- int index;
- int state;
- int type;
- int pesto;
-
- u16 handle;
- u16 hw_handle;
- struct timer_list timer;
- int ts_state;
-};
+ struct dvb_demux_filter *next;
+ struct dvb_demux_feed *feed;
+ int index;
+ int state;
+ int type;
+ u16 hw_handle;
+ struct timer_list timer;
+};
#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
struct dvb_demux_feed {
- union {
- struct dmx_ts_feed ts;
- struct dmx_section_feed sec;
+ union {
+ struct dmx_ts_feed ts;
+ struct dmx_section_feed sec;
} feed;
- union {
- dmx_ts_cb ts;
- dmx_section_cb sec;
+ union {
+ dmx_ts_cb ts;
+ dmx_section_cb sec;
} cb;
- struct dvb_demux *demux;
+ struct dvb_demux *demux;
void *priv;
- int type;
- int state;
- u16 pid;
- u8 *buffer;
- int buffer_size;
- int descramble;
+ int type;
+ int state;
+ u16 pid;
+ u8 *buffer;
+ int buffer_size;
- struct timespec timeout;
- struct dvb_demux_filter *filter;
- int cb_length;
+ struct timespec timeout;
+ struct dvb_demux_filter *filter;
- int ts_type;
- enum dmx_ts_pes pes_type;
+ int ts_type;
+ enum dmx_ts_pes pes_type;
- int cc;
- int pusi_seen; /* prevents feeding of garbage from previous section */
+ int cc;
+ int pusi_seen; /* prevents feeding of garbage from previous section */
- u16 peslen;
+ u16 peslen;
struct list_head list_head;
- int index; /* a unique index for each feed (can be used as hardware pid filter index) */
+ unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */
};
struct dvb_demux {
- struct dmx_demux dmx;
- void *priv;
- int filternum;
- int feednum;
- int (*start_feed) (struct dvb_demux_feed *feed);
- int (*stop_feed) (struct dvb_demux_feed *feed);
- int (*write_to_decoder) (struct dvb_demux_feed *feed,
+ struct dmx_demux dmx;
+ void *priv;
+ int filternum;
+ int feednum;
+ int (*start_feed)(struct dvb_demux_feed *feed);
+ int (*stop_feed)(struct dvb_demux_feed *feed);
+ int (*write_to_decoder)(struct dvb_demux_feed *feed,
const u8 *buf, size_t len);
- u32 (*check_crc32) (struct dvb_demux_feed *feed,
+ u32 (*check_crc32)(struct dvb_demux_feed *feed,
const u8 *buf, size_t len);
- void (*memcopy) (struct dvb_demux_feed *feed, u8 *dst,
+ void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
const u8 *src, size_t len);
- int users;
+ int users;
#define MAX_DVB_DEMUX_USERS 10
- struct dvb_demux_filter *filter;
- struct dvb_demux_feed *feed;
+ struct dvb_demux_filter *filter;
+ struct dvb_demux_feed *feed;
- struct list_head frontend_list;
+ struct list_head frontend_list;
- struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
- u16 pids[DMX_TS_PES_OTHER];
- int playing;
- int recording;
+ struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
+ u16 pids[DMX_TS_PES_OTHER];
+ int playing;
+ int recording;
#define DMX_MAX_PID 0x2000
struct list_head feed_list;
- u8 tsbuf[204];
- int tsbufp;
+ u8 tsbuf[204];
+ int tsbufp;
struct semaphore mutex;
spinlock_t lock;
};
-
int dvb_dmx_init(struct dvb_demux *dvbdemux);
-int dvb_dmx_release(struct dvb_demux *dvbdemux);
-void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count);
+void dvb_dmx_release(struct dvb_demux *dvbdemux);
+void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
+ size_t count);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
-void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count);
+void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
+ size_t count);
#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 6a968c346a36..87935490bfb2 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -62,7 +62,6 @@
#include <linux/uio.h>
#include <asm/uaccess.h>
#include <linux/crc32.h>
-#include <linux/version.h>
#include "dvb_demux.h"
#include "dvb_net.h"
@@ -171,11 +170,7 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
skb->mac.raw=skb->data;
skb_pull(skb,dev->hard_header_len);
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8)
- eth = skb->mac.ethernet;
-#else
eth = eth_hdr(skb);
-#endif
if (*eth->h_dest & 1) {
if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
@@ -908,7 +903,7 @@ static int dvb_net_feed_start(struct net_device *dev)
return ret;
}
- ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 1);
+ ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1);
if (ret<0) {
printk("%s: could not set section feed\n", dev->name);
@@ -960,9 +955,7 @@ static int dvb_net_feed_start(struct net_device *dev)
priv->tsfeed->priv = (void *)dev;
ret = priv->tsfeed->set(priv->tsfeed, priv->pid,
TS_PACKET, DMX_TS_PES_OTHER,
- 188 * 100, /* nr. of bytes delivered per callback */
32768, /* circular buffer size */
- 0, /* descramble */
timeout);
if (ret < 0) {
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 4b7adca3e286..477b4fa56430 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -235,7 +235,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
S_IFCHR | S_IRUSR | S_IWUSR,
"dvb/adapter%d/%s%d", adap->num, dnames[type], id);
- class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+ class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 612e5b087b1c..54e2b29076b1 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -93,13 +93,30 @@ config DVB_USB_DIGITV
Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
config DVB_USB_VP7045
- tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support"
+ tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
depends on DVB_USB
help
Say Y here to support the
+
TwinhanDTV Alpha (stick) (VP-7045),
- TwinhanDTV MagicBox II (VP-7046) and
- DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers.
+ TwinhanDTV MagicBox II (VP-7046),
+ DigitalNow TinyUSB 2 DVB-t,
+ DigitalRise USB 2.0 Ter (Beetle) and
+ TYPHOON DVB-T USB DRIVE
+
+ DVB-T USB2.0 receivers.
+
+config DVB_USB_VP702X
+ tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the
+
+ TwinhanDTV StarBox,
+ DigitalRise USB Starbox and
+ TYPHOON DVB-S USB 2.0 BOX
+
+ DVB-S USB2.0 receivers.
config DVB_USB_NOVA_T_USB2
tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 746d87ed6f32..2dc9aad9681e 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -4,6 +4,9 @@ obj-$(CONFIG_DVB_USB) += dvb-usb.o
dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
+dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
+obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
+
dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index f2fcc2f1f846..e55322ef76b3 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -90,7 +90,7 @@ static struct dvb_usb_properties a800_properties;
static int a800_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE,NULL);
}
/* do not change the order of the ID table */
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index c3e1b661aae6..3fe383f4bb4c 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -48,35 +48,26 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
return 0;
}
-/* I2C */
-static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path)
+/* GPIO */
+static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
{
struct cxusb_state *st = d->priv;
u8 o[2],i;
- if (path == st->cur_i2c_path)
+ if (st->gpio_write_state[GPIO_TUNER] == onoff)
return;
- o[0] = IOCTL_SET_I2C_PATH;
- switch (path) {
- case PATH_CX22702:
- o[1] = 0;
- break;
- case PATH_TUNER_OTHER:
- o[1] = 1;
- break;
- default:
- err("unkown i2c path");
- return;
- }
- cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1);
+ o[0] = GPIO_TUNER;
+ o[1] = onoff;
+ cxusb_ctrl_msg(d,CMD_GPIO_WRITE,o,2,&i,1);
if (i != 0x01)
- deb_info("i2c_path setting failed.\n");
+ deb_info("gpio_write failed.\n");
- st->cur_i2c_path = path;
+ st->gpio_write_state[GPIO_TUNER] = onoff;
}
+/* I2C */
static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
@@ -92,10 +83,10 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
switch (msg[i].addr) {
case 0x63:
- cxusb_set_i2c_path(d,PATH_CX22702);
+ cxusb_gpio_tuner(d,0);
break;
default:
- cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
+ cxusb_gpio_tuner(d,1);
break;
}
@@ -141,24 +132,26 @@ static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
}
static struct i2c_algorithm cxusb_i2c_algo = {
- .name = "Conexant USB I2C algorithm",
- .id = I2C_ALGO_BIT,
.master_xfer = cxusb_i2c_xfer,
.functionality = cxusb_i2c_func,
};
static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
{
- return 0;
+ u8 b = 0;
+ if (onoff)
+ return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
+ else
+ return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
}
static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 buf[2] = { 0x03, 0x00 };
if (onoff)
- cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
+ cxusb_ctrl_msg(d,CMD_STREAMING_ON, buf, 2, NULL, 0);
else
- cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0);
+ cxusb_ctrl_msg(d,CMD_STREAMING_OFF, NULL, 0, NULL, 0);
return 0;
}
@@ -184,22 +177,11 @@ static int cxusb_tuner_attach(struct dvb_usb_device *d)
static int cxusb_frontend_attach(struct dvb_usb_device *d)
{
- u8 buf[2] = { 0x03, 0x00 };
- u8 b = 0;
-
- if (usb_set_interface(d->udev,0,0) < 0)
- err("set interface to alts=0 failed");
-
- cxusb_ctrl_msg(d,0xde,&b,0,NULL,0);
- cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
- cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1);
-
+ u8 b;
if (usb_set_interface(d->udev,0,6) < 0)
err("set interface failed");
- cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
- cxusb_set_i2c_path(d,PATH_CX22702);
- cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1);
+ cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1);
if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
return 0;
@@ -213,7 +195,7 @@ static struct dvb_usb_properties cxusb_properties;
static int cxusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL);
}
static struct usb_device_id cxusb_table [] = {
@@ -239,14 +221,12 @@ static struct dvb_usb_properties cxusb_properties = {
.generic_bulk_ctrl_endpoint = 0x01,
/* parameter for the MPEG2-data transfer */
.urb = {
- .type = DVB_USB_ISOC,
+ .type = DVB_USB_BULK,
.count = 5,
.endpoint = 0x02,
.u = {
- .isoc = {
- .framesperurb = 32,
- .framesize = 940,
- .interval = 5,
+ .bulk = {
+ .buffersize = 8192,
}
}
},
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 1d79016e3195..135c2a81f581 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -1,30 +1,31 @@
#ifndef _DVB_USB_CXUSB_H_
#define _DVB_USB_CXUSB_H_
-#define DVB_USB_LOG_PREFIX "digitv"
+#define DVB_USB_LOG_PREFIX "cxusb"
#include "dvb-usb.h"
extern int dvb_usb_cxusb_debug;
#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
/* usb commands - some of it are guesses, don't have a reference yet */
-#define CMD_I2C_WRITE 0x08
-#define CMD_I2C_READ 0x09
+#define CMD_I2C_WRITE 0x08
+#define CMD_I2C_READ 0x09
-#define CMD_IOCTL 0x0e
-#define IOCTL_SET_I2C_PATH 0x02
+#define CMD_GPIO_READ 0x0d
+#define CMD_GPIO_WRITE 0x0e
+#define GPIO_TUNER 0x02
-#define CMD_POWER_OFF 0x50
-#define CMD_POWER_ON 0x51
+#define CMD_POWER_OFF 0xdc
+#define CMD_POWER_ON 0xde
-enum cxusb_i2c_pathes {
- PATH_UNDEF = 0x00,
- PATH_CX22702 = 0x01,
- PATH_TUNER_OTHER = 0x02,
-};
+#define CMD_STREAMING_ON 0x36
+#define CMD_STREAMING_OFF 0x37
+
+#define CMD_ANALOG 0x50
+#define CMD_DIGITAL 0x51
struct cxusb_state {
- enum cxusb_i2c_pathes cur_i2c_path;
+ u8 gpio_write_state[3];
};
#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 63b626f70c81..00b946419b40 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -70,13 +70,22 @@ EXPORT_SYMBOL(dibusb_power_ctrl);
int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
{
- u8 b[2];
- b[0] = DIBUSB_REQ_SET_IOCTL;
- b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
+ u8 b[3] = { 0 };
+ int ret;
+
+ if ((ret = dibusb_streaming_ctrl(d,onoff)) < 0)
+ return ret;
- dvb_usb_generic_write(d,b,3);
+ if (onoff) {
+ b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
+ b[1] = 0x00;
+ if ((ret = dvb_usb_generic_write(d,b,2)) < 0)
+ return ret;
+ }
- return dibusb_streaming_ctrl(d,onoff);
+ b[0] = DIBUSB_REQ_SET_IOCTL;
+ b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
+ return dvb_usb_generic_write(d,b,3);
}
EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
@@ -147,8 +156,6 @@ static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
}
struct i2c_algorithm dibusb_i2c_algo = {
- .name = "DiBcom USB I2C algorithm",
- .id = I2C_ALGO_BIT,
.master_xfer = dibusb_i2c_xfer,
.functionality = dibusb_i2c_func,
};
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 828b5182e16c..0058505634a0 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -86,9 +86,9 @@ static struct dvb_usb_properties dibusb2_0b_properties;
static int dibusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 ||
- dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 ||
- dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0)
+ if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0)
return 0;
return -EINVAL;
@@ -126,10 +126,12 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
+/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
+
// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
-/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
#endif
{ } /* Terminating entry */
};
@@ -262,7 +264,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
},
#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
{ "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
- { &dibusb_dib3000mb_table[27], NULL },
+ { &dibusb_dib3000mb_table[28], NULL },
{ NULL },
},
#endif
@@ -306,12 +308,16 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
}
},
- .num_device_descs = 1,
+ .num_device_descs = 2,
.devices = {
- { "KWorld/ADSTech Instant DVB-T USB 2.0",
+ { "KWorld/ADSTech Instant DVB-T USB2.0",
{ &dibusb_dib3000mb_table[23], NULL },
{ &dibusb_dib3000mb_table[24], NULL },
},
+ { "KWorld Xpert DVB-T USB2.0",
+ { &dibusb_dib3000mb_table[27], NULL },
+ { NULL }
+ },
}
};
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index e9dac430f37d..6a0912eab396 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -20,7 +20,7 @@ static struct dvb_usb_properties dibusb_mc_properties;
static int dibusb_mc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE,NULL);
}
/* do not change the order of the ID table */
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 9a676afc1d6e..74545f82eff1 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -77,8 +77,6 @@ static u32 digitv_i2c_func(struct i2c_adapter *adapter)
}
static struct i2c_algorithm digitv_i2c_algo = {
- .name = "Nebula DigiTV USB I2C algorithm",
- .id = I2C_ALGO_BIT,
.master_xfer = digitv_i2c_xfer,
.functionality = digitv_i2c_func,
};
@@ -113,31 +111,28 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe)
}
static struct mt352_config digitv_mt352_config = {
- .demod_address = 0x0, /* ignored by the digitv anyway */
.demod_init = digitv_mt352_demod_init,
.pll_set = dvb_usb_pll_set,
};
-static struct nxt6000_config digitv_nxt6000_config = {
- .demod_address = 0x0, /* ignored by the digitv anyway */
- .clock_inversion = 0x0,
+static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ u8 b[5];
+ dvb_usb_pll_set(fe,fep,b);
+ return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
+}
- .pll_init = NULL,
- .pll_set = NULL,
+static struct nxt6000_config digitv_nxt6000_config = {
+ .clock_inversion = 1,
+ .pll_set = digitv_nxt6000_pll_set,
};
static int digitv_frontend_attach(struct dvb_usb_device *d)
{
- if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL)
+ if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL ||
+ (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL)
return 0;
- if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
-
- warn("nxt6000 support is not done yet, in fact you are one of the first "
- "person who wants to use this device in Linux. Please report to "
- "linux-dvb@linuxtv.org");
-
- return 0;
- }
return -EIO;
}
@@ -175,7 +170,18 @@ static struct dvb_usb_properties digitv_properties;
static int digitv_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE);
+ struct dvb_usb_device *d;
+ int ret;
+ 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);
+
+ b[0] = 0;
+ digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+ }
+ return ret;
}
static struct usb_device_id digitv_table [] = {
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index b032523b07bc..0a94ec22aeb8 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -18,6 +18,7 @@ struct dtt200u_fe_state {
struct dvb_frontend_parameters fep;
struct dvb_frontend frontend;
+ struct dvb_frontend_ops ops;
};
static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
@@ -163,8 +164,9 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
deb_info("attaching frontend dtt200u\n");
state->d = d;
+ memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
- state->frontend.ops = &dtt200u_fe_ops;
+ state->frontend.ops = &state->ops;
state->frontend.demodulator_priv = state;
goto success;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 47dba6e45968..b595476332cd 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -98,20 +98,19 @@ static struct dvb_usb_properties wt220u_properties;
static int dtt200u_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 ||
- dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0)
+ if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
+ dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0)
return 0;
return -ENODEV;
}
static struct usb_device_id dtt200u_usb_table [] = {
-// { USB_DEVICE(0x04b4,0x8613) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
- { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
- { 0 },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
+ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
+ { 0 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
@@ -152,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = {
.cold_ids = { &dtt200u_usb_table[0], NULL },
.warm_ids = { &dtt200u_usb_table[1], NULL },
},
- { 0 },
+ { NULL },
}
};
@@ -189,11 +188,11 @@ static struct dvb_usb_properties wt220u_properties = {
.num_device_descs = 1,
.devices = {
- { .name = "WideView WT-220U PenType Receiver (and clones)",
+ { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
.cold_ids = { &dtt200u_usb_table[2], NULL },
.warm_ids = { &dtt200u_usb_table[3], NULL },
},
- { 0 },
+ { NULL },
}
};
@@ -201,9 +200,9 @@ static struct dvb_usb_properties wt220u_properties = {
static struct usb_driver dtt200u_usb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_dtt200u",
- .probe = dtt200u_usb_probe,
+ .probe = dtt200u_usb_probe,
.disconnect = dvb_usb_device_exit,
- .id_table = dtt200u_usb_table,
+ .id_table = dtt200u_usb_table,
};
/* module stuff */
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index 3491ff40885c..6fa92100248b 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -23,12 +23,12 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
*/
if (newfeedcount == 0) {
deb_ts("stop feeding\n");
+ dvb_usb_urb_kill(d);
if (d->props.streaming_ctrl != NULL)
if ((ret = d->props.streaming_ctrl(d,0)))
err("error while stopping stream.");
- dvb_usb_urb_kill(d);
}
d->feedcount = newfeedcount;
@@ -44,6 +44,8 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
* for reception.
*/
if (d->feedcount == onoff && d->feedcount > 0) {
+ deb_ts("submitting all URBs\n");
+ dvb_usb_urb_submit(d);
deb_ts("controlling pid parser\n");
if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
@@ -59,7 +61,6 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
return -ENODEV;
}
- dvb_usb_urb_submit(d);
}
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 9f0a8d90d146..da970947dfc7 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -27,7 +27,6 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
#endif
d->i2c_adap.algo = d->props.i2c_algo;
d->i2c_adap.algo_data = NULL;
- d->i2c_adap.id = I2C_ALGO_BIT;
i2c_set_adapdata(&d->i2c_adap, d);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 794d513a8480..0818996bf150 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -24,8 +24,10 @@
#define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_KWORLD 0xeb2a
#define USB_VID_KYE 0x0458
#define USB_VID_MEDION 0x1660
+#define USB_VID_PINNACLE 0x2304
#define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
@@ -52,12 +54,14 @@
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
#define USB_PID_TWINHAN_VP7041_WARM 0x3202
+#define USB_PID_TWINHAN_VP7020_COLD 0x3203
+#define USB_PID_TWINHAN_VP7020_WARM 0x3204
#define USB_PID_TWINHAN_VP7045_COLD 0x3205
#define USB_PID_TWINHAN_VP7045_WARM 0x3206
-#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
-#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_TWINHAN_VP7021_COLD 0x3207
#define USB_PID_TWINHAN_VP7021_WARM 0x3208
+#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
+#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
@@ -85,5 +89,7 @@
#define USB_PID_MEDION_MD95700 0x0932
#define USB_PID_KYE_DVB_T_COLD 0x701e
#define USB_PID_KYE_DVB_T_WARM 0x701f
+#define USB_PID_PCTV_200E 0x020e
+#define USB_PID_PCTV_400E 0x020f
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 65f0c095abc9..a902059812a2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -128,7 +128,9 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device
/*
* USB
*/
-int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner)
+
+int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties
+ *props, struct module *owner,struct dvb_usb_device **du)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct dvb_usb_device *d = NULL;
@@ -170,6 +172,9 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *p
usb_set_intfdata(intf, d);
+ if (du != NULL)
+ *du = d;
+
ret = dvb_usb_init(d);
}
@@ -196,19 +201,6 @@ void dvb_usb_device_exit(struct usb_interface *intf)
}
EXPORT_SYMBOL(dvb_usb_device_exit);
-/* module stuff */
-static int __init dvb_usb_module_init(void)
-{
- return 0;
-}
-
-static void __exit dvb_usb_module_exit(void)
-{
-}
-
-module_init (dvb_usb_module_init);
-module_exit (dvb_usb_module_exit);
-
MODULE_VERSION("0.3");
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index fc7800f1743e..e5c6d9835e06 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -39,9 +39,9 @@ static void dvb_usb_read_remote_control(void *data)
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n");
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, event, 1);
+ input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+ input_sync(d->rc_input_dev);
break;
default:
break;
@@ -53,8 +53,8 @@ static void dvb_usb_read_remote_control(void *data)
deb_rc("NO KEY PRESSED\n");
if (d->last_state != REMOTE_NO_KEY_PRESSED) {
deb_rc("releasing event %d\n",d->last_event);
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+ input_sync(d->rc_input_dev);
}
d->last_state = REMOTE_NO_KEY_PRESSED;
d->last_event = 0;
@@ -63,8 +63,8 @@ static void dvb_usb_read_remote_control(void *data)
deb_rc("KEY PRESSED\n");
deb_rc("pressing event %d\n",event);
- input_event(&d->rc_input_dev, EV_KEY, event, 1);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, event, 1);
+ input_sync(d->rc_input_dev);
d->last_event = event;
d->last_state = REMOTE_KEY_PRESSED;
@@ -73,8 +73,8 @@ static void dvb_usb_read_remote_control(void *data)
deb_rc("KEY_REPEAT\n");
if (d->last_state != REMOTE_NO_KEY_PRESSED) {
deb_rc("repeating event %d\n",d->last_event);
- input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
- input_sync(&d->rc_input_dev);
+ input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
+ input_sync(d->rc_input_dev);
d->last_state = REMOTE_KEY_REPEAT;
}
default:
@@ -89,24 +89,30 @@ schedule:
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
int i;
+
if (d->props.rc_key_map == NULL ||
d->props.rc_query == NULL ||
dvb_usb_disable_rc_polling)
return 0;
- /* Initialise the remote-control structures.*/
- init_input_dev(&d->rc_input_dev);
+ usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+ strlcpy(d->rc_phys, "/ir0", sizeof(d->rc_phys));
+
+ d->rc_input_dev = input_allocate_device();
+ if (!d->rc_input_dev)
+ return -ENOMEM;
- d->rc_input_dev.evbit[0] = BIT(EV_KEY);
- d->rc_input_dev.keycodesize = sizeof(unsigned char);
- d->rc_input_dev.keycodemax = KEY_MAX;
- d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
+ d->rc_input_dev->evbit[0] = BIT(EV_KEY);
+ d->rc_input_dev->keycodesize = sizeof(unsigned char);
+ d->rc_input_dev->keycodemax = KEY_MAX;
+ d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
+ d->rc_input_dev->phys = d->rc_phys;
/* set the bits for the keys */
- deb_rc("key map size: %d\n",d->props.rc_key_map_size);
+ deb_rc("key map size: %d\n", d->props.rc_key_map_size);
for (i = 0; i < d->props.rc_key_map_size; i++) {
deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
- set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
+ set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
}
/* Start the remote-control polling. */
@@ -114,14 +120,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
d->props.rc_interval = 100; /* default */
/* setting these two values to non-zero, we have to manage key repeats */
- d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
- d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150;
+ d->rc_input_dev->rep[REP_PERIOD] = d->props.rc_interval;
+ d->rc_input_dev->rep[REP_DELAY] = d->props.rc_interval + 150;
- input_register_device(&d->rc_input_dev);
+ input_register_device(d->rc_input_dev);
INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
- info("schedule remote query interval to %d msecs.",d->props.rc_interval);
+ info("schedule remote query interval to %d msecs.", d->props.rc_interval);
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
d->state |= DVB_USB_STATE_REMOTE;
@@ -134,7 +140,7 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
if (d->state & DVB_USB_STATE_REMOTE) {
cancel_delayed_work(&d->rc_query_work);
flush_scheduled_work();
- input_unregister_device(&d->rc_input_dev);
+ input_unregister_device(d->rc_input_dev);
}
d->state &= ~DVB_USB_STATE_REMOTE;
return 0;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index a80567caf508..b4a1a98006c7 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -127,7 +127,7 @@ struct dvb_usb_device;
* helper functions.
*
* @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
- * Currently only BULK is implemented
+ * (BULK or ISOC)
*
* @num_device_descs: number of struct dvb_usb_device_description in @devices
* @devices: array of struct dvb_usb_device_description compatibles with these
@@ -300,7 +300,8 @@ struct dvb_usb_device {
int (*fe_init) (struct dvb_frontend *);
/* remote control */
- struct input_dev rc_input_dev;
+ struct input_dev *rc_input_dev;
+ char rc_phys[64];
struct work_struct rc_query_work;
u32 last_event;
int last_state;
@@ -310,7 +311,7 @@ struct dvb_usb_device {
void *priv;
};
-extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *);
+extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *, struct dvb_usb_device **);
extern void dvb_usb_device_exit(struct usb_interface *);
/* the generic read/write method for device control */
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 258a92bfbcc7..1841a66427bf 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -144,7 +144,7 @@ static struct dvb_usb_properties nova_t_properties;
static int nova_t_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE,NULL);
}
/* do not change the order of the ID table */
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 2112ac3cf5e2..6fd67657c269 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -77,7 +77,7 @@ static struct dvb_usb_properties umt_properties;
static int umt_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0)
+ if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE,NULL) == 0)
return 0;
return -EINVAL;
}
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
new file mode 100644
index 000000000000..f20d8dbd0be8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -0,0 +1,339 @@
+/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0
+ * DVB-S receiver.
+ *
+ * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
+ * Metzler Brothers Systementwicklung GbR
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * This file can be removed soon, after the DST-driver is rewritten to provice
+ * the frontend-controlling separately.
+ *
+ * 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+#include "vp702x.h"
+
+struct vp702x_fe_state {
+ struct dvb_frontend fe;
+ struct dvb_usb_device *d;
+
+ fe_sec_voltage_t voltage;
+ fe_sec_tone_mode_t tone_mode;
+
+ u8 lnb_buf[8];
+
+ u8 lock;
+ u8 sig;
+ u8 snr;
+
+ unsigned long next_status_check;
+ unsigned long status_check_interval;
+};
+
+static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
+{
+ u8 buf[10];
+ if (time_after(jiffies,st->next_status_check)) {
+ vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10);
+
+ st->lock = buf[4];
+ vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1);
+ vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1);
+
+ st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+ }
+ return 0;
+}
+
+static u8 vp702x_chksum(u8 *buf,int f, int count)
+{
+ u8 s = 0;
+ int i;
+ for (i = f; i < f+count; i++)
+ s += buf[i];
+ return ~s+1;
+}
+
+static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+ deb_fe("%s\n",__FUNCTION__);
+
+ if (st->lock == 0)
+ *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
+ else
+ *status = 0;
+
+ deb_fe("real state: %x\n",*status);
+ *status = 0x1f;
+
+ if (*status & FE_HAS_LOCK)
+ st->status_check_interval = 1000;
+ else
+ st->status_check_interval = 250;
+ return 0;
+}
+
+/* not supported by this Frontend */
+static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+ *ber = 0;
+ return 0;
+}
+
+/* not supported by this Frontend */
+static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+ *unc = 0;
+ return 0;
+}
+
+static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+
+ *strength = (st->sig << 8) | st->sig;
+ return 0;
+}
+
+static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+ u8 _snr;
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ vp702x_fe_refresh_state(st);
+
+ _snr = (st->snr & 0x1f) * 0xff / 0x1f;
+ *snr = (_snr << 8) | _snr;
+ return 0;
+}
+
+static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+ deb_fe("%s\n",__FUNCTION__);
+ tune->min_delay_ms = 2000;
+ return 0;
+}
+
+static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u32 freq = fep->frequency/1000;
+ /*CalFrequency*/
+/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
+ u64 sr;
+ u8 cmd[8] = { 0 },ibuf[10];
+
+ cmd[0] = (freq >> 8) & 0x7f;
+ cmd[1] = freq & 0xff;
+ cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */
+
+ sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20;
+ do_div(sr,88000);
+ cmd[3] = (sr >> 12) & 0xff;
+ cmd[4] = (sr >> 4) & 0xff;
+ cmd[5] = (sr << 4) & 0xf0;
+
+ deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %Lu (%Lx)\n",
+ fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, sr, sr);
+
+/* if (fep->inversion == INVERSION_ON)
+ cmd[6] |= 0x80; */
+
+ if (st->voltage == SEC_VOLTAGE_18)
+ cmd[6] |= 0x40;
+
+/* if (fep->u.qpsk.symbol_rate > 8000000)
+ cmd[6] |= 0x20;
+
+ if (fep->frequency < 1531000)
+ cmd[6] |= 0x04;
+
+ if (st->tone_mode == SEC_TONE_ON)
+ cmd[6] |= 0x01;*/
+
+ cmd[7] = vp702x_chksum(cmd,0,7);
+
+ st->status_check_interval = 250;
+ st->next_status_check = jiffies;
+
+ vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
+ msleep(30);
+ vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("tuning failed.\n");
+ else
+ deb_fe("tuning succeeded.\n");
+
+ return 0;
+}
+
+static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ deb_fe("%s\n",__FUNCTION__);
+ return 0;
+}
+
+static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
+ struct dvb_diseqc_master_cmd *m)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 cmd[8],ibuf[10];
+ memset(cmd,0,8);
+
+ deb_fe("%s\n",__FUNCTION__);
+
+ if (m->msg_len > 4)
+ return -EINVAL;
+
+ cmd[1] = SET_DISEQC_CMD;
+ cmd[2] = m->msg_len;
+ memcpy(&cmd[3], m->msg, m->msg_len);
+ cmd[7] = vp702x_chksum(cmd,0,7);
+
+ vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("diseqc cmd failed.\n");
+ else
+ deb_fe("diseqc cmd succeeded.\n");
+
+ return 0;
+}
+
+static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+ deb_fe("%s\n",__FUNCTION__);
+ return 0;
+}
+
+static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 ibuf[10];
+ deb_fe("%s\n",__FUNCTION__);
+
+ st->tone_mode = tone;
+
+ if (tone == SEC_TONE_ON)
+ st->lnb_buf[2] = 0x02;
+ else
+ st->lnb_buf[2] = 0x00;
+
+ st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
+
+ vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("set_tone cmd failed.\n");
+ else
+ deb_fe("set_tone cmd succeeded.\n");
+
+ return 0;
+}
+
+static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
+ voltage)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 ibuf[10];
+ deb_fe("%s\n",__FUNCTION__);
+
+ st->voltage = voltage;
+
+ if (voltage != SEC_VOLTAGE_OFF)
+ st->lnb_buf[4] = 0x01;
+ else
+ st->lnb_buf[4] = 0x00;
+
+ st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
+
+ vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("set_voltage cmd failed.\n");
+ else
+ deb_fe("set_voltage cmd succeeded.\n");
+
+ return 0;
+}
+
+static void vp702x_fe_release(struct dvb_frontend* fe)
+{
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ kfree(st);
+}
+
+static struct dvb_frontend_ops vp702x_fe_ops;
+
+struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
+{
+ struct vp702x_fe_state *s = kmalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
+ if (s == NULL)
+ goto error;
+ memset(s,0,sizeof(struct vp702x_fe_state));
+
+ s->d = d;
+ s->fe.ops = &vp702x_fe_ops;
+ s->fe.demodulator_priv = s;
+
+ s->lnb_buf[1] = SET_LNB_POWER;
+ s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
+
+ goto success;
+error:
+ return NULL;
+success:
+ return &s->fe;
+}
+
+
+static struct dvb_frontend_ops vp702x_fe_ops = {
+ .info = {
+ .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 1000, /* kHz for QPSK frontends */
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = 500, /* ppm */
+ .caps = 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_QPSK |
+ FE_CAN_FEC_AUTO
+ },
+ .release = vp702x_fe_release,
+
+ .init = NULL,
+ .sleep = NULL,
+
+ .set_frontend = vp702x_fe_set_frontend,
+ .get_frontend = vp702x_fe_get_frontend,
+ .get_tune_settings = vp702x_fe_get_tune_settings,
+
+ .read_status = vp702x_fe_read_status,
+ .read_ber = vp702x_fe_read_ber,
+ .read_signal_strength = vp702x_fe_read_signal_strength,
+ .read_snr = vp702x_fe_read_snr,
+ .read_ucblocks = vp702x_fe_read_unc_blocks,
+
+ .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
+ .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
+ .set_tone = vp702x_fe_set_tone,
+ .set_voltage = vp702x_fe_set_voltage,
+};
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
new file mode 100644
index 000000000000..de13c04e8e64
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -0,0 +1,290 @@
+/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S
+ * receiver.
+ *
+ * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
+ * Metzler Brothers Systementwicklung GbR
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * 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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "vp702x.h"
+
+/* debug */
+int dvb_usb_vp702x_debug;
+module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+struct vp702x_state {
+ u8 pid_table[17]; /* [16] controls the pid_table state */
+};
+
+/* check for mutex FIXME */
+int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+ int ret = 0,try = 0;
+
+ while (ret >= 0 && ret != blen && try < 3) {
+ ret = usb_control_msg(d->udev,
+ usb_rcvctrlpipe(d->udev,0),
+ req,
+ USB_TYPE_VENDOR | USB_DIR_IN,
+ value,index,b,blen,
+ 2000);
+ deb_info("reading number %d (ret: %d)\n",try,ret);
+ try++;
+ }
+
+ if (ret < 0 || ret != blen) {
+ warn("usb in operation failed.");
+ ret = -EIO;
+ } else
+ ret = 0;
+
+ deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+ debug_dump(b,blen,deb_xfer);
+
+ return ret;
+}
+
+int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+ deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+ debug_dump(b,blen,deb_xfer);
+
+ if (usb_control_msg(d->udev,
+ usb_sndctrlpipe(d->udev,0),
+ req,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ value,index,b,blen,
+ 2000) != blen) {
+ warn("usb out operation failed.");
+ return -EIO;
+ } else
+ return 0;
+}
+
+int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
+{
+ int ret;
+
+ if ((ret = down_interruptible(&d->usb_sem)))
+ return ret;
+
+ if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0)
+ goto unlock;
+ msleep(msec);
+ ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
+
+unlock:
+ up(&d->usb_sem);
+
+ return ret;
+}
+
+int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec)
+{
+ u8 bout[olen+2];
+ u8 bin[ilen+1];
+ int ret = 0;
+
+ bout[0] = 0x00;
+ bout[1] = cmd;
+ memcpy(&bout[2],o,olen);
+
+ ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec);
+
+ if (ret == 0)
+ memcpy(i,&bin[1],ilen);
+
+ return ret;
+}
+
+static int vp702x_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+{
+ struct vp702x_state *st = d->priv;
+ u8 buf[9];
+
+ if (onoff) {
+ st->pid_table[16] |= 1 << index;
+ st->pid_table[index*2] = (pid >> 8) & 0xff;
+ st->pid_table[index*2+1] = pid & 0xff;
+ } else {
+ st->pid_table[16] &= ~(1 << index);
+ st->pid_table[index*2] = st->pid_table[index*2+1] = 0;
+ }
+
+ return vp702x_usb_inout_cmd(d,SET_PID_FILTER,st->pid_table,17,buf,9,10);
+}
+
+static int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ vp702x_usb_in_op(d,RESET_TUNER,0,0,NULL,0);
+
+ vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
+ return vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0);
+}
+
+/* keys for the enclosed remote control */
+static struct dvb_usb_rc_key vp702x_rc_keys[] = {
+ { 0x00, 0x01, KEY_1 },
+ { 0x00, 0x02, KEY_2 },
+};
+
+/* remote control stuff (does not work with my box) */
+static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[10];
+ int i;
+
+/* remove the following return to enabled remote querying */
+ return 0;
+
+ vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
+
+ deb_rc("remote query key: %x %d\n",key[1],key[1]);
+
+ if (key[1] == 0x44) {
+ *state = REMOTE_NO_KEY_PRESSED;
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++)
+ if (vp702x_rc_keys[i].custom == key[1]) {
+ *state = REMOTE_KEY_PRESSED;
+ *event = vp702x_rc_keys[i].event;
+ break;
+ }
+ return 0;
+}
+
+static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
+{
+ u8 macb[9];
+ if (vp702x_usb_inout_cmd(d, GET_MAC_ADDRESS, NULL, 0, macb, 9, 10))
+ return -EIO;
+ memcpy(mac,&macb[3],6);
+ return 0;
+}
+
+static int vp702x_frontend_attach(struct dvb_usb_device *d)
+{
+ u8 buf[9] = { 0 };
+
+ if (vp702x_usb_inout_cmd(d, GET_SYSTEM_STRING, NULL, 0, buf, 9, 10))
+ return -EIO;
+
+ buf[8] = '\0';
+ info("system string: %s",&buf[1]);
+
+ d->fe = vp702x_fe_attach(d);
+ return 0;
+}
+
+static struct dvb_usb_properties vp702x_properties;
+
+static int vp702x_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+
+ usb_clear_halt(udev,usb_sndctrlpipe(udev,0));
+ usb_clear_halt(udev,usb_rcvctrlpipe(udev,0));
+
+ return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL);
+}
+
+static struct usb_device_id vp702x_usb_table [] = {
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_WARM) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
+ { 0 },
+};
+MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
+
+static struct dvb_usb_properties vp702x_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+ .pid_filter_count = 8, /* !!! */
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-vp702x-01.fw",
+
+ .pid_filter = vp702x_pid_filter,
+ .power_ctrl = vp702x_power_ctrl,
+ .frontend_attach = vp702x_frontend_attach,
+ .read_mac_address = vp702x_read_mac_addr,
+
+ .rc_key_map = vp702x_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(vp702x_rc_keys),
+ .rc_interval = 400,
+ .rc_query = vp702x_rc_query,
+
+ .size_of_priv = sizeof(struct vp702x_state),
+
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
+ .cold_ids = { &vp702x_usb_table[0], NULL },
+ .warm_ids = { &vp702x_usb_table[1], NULL },
+ },
+ { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
+ .cold_ids = { &vp702x_usb_table[2], NULL },
+ .warm_ids = { &vp702x_usb_table[3], NULL },
+ },
+ { 0 },
+ }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver vp702x_usb_driver = {
+ .owner = THIS_MODULE,
+ .name = "dvb-usb-vp702x",
+ .probe = vp702x_usb_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = vp702x_usb_table,
+};
+
+/* module stuff */
+static int __init vp702x_usb_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&vp702x_usb_driver))) {
+ err("usb_register failed. (%d)",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit vp702x_usb_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&vp702x_usb_driver);
+}
+
+module_init(vp702x_usb_module_init);
+module_exit(vp702x_usb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
+MODULE_VERSION("1.0-alpha");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
new file mode 100644
index 000000000000..4a3e8c7eca2b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -0,0 +1,109 @@
+#ifndef _DVB_USB_VP7021_H_
+#define _DVB_USB_VP7021_H_
+
+#define DVB_USB_LOG_PREFIX "vp702x"
+#include "dvb-usb.h"
+
+extern int dvb_usb_vp702x_debug;
+#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args)
+#define deb_rc(args...) dprintk(dvb_usb_vp702x_debug,0x04,args)
+#define deb_fe(args...) dprintk(dvb_usb_vp702x_debug,0x08,args)
+
+/* commands are read and written with USB control messages */
+
+/* consecutive read/write operation */
+#define REQUEST_OUT 0xB2
+#define REQUEST_IN 0xB3
+
+/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
+ * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
+ * the returning buffer looks as follows
+ * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
+
+#define GET_TUNER_STATUS 0x05
+/* additional in buffer:
+ * 0 1 2 3 4 5 6 7 8
+ * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
+
+#define GET_SYSTEM_STRING 0x06
+/* additional in buffer:
+ * 0 1 2 3 4 5 6 7 8
+ * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
+
+#define SET_DISEQC_CMD 0x08
+/* additional out buffer:
+ * 0 1 2 3 4
+ * len X1 X2 X3 X4
+ * additional in buffer:
+ * 0 1 2
+ * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */
+
+#define SET_LNB_POWER 0x09
+/* additional out buffer:
+ * 0 1 2
+ * 0x00 0xff 1 = on, 0 = off
+ * additional in buffer:
+ * 0 1 2
+ * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */
+
+#define GET_MAC_ADDRESS 0x0A
+/* #define GET_MAC_ADDRESS 0x0B */
+/* additional in buffer:
+ * 0 1 2 3 4 5 6 7 8
+ * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
+
+#define SET_PID_FILTER 0x11
+/* additional in buffer:
+ * 0 1 ... 14 15 16
+ * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
+
+/* request: 0xB2; i: 0; v: 0;
+ * b[0] != 0 -> tune and lock a channel
+ * 0 1 2 3 4 5 6 7
+ * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
+ */
+
+
+/* one direction requests */
+#define READ_REMOTE_REQ 0xB4
+/* IN i: 0; v: 0; b[0] == request, b[1] == key */
+
+#define READ_PID_NUMBER_REQ 0xB5
+/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
+
+#define WRITE_EEPROM_REQ 0xB6
+/* OUT i: offset; v: value to write; no extra buffer */
+
+#define READ_EEPROM_REQ 0xB7
+/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */
+
+#define READ_STATUS 0xB8
+/* IN i: 0; v: 0; bufferlen 10 */
+
+#define READ_TUNER_REG_REQ 0xB9
+/* IN i: 0; v: register; b[0] = value */
+
+#define READ_FX2_REG_REQ 0xBA
+/* IN i: offset; v: 0; b[0] = value */
+
+#define WRITE_FX2_REG_REQ 0xBB
+/* OUT i: offset; v: value to write; 1 byte extra buffer */
+
+#define SET_TUNER_POWER_REQ 0xBC
+/* IN i: 0 = power off, 1 = power on */
+
+#define WRITE_TUNER_REG_REQ 0xBD
+/* IN i: register, v: value to write, no extra buffer */
+
+#define RESET_TUNER 0xBE
+/* IN i: 0, v: 0, no extra buffer */
+
+extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
+
+extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
+extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec);
+extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 9ac95f54f9fc..75765e3a569c 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -164,7 +164,6 @@ static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int off
return 0;
}
-
static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
{
return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
@@ -199,7 +198,7 @@ static struct dvb_usb_properties vp7045_properties;
static int vp7045_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE);
+ return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE,NULL);
}
static struct usb_device_id vp7045_usb_table [] = {
@@ -248,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = {
.cold_ids = { &vp7045_usb_table[2], NULL },
.warm_ids = { &vp7045_usb_table[3], NULL },
},
- { 0 },
+ { NULL },
}
};
@@ -256,9 +255,9 @@ static struct dvb_usb_properties vp7045_properties = {
static struct usb_driver vp7045_usb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_vp7045",
- .probe = vp7045_usb_probe,
+ .probe = vp7045_usb_probe,
.disconnect = dvb_usb_device_exit,
- .id_table = vp7045_usb_table,
+ .id_table = vp7045_usb_table,
};
/* module stuff */
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index e83256d0fd14..a50a41f6f79d 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -188,7 +188,7 @@ config DVB_BCM3510
support this frontend.
config DVB_LGDT330X
- tristate "LGDT3302 or LGDT3303 based (DViCO FusionHDTV Gold)"
+ tristate "LG Electronics LGDT3302/LGDT3303 based"
depends on DVB_CORE
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index f5fdc5c3e605..f6d4ee78bdd4 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -36,6 +36,9 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "bcm3510.h"
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 8222b88cb486..d4b97989e3ed 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -1,7 +1,7 @@
/*
cx24110 - Single Chip Satellite Channel Receiver driver module
- Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
+ Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
work
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
@@ -387,8 +387,9 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
{
- int rv, bit, i;
+ int rv, bit;
struct cx24110_state *state = fe->demodulator_priv;
+ unsigned long timeout;
if (burst == SEC_MINI_A)
bit = 0x00;
@@ -398,12 +399,14 @@ static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
return -EINVAL;
rv = cx24110_readreg(state, 0x77);
- cx24110_writereg(state, 0x77, rv|0x04);
+ if (!(rv & 0x04))
+ cx24110_writereg(state, 0x77, rv | 0x04);
rv = cx24110_readreg(state, 0x76);
cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
- for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
- ; /* wait for LNB ready */
+ timeout = jiffies + msecs_to_jiffies(100);
+ while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
+ ; /* wait for LNB ready */
return 0;
}
@@ -413,17 +416,22 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
{
int i, rv;
struct cx24110_state *state = fe->demodulator_priv;
+ unsigned long timeout;
for (i = 0; i < cmd->msg_len; i++)
cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
rv = cx24110_readreg(state, 0x77);
- cx24110_writereg(state, 0x77, rv|0x04);
+ if (rv & 0x04) {
+ cx24110_writereg(state, 0x77, rv & ~0x04);
+ msleep(30); /* reportedly fixes switching problems */
+ }
rv = cx24110_readreg(state, 0x76);
cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
- for (i=500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40);)
+ timeout = jiffies + msecs_to_jiffies(100);
+ while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
; /* wait for LNB ready */
return 0;
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index 6b663f4744e0..b63ecf26421a 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -1,7 +1,7 @@
/*
cx24110 - Single Chip Satellite Channel Receiver driver module
- Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
+ Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
work
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index cd434b7cf9db..6b0553608610 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -23,11 +23,12 @@
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dib3000-common.h"
#include "dib3000mb_priv.h"
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index cd33705a4320..c024fad17337 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -22,11 +22,12 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dib3000-common.h"
#include "dib3000mc_priv.h"
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 5264310c070e..536c35d969b7 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -225,6 +225,22 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
};
EXPORT_SYMBOL(dvb_pll_tua6034);
+/* Infineon TUA6034
+ * used in LG Innotek TDVS-H062F
+ */
+struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
+ .name = "LG/Infineon TUA6034",
+ .min = 54000000,
+ .max = 863000000,
+ .count = 3,
+ .entries = {
+ { 160000000, 44000000, 62500, 0xce, 0x01 },
+ { 455000000, 44000000, 62500, 0xce, 0x02 },
+ { 999999999, 44000000, 62500, 0xce, 0x04 },
+ },
+};
+EXPORT_SYMBOL(dvb_pll_tdvs_tua6034);
+
/* Philips FMD1216ME
* used in Medion Hybrid PCMCIA card and USB Box
*/
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index cb794759d89e..205b2d1a8852 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -31,6 +31,7 @@ extern struct dvb_pll_desc dvb_pll_unknown_1;
extern struct dvb_pll_desc dvb_pll_tua6010xs;
extern struct dvb_pll_desc dvb_pll_env57h1xd5;
extern struct dvb_pll_desc dvb_pll_tua6034;
+extern struct dvb_pll_desc dvb_pll_tdvs_tua6034;
extern struct dvb_pll_desc dvb_pll_tda665x;
extern struct dvb_pll_desc dvb_pll_fmd1216me;
extern struct dvb_pll_desc dvb_pll_tded4;
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index cff93b9d8ab2..794be520d590 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -22,6 +22,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "dvb_dummy_fe.h"
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index e94dee50eecd..8dde72bd1046 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -1,11 +1,8 @@
/*
- * Support for LGDT3302 & LGDT3303 (DViCO FusionHDTV Gold) - VSB/QAM
+ * Support for LGDT3302 and LGDT3303 - VSB/QAM
*
* Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
*
- * Based on code from Kirk Lapray <kirk_lapray@bigfoot.com>
- * Copyright (C) 2005
- *
* 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
@@ -25,11 +22,13 @@
/*
* NOTES ABOUT THIS DRIVER
*
- * This driver supports DViCO FusionHDTV Gold under Linux.
+ * This Linux driver supports:
+ * DViCO FusionHDTV 3 Gold-Q
+ * DViCO FusionHDTV 3 Gold-T
+ * DViCO FusionHDTV 5 Gold
*
* TODO:
- * BER and signal strength always return 0.
- * Include support for LGDT3303
+ * signal strength always returns 0.
*
*/
@@ -38,10 +37,11 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
-#include "dvb-pll.h"
#include "lgdt330x_priv.h"
#include "lgdt330x.h"
@@ -70,55 +70,37 @@ struct lgdt330x_state
u32 current_frequency;
};
-static int i2c_writebytes (struct lgdt330x_state* state,
- u8 addr, /* demod_address or pll_address */
- u8 *buf, /* data bytes to send */
- int len /* number of bytes to send */ )
+static int i2c_write_demod_bytes (struct lgdt330x_state* state,
+ u8 *buf, /* data bytes to send */
+ int len /* number of bytes to send */ )
{
- u8 tmp[] = { buf[0], buf[1] };
struct i2c_msg msg =
- { .addr = addr, .flags = 0, .buf = tmp, .len = 2 };
- int err;
+ { .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf,
+ .len = 2 };
int i;
+ int err;
- for (i=1; i<len; i++) {
- tmp[1] = buf[i];
+ for (i=0; i<len-1; i+=2){
if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
- printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
+ printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
if (err < 0)
return err;
else
return -EREMOTEIO;
}
- tmp[0]++;
+ msg.buf += 2;
}
return 0;
}
-#if 0
-static int i2c_readbytes (struct lgdt330x_state* state,
- u8 addr, /* demod_address or pll_address */
- u8 *buf, /* holds data bytes read */
- int len /* number of bytes to read */ )
-{
- struct i2c_msg msg =
- { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
- int err;
-
- if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
- printk(KERN_WARNING "lgdt330x: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err);
- return -EREMOTEIO;
- }
- return 0;
-}
-#endif
-
/*
* This routine writes the register (reg) to the demod bus
* then reads the data returned for (len) bytes.
*/
-static u8 i2c_selectreadbytes (struct lgdt330x_state* state,
+static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
enum I2C_REG reg, u8* buf, int len)
{
u8 wr [] = { reg };
@@ -139,7 +121,7 @@ static u8 i2c_selectreadbytes (struct lgdt330x_state* state,
}
/* Software reset */
-int lgdt330x_SwReset(struct lgdt330x_state* state)
+static int lgdt3302_SwReset(struct lgdt330x_state* state)
{
u8 ret;
u8 reset[] = {
@@ -148,23 +130,50 @@ int lgdt330x_SwReset(struct lgdt330x_state* state)
* bits 5-0 are 1 to mask interrupts */
};
- ret = i2c_writebytes(state,
- state->config->demod_address,
- reset, sizeof(reset));
+ ret = i2c_write_demod_bytes(state,
+ reset, sizeof(reset));
if (ret == 0) {
- /* spec says reset takes 100 ns why wait */
- /* mdelay(100); */ /* keep low for 100mS */
- reset[1] = 0x7f; /* force reset high (inactive)
- * and unmask interrupts */
- ret = i2c_writebytes(state,
- state->config->demod_address,
- reset, sizeof(reset));
+
+ /* force reset high (inactive) and unmask interrupts */
+ reset[1] = 0x7f;
+ ret = i2c_write_demod_bytes(state,
+ reset, sizeof(reset));
+ }
+ return ret;
+}
+
+static int lgdt3303_SwReset(struct lgdt330x_state* state)
+{
+ u8 ret;
+ u8 reset[] = {
+ 0x02,
+ 0x00 /* bit 0 is active low software reset */
+ };
+
+ ret = i2c_write_demod_bytes(state,
+ reset, sizeof(reset));
+ if (ret == 0) {
+
+ /* force reset high (inactive) */
+ reset[1] = 0x01;
+ ret = i2c_write_demod_bytes(state,
+ reset, sizeof(reset));
}
- /* Spec does not indicate a need for this either */
- /*mdelay(5); */ /* wait 5 msec before doing more */
return ret;
}
+static int lgdt330x_SwReset(struct lgdt330x_state* state)
+{
+ switch (state->config->demod_chip) {
+ case LGDT3302:
+ return lgdt3302_SwReset(state);
+ case LGDT3303:
+ return lgdt3303_SwReset(state);
+ default:
+ return -ENODEV;
+ }
+}
+
static int lgdt330x_init(struct dvb_frontend* fe)
{
/* Hardware reset is done using gpio[0] of cx23880x chip.
@@ -173,22 +182,98 @@ static int lgdt330x_init(struct dvb_frontend* fe)
* Maybe there needs to be a callable function in cx88-core or
* the caller of this function needs to do it. */
- dprintk("%s entered\n", __FUNCTION__);
- return lgdt330x_SwReset((struct lgdt330x_state*) fe->demodulator_priv);
+ /*
+ * Array of byte pairs <address, value>
+ * to initialize each different chip
+ */
+ static u8 lgdt3302_init_data[] = {
+ /* Use 50MHz parameter values from spec sheet since xtal is 50 */
+ /* Change the value of NCOCTFV[25:0] of carrier
+ recovery center frequency register */
+ VSB_CARRIER_FREQ0, 0x00,
+ VSB_CARRIER_FREQ1, 0x87,
+ VSB_CARRIER_FREQ2, 0x8e,
+ VSB_CARRIER_FREQ3, 0x01,
+ /* Change the TPCLK pin polarity
+ data is valid on falling clock */
+ DEMUX_CONTROL, 0xfb,
+ /* Change the value of IFBW[11:0] of
+ AGC IF/RF loop filter bandwidth register */
+ AGC_RF_BANDWIDTH0, 0x40,
+ AGC_RF_BANDWIDTH1, 0x93,
+ AGC_RF_BANDWIDTH2, 0x00,
+ /* Change the value of bit 6, 'nINAGCBY' and
+ 'NSSEL[1:0] of ACG function control register 2 */
+ AGC_FUNC_CTRL2, 0xc6,
+ /* Change the value of bit 6 'RFFIX'
+ of AGC function control register 3 */
+ AGC_FUNC_CTRL3, 0x40,
+ /* Set the value of 'INLVTHD' register 0x2a/0x2c
+ to 0x7fe */
+ AGC_DELAY0, 0x07,
+ AGC_DELAY2, 0xfe,
+ /* Change the value of IAGCBW[15:8]
+ of inner AGC loop filter bandwith */
+ AGC_LOOP_BANDWIDTH0, 0x08,
+ AGC_LOOP_BANDWIDTH1, 0x9a
+ };
+
+ static u8 lgdt3303_init_data[] = {
+ 0x4c, 0x14
+ };
+
+ struct lgdt330x_state* state = fe->demodulator_priv;
+ char *chip_name;
+ int err;
+
+ switch (state->config->demod_chip) {
+ case LGDT3302:
+ chip_name = "LGDT3302";
+ err = i2c_write_demod_bytes(state, lgdt3302_init_data,
+ sizeof(lgdt3302_init_data));
+ break;
+ case LGDT3303:
+ chip_name = "LGDT3303";
+ err = i2c_write_demod_bytes(state, lgdt3303_init_data,
+ sizeof(lgdt3303_init_data));
+ break;
+ default:
+ chip_name = "undefined";
+ printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
+ err = -ENODEV;
+ }
+ dprintk("%s entered as %s\n", __FUNCTION__, chip_name);
+ if (err < 0)
+ return err;
+ return lgdt330x_SwReset(state);
}
static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
{
- *ber = 0; /* Dummy out for now */
+ *ber = 0; /* Not supplied by the demod chips */
return 0;
}
static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
- struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+ struct lgdt330x_state* state = fe->demodulator_priv;
+ int err;
u8 buf[2];
- i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf));
+ switch (state->config->demod_chip) {
+ case LGDT3302:
+ err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
+ buf, sizeof(buf));
+ break;
+ case LGDT3303:
+ err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
+ buf, sizeof(buf));
+ break;
+ default:
+ printk(KERN_WARNING
+ "Only LGDT3302 and LGDT3303 are supported chips.\n");
+ err = -ENODEV;
+ }
*ucblocks = (buf[0] << 8) | buf[1];
return 0;
@@ -197,125 +282,116 @@ static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
static int lgdt330x_set_parameters(struct dvb_frontend* fe,
struct dvb_frontend_parameters *param)
{
- struct lgdt330x_state* state =
- (struct lgdt330x_state*) fe->demodulator_priv;
+ /*
+ * Array of byte pairs <address, value>
+ * to initialize 8VSB for lgdt3303 chip 50 MHz IF
+ */
+ static u8 lgdt3303_8vsb_44_data[] = {
+ 0x04, 0x00,
+ 0x0d, 0x40,
+ 0x0e, 0x87,
+ 0x0f, 0x8e,
+ 0x10, 0x01,
+ 0x47, 0x8b };
+
+ /*
+ * Array of byte pairs <address, value>
+ * to initialize QAM for lgdt3303 chip
+ */
+ static u8 lgdt3303_qam_data[] = {
+ 0x04, 0x00,
+ 0x0d, 0x00,
+ 0x0e, 0x00,
+ 0x0f, 0x00,
+ 0x10, 0x00,
+ 0x51, 0x63,
+ 0x47, 0x66,
+ 0x48, 0x66,
+ 0x4d, 0x1a,
+ 0x49, 0x08,
+ 0x4a, 0x9b };
+
+ struct lgdt330x_state* state = fe->demodulator_priv;
- /* Use 50MHz parameter values from spec sheet since xtal is 50 */
static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
- static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 };
- static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
- static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
- static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
- static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x07, 0x00, 0xfe };
- static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
+ int err;
/* Change only if we are actually changing the modulation */
if (state->current_modulation != param->u.vsb.modulation) {
switch(param->u.vsb.modulation) {
case VSB_8:
dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
- /* Select VSB mode and serial MPEG interface */
- top_ctrl_cfg[1] = 0x07;
+ /* Select VSB mode */
+ top_ctrl_cfg[1] = 0x03;
/* Select ANT connector if supported by card */
if (state->config->pll_rf_set)
state->config->pll_rf_set(fe, 1);
+
+ if (state->config->demod_chip == LGDT3303) {
+ err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
+ sizeof(lgdt3303_8vsb_44_data));
+ }
break;
case QAM_64:
dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
- /* Select QAM_64 mode and serial MPEG interface */
- top_ctrl_cfg[1] = 0x04;
+ /* Select QAM_64 mode */
+ top_ctrl_cfg[1] = 0x00;
/* Select CABLE connector if supported by card */
if (state->config->pll_rf_set)
state->config->pll_rf_set(fe, 0);
+
+ if (state->config->demod_chip == LGDT3303) {
+ err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
+ sizeof(lgdt3303_qam_data));
+ }
break;
case QAM_256:
dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
- /* Select QAM_256 mode and serial MPEG interface */
- top_ctrl_cfg[1] = 0x05;
+ /* Select QAM_256 mode */
+ top_ctrl_cfg[1] = 0x01;
/* Select CABLE connector if supported by card */
if (state->config->pll_rf_set)
state->config->pll_rf_set(fe, 0);
+
+ if (state->config->demod_chip == LGDT3303) {
+ err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
+ sizeof(lgdt3303_qam_data));
+ }
break;
default:
printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
return -1;
}
- /* Initializations common to all modes */
+ /*
+ * select serial or parallel MPEG harware interface
+ * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303
+ * Parallel: 0x00
+ */
+ top_ctrl_cfg[1] |= state->config->serial_mpeg;
/* Select the requested mode */
- i2c_writebytes(state, state->config->demod_address,
- top_ctrl_cfg, sizeof(top_ctrl_cfg));
-
- /* Change the value of IFBW[11:0]
- of AGC IF/RF loop filter bandwidth register */
- i2c_writebytes(state, state->config->demod_address,
- agc_rf_cfg, sizeof(agc_rf_cfg));
-
- /* Change the value of bit 6, 'nINAGCBY' and
- 'NSSEL[1:0] of ACG function control register 2 */
- /* Change the value of bit 6 'RFFIX'
- of AGC function control register 3 */
- i2c_writebytes(state, state->config->demod_address,
- agc_ctrl_cfg, sizeof(agc_ctrl_cfg));
-
- /* Change the TPCLK pin polarity
- data is valid on falling clock */
- i2c_writebytes(state, state->config->demod_address,
- demux_ctrl_cfg, sizeof(demux_ctrl_cfg));
-
- /* Change the value of NCOCTFV[25:0] of carrier
- recovery center frequency register */
- i2c_writebytes(state, state->config->demod_address,
- vsb_freq_cfg, sizeof(vsb_freq_cfg));
-
- /* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */
- i2c_writebytes(state, state->config->demod_address,
- agc_delay_cfg, sizeof(agc_delay_cfg));
-
- /* Change the value of IAGCBW[15:8]
- of inner AGC loop filter bandwith */
- i2c_writebytes(state, state->config->demod_address,
- agc_loop_cfg, sizeof(agc_loop_cfg));
-
- state->config->set_ts_params(fe, 0);
+ i2c_write_demod_bytes(state, top_ctrl_cfg,
+ sizeof(top_ctrl_cfg));
+ if (state->config->set_ts_params)
+ state->config->set_ts_params(fe, 0);
state->current_modulation = param->u.vsb.modulation;
}
- /* Change only if we are actually changing the channel */
- if (state->current_frequency != param->frequency) {
- u8 buf[5];
- struct i2c_msg msg = { .flags = 0, .buf = &buf[1], .len = 4 };
- int err;
+ /* Tune to the specified frequency */
+ if (state->config->pll_set)
+ state->config->pll_set(fe, param);
- state->config->pll_set(fe, param, buf);
- msg.addr = buf[0];
+ /* Keep track of the new frequency */
+ state->current_frequency = param->frequency;
- dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x "
- "0x%02x 0x%02x\n", __FUNCTION__,
- buf[0],buf[1],buf[2],buf[3],buf[4]);
- if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
- printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, buf[0], buf[1], err);
- if (err < 0)
- return err;
- else
- return -EREMOTEIO;
- }
-#if 0
- /* Check the status of the tuner pll */
- i2c_readbytes(state, buf[0], &buf[1], 1);
- dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[1]);
-#endif
- /* Update current frequency */
- state->current_frequency = param->frequency;
- }
lgdt330x_SwReset(state);
return 0;
}
@@ -328,21 +404,15 @@ static int lgdt330x_get_frontend(struct dvb_frontend* fe,
return 0;
}
-static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
- struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+ struct lgdt330x_state* state = fe->demodulator_priv;
u8 buf[3];
*status = 0; /* Reset status result */
- /*
- * You must set the Mask bits to 1 in the IRQ_MASK in order
- * to see that status bit in the IRQ_STATUS register.
- * This is done in SwReset();
- */
-
/* AGC status register */
- i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
+ i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
if ((buf[0] & 0x0c) == 0x8){
/* Test signal does not exist flag */
@@ -353,16 +423,15 @@ static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status)
return 0;
}
+ /*
+ * You must set the Mask bits to 1 in the IRQ_MASK in order
+ * to see that status bit in the IRQ_STATUS register.
+ * This is done in SwReset();
+ */
/* signal status */
- i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
+ i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
-#if 0
- /* Alternative method to check for a signal */
- /* using the SNR good/bad interrupts. */
- if ((buf[2] & 0x30) == 0x10)
- *status |= FE_HAS_SIGNAL;
-#endif
/* sync status */
if ((buf[2] & 0x03) == 0x01) {
@@ -376,7 +445,7 @@ static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status)
}
/* Carrier Recovery Lock Status Register */
- i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
+ i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
switch (state->current_modulation) {
case QAM_256:
@@ -396,13 +465,75 @@ static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status)
return 0;
}
+static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+ struct lgdt330x_state* state = fe->demodulator_priv;
+ int err;
+ u8 buf[3];
+
+ *status = 0; /* Reset status result */
+
+ /* lgdt3303 AGC status register */
+ err = i2c_read_demod_bytes(state, 0x58, buf, 1);
+ if (err < 0)
+ return err;
+
+ dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
+ if ((buf[0] & 0x21) == 0x01){
+ /* Test input signal does not exist flag */
+ /* as well as the AGC lock flag. */
+ *status |= FE_HAS_SIGNAL;
+ } else {
+ /* Without a signal all other status bits are meaningless */
+ return 0;
+ }
+
+ /* Carrier Recovery Lock Status Register */
+ i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
+ dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ /* Need to undestand why there are 3 lock levels here */
+ if ((buf[0] & 0x07) == 0x07)
+ *status |= FE_HAS_CARRIER;
+ else
+ break;
+ i2c_read_demod_bytes(state, 0x8a, buf, 1);
+ if ((buf[0] & 0x04) == 0x04)
+ *status |= FE_HAS_SYNC;
+ if ((buf[0] & 0x01) == 0x01)
+ *status |= FE_HAS_LOCK;
+ if ((buf[0] & 0x08) == 0x08)
+ *status |= FE_HAS_VITERBI;
+ break;
+ case VSB_8:
+ if ((buf[0] & 0x80) == 0x80)
+ *status |= FE_HAS_CARRIER;
+ else
+ break;
+ i2c_read_demod_bytes(state, 0x38, buf, 1);
+ if ((buf[0] & 0x02) == 0x00)
+ *status |= FE_HAS_SYNC;
+ if ((buf[0] & 0x01) == 0x01) {
+ *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_VITERBI;
+ }
+ break;
+ default:
+ printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ }
+ return 0;
+}
+
static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
{
/* not directly available. */
+ *strength = 0;
return 0;
}
-static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr)
+static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
{
#ifdef SNR_IN_DB
/*
@@ -451,7 +582,7 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr)
91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
- 90833, 114351, 143960, 181235, 228161, 0x040000
+ 90833, 114351, 143960, 181235, 228161, 0x080000
};
static u8 buf[5];/* read data buffer */
@@ -459,8 +590,8 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr)
static u32 snr_db; /* index into SNR_EQ[] */
struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
- /* read both equalizer and pase tracker noise data */
- i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
+ /* read both equalizer and phase tracker noise data */
+ i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
if (state->current_modulation == VSB_8) {
/* Equalizer Mean-Square Error Register for VSB */
@@ -496,19 +627,20 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr)
struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
/* read both equalizer and pase tracker noise data */
- i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
+ i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
if (state->current_modulation == VSB_8) {
- /* Equalizer Mean-Square Error Register for VSB */
- noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
- } else {
- /* Phase Tracker Mean-Square Error Register for QAM */
+ /* Phase Tracker Mean-Square Error Register for VSB */
noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
+ } else {
+
+ /* Carrier Recovery Mean-Square Error for QAM */
+ i2c_read_demod_bytes(state, 0x1a, buf, 2);
+ noise = ((buf[0] & 3) << 8) | buf[1];
}
/* Small values for noise mean signal is better so invert noise */
- /* Noise is 19 bit value so discard 3 LSB*/
- *snr = ~noise>>3;
+ *snr = ~noise;
#endif
dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
@@ -516,6 +648,32 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr)
return 0;
}
+static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+ /* Return the raw noise value */
+ static u8 buf[5];/* read data buffer */
+ static u32 noise; /* noise value */
+ struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+
+ if (state->current_modulation == VSB_8) {
+
+ /* Phase Tracker Mean-Square Error Register for VSB */
+ noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
+ } else {
+
+ /* Carrier Recovery Mean-Square Error for QAM */
+ i2c_read_demod_bytes(state, 0x1a, buf, 2);
+ noise = (buf[0] << 8) | buf[1];
+ }
+
+ /* Small values for noise mean signal is better so invert noise */
+ *snr = ~noise;
+
+ dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
+
+ return 0;
+}
+
static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
{
/* I have no idea about this - it may not be needed */
@@ -531,7 +689,8 @@ static void lgdt330x_release(struct dvb_frontend* fe)
kfree(state);
}
-static struct dvb_frontend_ops lgdt330x_ops;
+static struct dvb_frontend_ops lgdt3302_ops;
+static struct dvb_frontend_ops lgdt3303_ops;
struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
struct i2c_adapter* i2c)
@@ -548,9 +707,19 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
/* Setup the state */
state->config = config;
state->i2c = i2c;
- memcpy(&state->ops, &lgdt330x_ops, sizeof(struct dvb_frontend_ops));
+ switch (config->demod_chip) {
+ case LGDT3302:
+ memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
+ break;
+ case LGDT3303:
+ memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
+ break;
+ default:
+ goto error;
+ }
+
/* Verify communication with demod chip */
- if (i2c_selectreadbytes(state, 2, buf, 1))
+ if (i2c_read_demod_bytes(state, 2, buf, 1))
goto error;
state->current_frequency = -1;
@@ -568,9 +737,33 @@ error:
return NULL;
}
-static struct dvb_frontend_ops lgdt330x_ops = {
+static struct dvb_frontend_ops lgdt3302_ops = {
+ .info = {
+ .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
+ .type = FE_ATSC,
+ .frequency_min= 54000000,
+ .frequency_max= 858000000,
+ .frequency_stepsize= 62500,
+ /* Symbol rate is for all VSB modes need to check QAM */
+ .symbol_rate_min = 10762000,
+ .symbol_rate_max = 10762000,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+ .init = lgdt330x_init,
+ .set_frontend = lgdt330x_set_parameters,
+ .get_frontend = lgdt330x_get_frontend,
+ .get_tune_settings = lgdt330x_get_tune_settings,
+ .read_status = lgdt3302_read_status,
+ .read_ber = lgdt330x_read_ber,
+ .read_signal_strength = lgdt330x_read_signal_strength,
+ .read_snr = lgdt3302_read_snr,
+ .read_ucblocks = lgdt330x_read_ucblocks,
+ .release = lgdt330x_release,
+};
+
+static struct dvb_frontend_ops lgdt3303_ops = {
.info = {
- .name= "LG Electronics lgdt330x VSB/QAM Frontend",
+ .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
.type = FE_ATSC,
.frequency_min= 54000000,
.frequency_max= 858000000,
@@ -584,15 +777,15 @@ static struct dvb_frontend_ops lgdt330x_ops = {
.set_frontend = lgdt330x_set_parameters,
.get_frontend = lgdt330x_get_frontend,
.get_tune_settings = lgdt330x_get_tune_settings,
- .read_status = lgdt330x_read_status,
+ .read_status = lgdt3303_read_status,
.read_ber = lgdt330x_read_ber,
.read_signal_strength = lgdt330x_read_signal_strength,
- .read_snr = lgdt330x_read_snr,
+ .read_snr = lgdt3303_read_snr,
.read_ucblocks = lgdt330x_read_ucblocks,
.release = lgdt330x_release,
};
-MODULE_DESCRIPTION("lgdt330x [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
+MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
MODULE_AUTHOR("Wilson Michaels");
MODULE_LICENSE("GPL");
@@ -601,6 +794,5 @@ EXPORT_SYMBOL(lgdt330x_attach);
/*
* Local variables:
* c-basic-offset: 8
- * compile-command: "make DVB=1"
* End:
*/
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index 04986f8e7565..e209ba1e47c5 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -1,5 +1,5 @@
/*
- * Support for LGDT3302 & LGDT3303 (DViCO FustionHDTV Gold) - VSB/QAM
+ * Support for LGDT3302 and LGDT3303 - VSB/QAM
*
* Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
*
@@ -24,14 +24,26 @@
#include <linux/dvb/frontend.h>
+typedef enum lg_chip_t {
+ UNDEFINED,
+ LGDT3302,
+ LGDT3303
+}lg_chip_type;
+
struct lgdt330x_config
{
/* The demodulator's i2c address */
u8 demod_address;
+ /* LG demodulator chip LGDT3302 or LGDT3303 */
+ lg_chip_type demod_chip;
+
+ /* MPEG hardware interface - 0:parallel 1:serial */
+ int serial_mpeg;
+
/* PLL interface */
int (*pll_rf_set) (struct dvb_frontend* fe, int index);
- int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pll_address);
+ int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
/* Need to set device param for start_dma */
int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h
index 4143ce8f1a95..59b7c5b9012d 100644
--- a/drivers/media/dvb/frontends/lgdt330x_priv.h
+++ b/drivers/media/dvb/frontends/lgdt330x_priv.h
@@ -1,5 +1,5 @@
/*
- * Support for LGDT3302 & LGDT3303 (DViCO FustionHDTV Gold) - VSB/QAM
+ * Support for LGDT3302 and LGDT3303 - VSB/QAM
*
* Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
*
@@ -57,8 +57,10 @@ enum I2C_REG {
PH_ERR1= 0x4a,
PH_ERR2= 0x4b,
DEMUX_CONTROL= 0x66,
- PACKET_ERR_COUNTER1= 0x6a,
- PACKET_ERR_COUNTER2= 0x6b,
+ LGDT3302_PACKET_ERR_COUNTER1= 0x6a,
+ LGDT3302_PACKET_ERR_COUNTER2= 0x6b,
+ LGDT3303_PACKET_ERR_COUNTER1= 0x8b,
+ LGDT3303_PACKET_ERR_COUNTER2= 0x8c,
};
#endif /* _LGDT330X_PRIV_ */
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index e455aecd76b2..e38454901dd1 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -29,6 +29,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mt312_priv.h"
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index d32dc4de9e7f..f0c610f2c2df 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -35,6 +35,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "mt352_priv.h"
@@ -462,9 +464,11 @@ static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
{
struct mt352_state* state = fe->demodulator_priv;
- u16 signal = ((mt352_read_register(state, AGC_GAIN_1) << 8) & 0x0f) |
- (mt352_read_register(state, AGC_GAIN_0));
+ /* align the 12 bit AGC gain with the most significant bits */
+ u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
+ (mt352_read_register(state, AGC_GAIN_0) << 4);
+ /* inverse of gain is signal strength */
*strength = ~signal;
return 0;
}
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
index 35a1d60f1927..30786b1911bd 100644
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -32,6 +32,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "nxt2002.h"
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index 966de9853d18..88a57b791112 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -482,6 +482,7 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
return result;
+ msleep(500);
return 0;
}
@@ -525,6 +526,12 @@ static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
return 0;
}
+static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 500;
+ return 0;
+}
+
static struct dvb_frontend_ops nxt6000_ops;
struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
@@ -578,6 +585,8 @@ static struct dvb_frontend_ops nxt6000_ops = {
.init = nxt6000_init,
+ .get_tune_settings = nxt6000_fe_get_tune_settings,
+
.set_frontend = nxt6000_set_frontend,
.read_status = nxt6000_read_status,
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index cc0a77c790f1..817b044c7fd1 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -36,6 +36,8 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
@@ -370,22 +372,19 @@ static int or51132_set_parameters(struct dvb_frontend* fe,
or51132_setmode(fe);
}
- /* Change only if we are actually changing the channel */
- if (state->current_frequency != param->frequency) {
- dvb_pll_configure(state->config->pll_desc, buf,
- param->frequency, 0);
- dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
- "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
- if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
- printk(KERN_WARNING "or51132: set_parameters error "
- "writing to tuner\n");
-
- /* Set to current mode */
- or51132_setmode(fe);
+ dvb_pll_configure(state->config->pll_desc, buf,
+ param->frequency, 0);
+ dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
+ "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
+ if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
+ printk(KERN_WARNING "or51132: set_parameters error "
+ "writing to tuner\n");
- /* Update current frequency */
- state->current_frequency = param->frequency;
- }
+ /* Set to current mode */
+ or51132_setmode(fe);
+
+ /* Update current frequency */
+ state->current_frequency = param->frequency;
return 0;
}
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index ad56a9958404..8a9db23dd1b7 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -34,6 +34,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include <asm/byteorder.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 4f396ac8de77..f265418e3261 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
#include "dvb_frontend.h"
#include "s5h1420.h"
@@ -48,7 +50,8 @@ struct s5h1420_state {
};
static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
-static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings);
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
+ struct dvb_frontend_tune_settings* fesettings);
static int debug = 0;
@@ -91,7 +94,8 @@ static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
switch(voltage) {
case SEC_VOLTAGE_13:
- s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
+ s5h1420_writereg(state, 0x3c,
+ (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
break;
case SEC_VOLTAGE_18:
@@ -112,18 +116,21 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
switch(tone) {
case SEC_TONE_ON:
- s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
+ s5h1420_writereg(state, 0x3b,
+ (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
break;
case SEC_TONE_OFF:
- s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
+ s5h1420_writereg(state, 0x3b,
+ (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
break;
}
return 0;
}
-static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
+ struct dvb_diseqc_master_cmd* cmd)
{
struct s5h1420_state* state = fe->demodulator_priv;
u8 val;
@@ -131,6 +138,9 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
unsigned long timeout;
int result = 0;
+ if (cmd->msg_len > 8)
+ return -EINVAL;
+
/* setup for DISEQC */
val = s5h1420_readreg(state, 0x3b);
s5h1420_writereg(state, 0x3b, 0x02);
@@ -138,16 +148,17 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
/* write the DISEQC command bytes */
for(i=0; i< cmd->msg_len; i++) {
- s5h1420_writereg(state, 0x3c + i, cmd->msg[i]);
+ s5h1420_writereg(state, 0x3d + i, cmd->msg[i]);
}
/* kick off transmission */
- s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08);
+ s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
+ ((cmd->msg_len-1) << 4) | 0x08);
/* wait for transmission to complete */
timeout = jiffies + ((100*HZ) / 1000);
while(time_before(jiffies, timeout)) {
- if (s5h1420_readreg(state, 0x3b) & 0x08)
+ if (!(s5h1420_readreg(state, 0x3b) & 0x08))
break;
msleep(5);
@@ -161,7 +172,8 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
return result;
}
-static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply)
+static int s5h1420_recv_slave_reply (struct dvb_frontend* fe,
+ struct dvb_diseqc_slave_reply* reply)
{
struct s5h1420_state* state = fe->demodulator_priv;
u8 val;
@@ -205,7 +217,7 @@ static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_
/* extract data */
for(i=0; i< length; i++) {
- reply->msg[i] = s5h1420_readreg(state, 0x3c + i);
+ reply->msg[i] = s5h1420_readreg(state, 0x3d + i);
}
exit:
@@ -236,7 +248,7 @@ static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicm
s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
/* wait for transmission to complete */
- timeout = jiffies + ((20*HZ) / 1000);
+ timeout = jiffies + ((100*HZ) / 1000);
while(time_before(jiffies, timeout)) {
if (!(s5h1420_readreg(state, 0x3b) & 0x08))
break;
@@ -259,9 +271,9 @@ static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
val = s5h1420_readreg(state, 0x14);
if (val & 0x02)
- status |= FE_HAS_SIGNAL; // FIXME: not sure if this is right
+ status |= FE_HAS_SIGNAL;
if (val & 0x01)
- status |= FE_HAS_CARRIER; // FIXME: not sure if this is right
+ status |= FE_HAS_CARRIER;
val = s5h1420_readreg(state, 0x36);
if (val & 0x01)
status |= FE_HAS_VITERBI;
@@ -284,8 +296,8 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* determine lock state */
*status = s5h1420_get_status_bits(state);
- /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion,
- wait a bit and check again */
+ /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
+ the inversion, wait a bit and check again */
if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
val = s5h1420_readreg(state, 0x32);
if ((val & 0x07) == 0x03) {
@@ -330,6 +342,10 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
tmp = (tmp * 2 * 7) / 8;
break;
}
+ if (tmp == 0) {
+ printk("s5h1420: avoided division by 0\n");
+ tmp = 1;
+ }
tmp = state->fclk / tmp;
/* set the MPEG_CLK_INTL for the calculated data rate */
@@ -368,16 +384,21 @@ static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
s5h1420_writereg(state, 0x46, 0x1d);
mdelay(25);
- return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ return 0;
}
static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
{
struct s5h1420_state* state = fe->demodulator_priv;
- u8 val = 0xff - s5h1420_readreg(state, 0x15);
+ u8 val = s5h1420_readreg(state, 0x15);
- return (int) ((val << 8) | val);
+ *strength = (u16) ((val << 8) | val);
+
+ return 0;
}
static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
@@ -386,7 +407,10 @@ static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
s5h1420_writereg(state, 0x46, 0x1f);
mdelay(25);
- return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+
+ return 0;
}
static void s5h1420_reset(struct s5h1420_state* state)
@@ -396,11 +420,12 @@ static void s5h1420_reset(struct s5h1420_state* state)
udelay(10);
}
-static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+static void s5h1420_setsymbolrate(struct s5h1420_state* state,
+ struct dvb_frontend_parameters *p)
{
u64 val;
- val = (p->u.qpsk.symbol_rate / 1000) * (1<<24);
+ val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24);
if (p->u.qpsk.symbol_rate <= 21000000) {
val *= 2;
}
@@ -415,7 +440,7 @@ static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_fronte
static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
{
- u64 val;
+ u64 val = 0;
int sampling = 2;
if (s5h1420_readreg(state, 0x05) & 0x2)
@@ -427,10 +452,10 @@ static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
val |= s5h1420_readreg(state, 0x13);
s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
- val *= (state->fclk / 1000);
+ val *= (state->fclk / 1000ULL);
do_div(val, ((1<<24) * sampling));
- return (u32) (val * 1000);
+ return (u32) (val * 1000ULL);
}
static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
@@ -463,46 +488,55 @@ static int s5h1420_getfreqoffset(struct s5h1420_state* state)
/* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
* divide fclk by 1000000 to get the correct value. */
- val = - ((val * (state->fclk/1000000)) / (1<<24));
+ val = (((-val) * (state->fclk/1000000)) / (1<<24));
return val;
}
-static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+static void s5h1420_setfec_inversion(struct s5h1420_state* state,
+ struct dvb_frontend_parameters *p)
{
+ u8 inversion = 0;
+
+ if (p->inversion == INVERSION_OFF) {
+ inversion = state->config->invert ? 0x08 : 0;
+ } else if (p->inversion == INVERSION_ON) {
+ inversion = state->config->invert ? 0 : 0x08;
+ }
+
if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
- s5h1420_writereg(state, 0x31, 0x00);
s5h1420_writereg(state, 0x30, 0x3f);
+ s5h1420_writereg(state, 0x31, 0x00 | inversion);
} else {
switch(p->u.qpsk.fec_inner) {
case FEC_1_2:
- s5h1420_writereg(state, 0x31, 0x10);
s5h1420_writereg(state, 0x30, 0x01);
+ s5h1420_writereg(state, 0x31, 0x10 | inversion);
break;
case FEC_2_3:
- s5h1420_writereg(state, 0x31, 0x11);
s5h1420_writereg(state, 0x30, 0x02);
+ s5h1420_writereg(state, 0x31, 0x11 | inversion);
break;
case FEC_3_4:
- s5h1420_writereg(state, 0x31, 0x12);
s5h1420_writereg(state, 0x30, 0x04);
- break;
+ s5h1420_writereg(state, 0x31, 0x12 | inversion);
+ break;
case FEC_5_6:
- s5h1420_writereg(state, 0x31, 0x13);
s5h1420_writereg(state, 0x30, 0x08);
+ s5h1420_writereg(state, 0x31, 0x13 | inversion);
break;
case FEC_6_7:
- s5h1420_writereg(state, 0x31, 0x14);
s5h1420_writereg(state, 0x30, 0x10);
+ s5h1420_writereg(state, 0x31, 0x14 | inversion);
break;
case FEC_7_8:
- s5h1420_writereg(state, 0x31, 0x15);
s5h1420_writereg(state, 0x30, 0x20);
+ s5h1420_writereg(state, 0x31, 0x15 | inversion);
break;
default:
@@ -536,22 +570,6 @@ static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
return FEC_NONE;
}
-static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
-{
- if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
- s5h1420_writereg(state, 0x31, 0x00);
- s5h1420_writereg(state, 0x30, 0x3f);
- } else {
- u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
- tmp |= 0x10;
-
- if (p->inversion == INVERSION_ON)
- tmp |= 0x80;
-
- s5h1420_writereg(state, 0x31, tmp);
- }
-}
-
static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
{
if (s5h1420_readreg(state, 0x32) & 0x08)
@@ -560,35 +578,35 @@ static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
return INVERSION_OFF;
}
-static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int s5h1420_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *p)
{
struct s5h1420_state* state = fe->demodulator_priv;
- u32 frequency_delta;
+ int frequency_delta;
struct dvb_frontend_tune_settings fesettings;
+ u32 tmp;
/* check if we should do a fast-tune */
memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
s5h1420_get_tune_settings(fe, &fesettings);
frequency_delta = p->frequency - state->tunedfreq;
- if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) &&
+ if ((frequency_delta > -fesettings.max_drift) &&
+ (frequency_delta < fesettings.max_drift) &&
(frequency_delta != 0) &&
(state->fec_inner == p->u.qpsk.fec_inner) &&
(state->symbol_rate == p->u.qpsk.symbol_rate)) {
- s5h1420_setfreqoffset(state, frequency_delta);
+ if (state->config->pll_set) {
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+ state->config->pll_set(fe, p, &tmp);
+ s5h1420_setfreqoffset(state, p->frequency - tmp);
+ }
return 0;
}
/* first of all, software reset */
s5h1420_reset(state);
- /* set tuner PLL */
- if (state->config->pll_set) {
- s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
- state->config->pll_set(fe, p, &state->tunedfreq);
- s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
- }
-
/* set s5h1420 fclk PLL according to desired symbol rate */
if (p->u.qpsk.symbol_rate > 28000000) {
state->fclk = 88000000;
@@ -609,8 +627,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
/* set misc registers */
s5h1420_writereg(state, 0x02, 0x00);
+ s5h1420_writereg(state, 0x06, 0x00);
s5h1420_writereg(state, 0x07, 0xb0);
- s5h1420_writereg(state, 0x0a, 0x67);
+ s5h1420_writereg(state, 0x0a, 0xe7);
s5h1420_writereg(state, 0x0b, 0x78);
s5h1420_writereg(state, 0x0c, 0x48);
s5h1420_writereg(state, 0x0d, 0x6b);
@@ -626,21 +645,26 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
/* start QPSK */
s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
- /* set the frequency offset to adjust for PLL inaccuracy */
- s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq);
+ /* set tuner PLL */
+ if (state->config->pll_set) {
+ s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+ state->config->pll_set(fe, p, &tmp);
+ s5h1420_setfreqoffset(state, 0);
+ }
/* set the reset of the parameters */
s5h1420_setsymbolrate(state, p);
- s5h1420_setinversion(state, p);
- s5h1420_setfec(state, p);
+ s5h1420_setfec_inversion(state, p);
state->fec_inner = p->u.qpsk.fec_inner;
state->symbol_rate = p->u.qpsk.symbol_rate;
state->postlocked = 0;
+ state->tunedfreq = p->frequency;
return 0;
}
-static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int s5h1420_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *p)
{
struct s5h1420_state* state = fe->demodulator_priv;
@@ -652,7 +676,8 @@ static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
return 0;
}
-static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
+ struct dvb_frontend_tune_settings* fesettings)
{
if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
fesettings->min_delay_ms = 50;
@@ -717,7 +742,8 @@ static void s5h1420_release(struct dvb_frontend* fe)
static struct dvb_frontend_ops s5h1420_ops;
-struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c)
+struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
+ struct i2c_adapter* i2c)
{
struct s5h1420_state* state = NULL;
u8 identity;
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index b687fc77ceb3..872028ddf2a2 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -30,6 +30,9 @@ struct s5h1420_config
/* the demodulator's i2c address */
u8 demod_address;
+ /* does the inversion require inversion? */
+ u8 invert:1;
+
/* PLL maintenance */
int (*pll_init)(struct dvb_frontend* fe);
int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index 764a95a2e212..1c6b2e9264bc 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -32,6 +32,8 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "sp8870.h"
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index d868a6927a16..73384e75625e 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -14,6 +14,8 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "sp887x.h"
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index 928aca052afe..6122ba754bc5 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -24,6 +24,8 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
#include "dvb_frontend.h"
#include "stv0297.h"
@@ -35,7 +37,6 @@ struct stv0297_state {
struct dvb_frontend frontend;
unsigned long base_freq;
- u8 pwm;
};
#if 1
@@ -46,94 +47,6 @@ struct stv0297_state {
#define STV0297_CLOCK_KHZ 28900
-static u8 init_tab[] = {
- 0x00, 0x09,
- 0x01, 0x69,
- 0x03, 0x00,
- 0x04, 0x00,
- 0x07, 0x00,
- 0x08, 0x00,
- 0x20, 0x00,
- 0x21, 0x40,
- 0x22, 0x00,
- 0x23, 0x00,
- 0x24, 0x40,
- 0x25, 0x88,
- 0x30, 0xff,
- 0x31, 0x00,
- 0x32, 0xff,
- 0x33, 0x00,
- 0x34, 0x50,
- 0x35, 0x7f,
- 0x36, 0x00,
- 0x37, 0x20,
- 0x38, 0x00,
- 0x40, 0x1c,
- 0x41, 0xff,
- 0x42, 0x29,
- 0x43, 0x00,
- 0x44, 0xff,
- 0x45, 0x00,
- 0x46, 0x00,
- 0x49, 0x04,
- 0x4a, 0xff,
- 0x4b, 0x7f,
- 0x52, 0x30,
- 0x55, 0xae,
- 0x56, 0x47,
- 0x57, 0xe1,
- 0x58, 0x3a,
- 0x5a, 0x1e,
- 0x5b, 0x34,
- 0x60, 0x00,
- 0x63, 0x00,
- 0x64, 0x00,
- 0x65, 0x00,
- 0x66, 0x00,
- 0x67, 0x00,
- 0x68, 0x00,
- 0x69, 0x00,
- 0x6a, 0x02,
- 0x6b, 0x00,
- 0x70, 0xff,
- 0x71, 0x00,
- 0x72, 0x00,
- 0x73, 0x00,
- 0x74, 0x0c,
- 0x80, 0x00,
- 0x81, 0x00,
- 0x82, 0x00,
- 0x83, 0x00,
- 0x84, 0x04,
- 0x85, 0x80,
- 0x86, 0x24,
- 0x87, 0x78,
- 0x88, 0x00,
- 0x89, 0x00,
- 0x90, 0x01,
- 0x91, 0x01,
- 0xa0, 0x00,
- 0xa1, 0x00,
- 0xa2, 0x00,
- 0xb0, 0x91,
- 0xb1, 0x0b,
- 0xc0, 0x53,
- 0xc1, 0x70,
- 0xc2, 0x12,
- 0xd0, 0x00,
- 0xd1, 0x00,
- 0xd2, 0x00,
- 0xd3, 0x00,
- 0xd4, 0x00,
- 0xd5, 0x00,
- 0xde, 0x00,
- 0xdf, 0x00,
- 0x61, 0x49,
- 0x62, 0x0b,
- 0x53, 0x08,
- 0x59, 0x08,
-};
-
static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
{
@@ -378,34 +291,9 @@ static int stv0297_init(struct dvb_frontend *fe)
struct stv0297_state *state = fe->demodulator_priv;
int i;
- /* soft reset */
- stv0297_writereg_mask(state, 0x80, 1, 1);
- stv0297_writereg_mask(state, 0x80, 1, 0);
-
- /* reset deinterleaver */
- stv0297_writereg_mask(state, 0x81, 1, 1);
- stv0297_writereg_mask(state, 0x81, 1, 0);
-
/* load init table */
- for (i = 0; i < sizeof(init_tab); i += 2) {
- stv0297_writereg(state, init_tab[i], init_tab[i + 1]);
- }
-
- /* set a dummy symbol rate */
- stv0297_set_symbolrate(state, 6900);
-
- /* invert AGC1 polarity */
- stv0297_writereg_mask(state, 0x88, 0x10, 0x10);
-
- /* setup bit error counting */
- stv0297_writereg_mask(state, 0xA0, 0x80, 0x00);
- stv0297_writereg_mask(state, 0xA0, 0x10, 0x00);
- stv0297_writereg_mask(state, 0xA0, 0x08, 0x00);
- stv0297_writereg_mask(state, 0xA0, 0x07, 0x04);
-
- /* min + max PWM */
- stv0297_writereg(state, 0x4a, 0x00);
- stv0297_writereg(state, 0x4b, state->pwm);
+ for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
+ stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
msleep(200);
if (state->config->pll_init)
@@ -606,7 +494,13 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
stv0297_set_inversion(state, inversion);
/* kick off lock */
- stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
+ /* Disable corner detection for higher QAMs */
+ if (p->u.qam.modulation == QAM_128 ||
+ p->u.qam.modulation == QAM_256)
+ stv0297_writereg_mask(state, 0x88, 0x08, 0x00);
+ else
+ stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
+
stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
@@ -732,7 +626,7 @@ static void stv0297_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops stv0297_ops;
struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
- struct i2c_adapter *i2c, int pwm)
+ struct i2c_adapter *i2c)
{
struct stv0297_state *state = NULL;
@@ -746,7 +640,6 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
state->i2c = i2c;
memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
state->base_freq = 0;
- state->pwm = pwm;
/* check if the demod is there */
if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 3be535989302..9e53f019db71 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -29,6 +29,12 @@ struct stv0297_config
/* the demodulator's i2c address */
u8 demod_address;
+ /* inittab - array of pairs of values.
+ * First of each pair is the register, second is the value.
+ * List should be terminated with an 0xff, 0xff pair.
+ */
+ u8* inittab;
+
/* does the "inversion" need inverted? */
u8 invert:1;
@@ -38,7 +44,7 @@ struct stv0297_config
};
extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
- struct i2c_adapter* i2c, int pwm);
+ struct i2c_adapter* i2c);
extern int stv0297_enable_plli2c(struct dvb_frontend* fe);
#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index cfa3928bb487..889d9257215d 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -48,6 +48,7 @@
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/jiffies.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
@@ -63,12 +64,8 @@ struct stv0299_state {
u32 tuner_frequency;
u32 symbol_rate;
fe_code_rate_t fec_inner;
- int errmode;
};
-#define STATUS_BER 0
-#define STATUS_UCBLOCKS 1
-
static int debug;
static int debug_legacy_dish_switch;
#define dprintk(args...) \
@@ -481,7 +478,7 @@ static int stv0299_init (struct dvb_frontend* fe)
if (state->config->pll_init) {
stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_init(fe);
+ state->config->pll_init(fe, state->i2c);
stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
}
@@ -520,7 +517,8 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct stv0299_state* state = fe->demodulator_priv;
- if (state->errmode != STATUS_BER) return 0;
+ stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10);
+ msleep(100);
*ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
return 0;
@@ -559,8 +557,9 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
struct stv0299_state* state = fe->demodulator_priv;
- if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
- else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+ stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30);
+ msleep(100);
+ *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
return 0;
}
@@ -603,7 +602,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
} else {
/* A "normal" tune is requested */
stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_set(fe, p);
+ state->config->pll_set(fe, state->i2c, p);
stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
stv0299_writeregI(state, 0x32, 0x80);
@@ -615,7 +614,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
}
} else {
stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
- state->config->pll_set(fe, p);
+ state->config->pll_set(fe, state->i2c, p);
stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
stv0299_set_FEC (state, p->u.qpsk.fec_inner);
@@ -709,7 +708,6 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
state->tuner_frequency = 0;
state->symbol_rate = 0;
state->fec_inner = 0;
- state->errmode = STATUS_BER;
/* check if the demod is there */
stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 79457a80a11f..d0c4484861e1 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -92,8 +92,8 @@ struct stv0299_config
int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
/* PLL maintenance */
- int (*pll_init)(struct dvb_frontend* fe);
- int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+ int (*pll_init)(struct dvb_frontend *fe, struct i2c_adapter *i2c);
+ int (*pll_set)(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params);
};
extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 87d5f4d8790f..eaf130e666d8 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -100,8 +100,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
ret = i2c_transfer (state->i2c, msg, 2);
if (ret != 2)
- printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n",
- state->frontend.dvb->num, __FUNCTION__, ret);
+ printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
+ __FUNCTION__, ret);
return b1[0];
}
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index ab0c032472cc..3529c618f828 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -32,6 +32,10 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
#include "dvb_frontend.h"
#include "tda1004x.h"
@@ -1046,8 +1050,7 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
tmp = tda1004x_read_byte(state, TDA1004X_SNR);
if (tmp < 0)
return -EIO;
- if (tmp)
- tmp = 255 - tmp;
+ tmp = 255 - tmp;
*snr = ((tmp << 8) | tmp);
dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
index 168e013d23bd..c05cf1861051 100644
--- a/drivers/media/dvb/frontends/tda8083.c
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/jiffies.h>
#include "dvb_frontend.h"
#include "tda8083.h"
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
index 88e125079ca1..d1cabb6a0a13 100644
--- a/drivers/media/dvb/frontends/tda80xx.c
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <asm/irq.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index 70fb44b391a7..c6d276618e86 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -194,19 +194,18 @@ static int ves1820_init(struct dvb_frontend* fe)
{
struct ves1820_state* state = fe->demodulator_priv;
int i;
- int val;
ves1820_writereg(state, 0, 0);
- for (i = 0; i < 53; i++) {
- val = ves1820_inittab[i];
- if ((i == 2) && (state->config->selagc)) val |= 0x08;
- ves1820_writereg(state, i, val);
- }
+ for (i = 0; i < sizeof(ves1820_inittab); i++)
+ ves1820_writereg(state, i, ves1820_inittab[i]);
+ if (state->config->selagc)
+ ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08);
ves1820_writereg(state, 0x34, state->pwm);
- if (state->config->pll_init) state->config->pll_init(fe);
+ if (state->config->pll_init)
+ state->config->pll_init(fe);
return 0;
}
@@ -234,7 +233,7 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p
ves1820_writereg(state, 0x09, reg0x09[real_qam]);
ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
-
+ ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0));
return 0;
}
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 706e0bcb5ede..85b437bbddcd 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -633,7 +633,6 @@ static int __devinit pluto2_probe(struct pci_dev *pdev,
i2c_set_adapdata(&pluto->i2c_adap, pluto);
strcpy(pluto->i2c_adap.name, DRIVER_NAME);
pluto->i2c_adap.owner = THIS_MODULE;
- pluto->i2c_adap.id = I2C_ALGO_BIT;
pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
pluto->i2c_adap.dev.parent = &pdev->dev;
pluto->i2c_adap.algo_data = &pluto->i2c_bit;
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index bf3c011d2cfb..d8bf65877897 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -102,6 +102,9 @@ config DVB_BUDGET_AV
select VIDEO_DEV
select VIDEO_SAA7146_VV
select DVB_STV0299
+ select DVB_TDA1004X
+ select DVB_TDA10021
+ select FW_LOADER
help
Support for simple SAA7146 based DVB cards
(so called Budget- or Nova-PCI cards) without onboard
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index e4c6e87f6c5d..22b203f8ff27 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -168,7 +168,9 @@ static void init_av7110_av(struct av7110 *av7110)
if (ret < 0)
printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
if (rgb_on &&
- (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
+ ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
+ (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
+ (av7110->dev->pci->subsystem_device == 0x0000)) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
//saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
}
@@ -177,9 +179,6 @@ static void init_av7110_av(struct av7110 *av7110)
ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
if (ret < 0)
printk("dvb-ttpci:cannot set volume :%d\n",ret);
- ret = av7110_setup_irc_config(av7110, 0);
- if (ret < 0)
- printk("dvb-ttpci:cannot setup irc config :%d\n",ret);
}
static void recover_arm(struct av7110 *av7110)
@@ -265,60 +264,6 @@ static int arm_thread(void *data)
}
-/**
- * Hack! we save the last av7110 ptr. This should be ok, since
- * you rarely will use more then one IR control.
- *
- * If we want to support multiple controls we would have to do much more...
- */
-int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
-{
- int ret = 0;
- static struct av7110 *last;
-
- dprintk(4, "%p\n", av7110);
-
- if (!av7110)
- av7110 = last;
- else
- last = av7110;
-
- if (av7110) {
- ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
- av7110->ir_config = ir_config;
- }
- return ret;
-}
-
-static void (*irc_handler)(u32);
-
-void av7110_register_irc_handler(void (*func)(u32))
-{
- dprintk(4, "registering %p\n", func);
- irc_handler = func;
-}
-
-void av7110_unregister_irc_handler(void (*func)(u32))
-{
- dprintk(4, "unregistering %p\n", func);
- irc_handler = NULL;
-}
-
-static void run_handlers(unsigned long ircom)
-{
- if (irc_handler != NULL)
- (*irc_handler)((u32) ircom);
-}
-
-static DECLARE_TASKLET(irtask, run_handlers, 0);
-
-static void IR_handle(struct av7110 *av7110, u32 ircom)
-{
- dprintk(4, "ircommand = %08x\n", ircom);
- irtask.data = (unsigned long) ircom;
- tasklet_schedule(&irtask);
-}
-
/****************************************************************************
* IRQ handling
****************************************************************************/
@@ -711,8 +656,9 @@ static void gpioirq(unsigned long data)
return;
case DATA_IRCOMMAND:
- IR_handle(av7110,
- swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
+ if (av7110->ir_handler)
+ av7110->ir_handler(av7110,
+ swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
break;
@@ -1668,9 +1614,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
int ret;
u8 data[4];
u32 div;
@@ -1687,7 +1632,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
if (params->frequency > 1530000) data[3] = 0xc0;
- ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
+ ret = i2c_transfer(i2c, &msg, 1);
if (ret != 1)
return -EIO;
return 0;
@@ -1751,9 +1696,8 @@ static u8 alps_bsbe1_inittab[] = {
0xff, 0xff
};
-static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
int ret;
u8 data[4];
u32 div;
@@ -1768,7 +1712,7 @@ static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
- ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
+ ret = i2c_transfer(i2c, &msg, 1);
return (ret != 1) ? -EIO : 0;
}
@@ -1936,6 +1880,98 @@ static struct sp8870_config alps_tdlb7_config = {
};
+static u8 nexusca_stv0297_inittab[] = {
+ 0x80, 0x01,
+ 0x80, 0x00,
+ 0x81, 0x01,
+ 0x81, 0x00,
+ 0x00, 0x09,
+ 0x01, 0x69,
+ 0x03, 0x00,
+ 0x04, 0x00,
+ 0x07, 0x00,
+ 0x08, 0x00,
+ 0x20, 0x00,
+ 0x21, 0x40,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x40,
+ 0x25, 0x88,
+ 0x30, 0xff,
+ 0x31, 0x00,
+ 0x32, 0xff,
+ 0x33, 0x00,
+ 0x34, 0x50,
+ 0x35, 0x7f,
+ 0x36, 0x00,
+ 0x37, 0x20,
+ 0x38, 0x00,
+ 0x40, 0x1c,
+ 0x41, 0xff,
+ 0x42, 0x29,
+ 0x43, 0x00,
+ 0x44, 0xff,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x49, 0x04,
+ 0x4a, 0x00,
+ 0x4b, 0x7b,
+ 0x52, 0x30,
+ 0x55, 0xae,
+ 0x56, 0x47,
+ 0x57, 0xe1,
+ 0x58, 0x3a,
+ 0x5a, 0x1e,
+ 0x5b, 0x34,
+ 0x60, 0x00,
+ 0x63, 0x00,
+ 0x64, 0x00,
+ 0x65, 0x00,
+ 0x66, 0x00,
+ 0x67, 0x00,
+ 0x68, 0x00,
+ 0x69, 0x00,
+ 0x6a, 0x02,
+ 0x6b, 0x00,
+ 0x70, 0xff,
+ 0x71, 0x00,
+ 0x72, 0x00,
+ 0x73, 0x00,
+ 0x74, 0x0c,
+ 0x80, 0x00,
+ 0x81, 0x00,
+ 0x82, 0x00,
+ 0x83, 0x00,
+ 0x84, 0x04,
+ 0x85, 0x80,
+ 0x86, 0x24,
+ 0x87, 0x78,
+ 0x88, 0x10,
+ 0x89, 0x00,
+ 0x90, 0x01,
+ 0x91, 0x01,
+ 0xa0, 0x04,
+ 0xa1, 0x00,
+ 0xa2, 0x00,
+ 0xb0, 0x91,
+ 0xb1, 0x0b,
+ 0xc0, 0x53,
+ 0xc1, 0x70,
+ 0xc2, 0x12,
+ 0xd0, 0x00,
+ 0xd1, 0x00,
+ 0xd2, 0x00,
+ 0xd3, 0x00,
+ 0xd4, 0x00,
+ 0xd5, 0x00,
+ 0xde, 0x00,
+ 0xdf, 0x00,
+ 0x61, 0x49,
+ 0x62, 0x0b,
+ 0x53, 0x08,
+ 0x59, 0x08,
+ 0xff, 0xff,
+};
static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
@@ -1984,6 +2020,7 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_
static struct stv0297_config nexusca_stv0297_config = {
.demod_address = 0x1C,
+ .inittab = nexusca_stv0297_inittab,
.invert = 1,
.pll_set = nexusca_stv0297_pll_set,
};
@@ -2261,7 +2298,7 @@ static int frontend_init(struct av7110 *av7110)
case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
- av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
+ av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
if (av7110->fe) {
/* set TDA9819 into DVB mode */
saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
@@ -2692,7 +2729,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
goto err_av7110_exit_v4l_12;
#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
- av7110_ir_init();
+ av7110_ir_init(av7110);
#endif
printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
av7110_num++;
@@ -2734,6 +2771,9 @@ static int av7110_detach(struct saa7146_dev* saa)
struct av7110 *av7110 = saa->ext_priv;
dprintk(4, "%p\n", av7110);
+#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
+ av7110_ir_exit(av7110);
+#endif
if (budgetpatch) {
/* Disable RPS1 */
saa7146_write(saa, MC1, MASK_29);
@@ -2830,7 +2870,7 @@ static struct saa7146_pci_extension_data x_var = { \
.ext_priv = x_name, \
.ext = &av7110_extension }
-MAKE_AV7110_INFO(tts_1_X, "Technotrend/Hauppauge WinTV DVB-S rev1.X");
+MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
@@ -2842,16 +2882,16 @@ MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
static struct pci_device_id pci_tbl[] = {
- MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
- MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000),
- 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(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(fsc, 0x110a, 0x0000),
+ MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
+ 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(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
@@ -2889,9 +2929,6 @@ static int __init av7110_init(void)
static void __exit av7110_exit(void)
{
-#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
- av7110_ir_exit();
-#endif
saa7146_unregister_extension(&av7110_extension);
}
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 508b7739c609..cce00ef293e9 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -228,7 +228,10 @@ struct av7110 {
struct dvb_video_events video_events;
video_size_t video_size;
- u32 ir_config;
+ u32 ir_config;
+ u32 ir_command;
+ void (*ir_handler)(struct av7110 *av7110, u32 ircom);
+ struct tasklet_struct ir_tasklet;
/* firmware stuff */
unsigned char *bin_fw;
@@ -257,12 +260,10 @@ struct av7110 {
extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid);
-extern void av7110_register_irc_handler(void (*func)(u32));
-extern void av7110_unregister_irc_handler(void (*func)(u32));
extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
-extern int av7110_ir_init (void);
-extern void av7110_ir_exit (void);
+extern int av7110_ir_init(struct av7110 *av7110);
+extern void av7110_ir_exit(struct av7110 *av7110);
/* msp3400 i2c subaddresses */
#define MSP_WR_DEM 0x10
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 1220826696c5..7442f56a72ec 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -41,6 +41,8 @@
#include "av7110.h"
#include "av7110_hw.h"
+#define _NOHANDSHAKE
+
/****************************************************************************
* DEBI functions
****************************************************************************/
@@ -364,7 +366,8 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
msleep(1);
}
- wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
+ if (FW_VERSION(av7110->arm_app) <= 0x261f)
+ wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
#ifndef _NOHANDSHAKE
start = jiffies;
@@ -437,7 +440,8 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
- wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
+ if (FW_VERSION(av7110->arm_app) <= 0x261f)
+ wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
#ifdef COM_DEBUG
start = jiffies;
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 665cdb8a3f71..f5e59fc924af 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -7,15 +7,15 @@
#include <asm/bitops.h>
#include "av7110.h"
+#include "av7110_hw.h"
-#define UP_TIMEOUT (HZ/4)
+#define UP_TIMEOUT (HZ*7/25)
/* enable ir debugging by or'ing debug with 16 */
-static int ir_initialized;
-static struct input_dev input_dev;
-
-static u32 ir_config;
+static int av_cnt;
+static struct av7110 *av_list[4];
+static struct input_dev *input_dev;
static u16 key_map [256] = {
KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
@@ -43,18 +43,21 @@ static u16 key_map [256] = {
static void av7110_emit_keyup(unsigned long data)
{
- if (!data || !test_bit(data, input_dev.key))
+ if (!data || !test_bit(data, input_dev->key))
return;
- input_event(&input_dev, EV_KEY, data, !!0);
+ input_event(input_dev, EV_KEY, data, !!0);
}
static struct timer_list keyup_timer = { .function = av7110_emit_keyup };
-static void av7110_emit_key(u32 ircom)
+static void av7110_emit_key(unsigned long parm)
{
+ struct av7110 *av7110 = (struct av7110 *) parm;
+ u32 ir_config = av7110->ir_config;
+ u32 ircom = av7110->ir_command;
u8 data;
u8 addr;
static u16 old_toggle = 0;
@@ -62,19 +65,33 @@ static void av7110_emit_key(u32 ircom)
u16 keycode;
/* extract device address and data */
- if (ir_config & 0x0001) {
- /* TODO RCMM: ? bits device address, 8 bits data */
+ switch (ir_config & 0x0003) {
+ case 0: /* RC5: 5 bits device address, 6 bits data */
+ data = ircom & 0x3f;
+ addr = (ircom >> 6) & 0x1f;
+ break;
+
+ case 1: /* RCMM: 8(?) bits device address, 8(?) bits data */
data = ircom & 0xff;
addr = (ircom >> 8) & 0xff;
- } else {
- /* RC5: 5 bits device address, 6 bits data */
+ break;
+
+ case 2: /* extended RC5: 5 bits device address, 7 bits data */
data = ircom & 0x3f;
addr = (ircom >> 6) & 0x1f;
+ /* invert 7th data bit for backward compatibility with RC5 keymaps */
+ if (!(ircom & 0x1000))
+ data |= 0x40;
+ break;
+
+ default:
+ printk("invalid ir_config %x\n", ir_config);
+ return;
}
keycode = key_map[data];
- dprintk(16, "#########%08x######### addr %i data 0x%02x (keycode %i)\n",
+ dprintk(16, "code %08x -> addr %i data 0x%02x -> keycode %i\n",
ircom, addr, data, keycode);
/* check device address (if selected) */
@@ -87,21 +104,21 @@ static void av7110_emit_key(u32 ircom)
return;
}
- if (ir_config & 0x0001)
+ if ((ir_config & 0x0003) == 1)
new_toggle = 0; /* RCMM */
else
- new_toggle = (ircom & 0x800); /* RC5 */
+ new_toggle = (ircom & 0x800); /* RC5, extended RC5 */
if (timer_pending(&keyup_timer)) {
del_timer(&keyup_timer);
if (keyup_timer.data != keycode || new_toggle != old_toggle) {
- input_event(&input_dev, EV_KEY, keyup_timer.data, !!0);
- input_event(&input_dev, EV_KEY, keycode, !0);
+ input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
+ input_event(input_dev, EV_KEY, keycode, !0);
} else
- input_event(&input_dev, EV_KEY, keycode, 2);
+ input_event(input_dev, EV_KEY, keycode, 2);
} else
- input_event(&input_dev, EV_KEY, keycode, !0);
+ input_event(input_dev, EV_KEY, keycode, !0);
keyup_timer.expires = jiffies + UP_TIMEOUT;
keyup_timer.data = keycode;
@@ -115,13 +132,13 @@ static void input_register_keys(void)
{
int i;
- memset(input_dev.keybit, 0, sizeof(input_dev.keybit));
+ memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
- for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(key_map); i++) {
if (key_map[i] > KEY_MAX)
key_map[i] = 0;
else if (key_map[i] > KEY_RESERVED)
- set_bit(key_map[i], input_dev.keybit);
+ set_bit(key_map[i], input_dev->keybit);
}
}
@@ -137,6 +154,8 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
{
char *page;
int size = 4 + 256 * sizeof(u16);
+ u32 ir_config;
+ int i;
if (count < size)
return -EINVAL;
@@ -153,60 +172,100 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
memcpy(&ir_config, page, 4);
memcpy(&key_map, page + 4, 256 * sizeof(u16));
vfree(page);
- av7110_setup_irc_config(NULL, ir_config);
+ if (FW_VERSION(av_list[0]->arm_app) >= 0x2620 && !(ir_config & 0x0001))
+ ir_config |= 0x0002; /* enable extended RC5 */
+ for (i = 0; i < av_cnt; i++)
+ av7110_setup_irc_config(av_list[i], ir_config);
input_register_keys();
return count;
}
-int __init av7110_ir_init(void)
+int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
{
- static struct proc_dir_entry *e;
+ int ret = 0;
- if (ir_initialized)
- return 0;
+ dprintk(4, "%p\n", av7110);
+ if (av7110) {
+ ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
+ av7110->ir_config = ir_config;
+ }
+ return ret;
+}
- init_timer(&keyup_timer);
- keyup_timer.data = 0;
- input_dev.name = "DVB on-card IR receiver";
+static void ir_handler(struct av7110 *av7110, u32 ircom)
+{
+ dprintk(4, "ircommand = %08x\n", ircom);
+ av7110->ir_command = ircom;
+ tasklet_schedule(&av7110->ir_tasklet);
+}
- /**
- * enable keys
- */
- set_bit(EV_KEY, input_dev.evbit);
- set_bit(EV_REP, input_dev.evbit);
- input_register_keys();
+int __init av7110_ir_init(struct av7110 *av7110)
+{
+ static struct proc_dir_entry *e;
+
+ if (av_cnt >= sizeof av_list/sizeof av_list[0])
+ return -ENOSPC;
+
+ av7110_setup_irc_config(av7110, 0x0001);
+ av_list[av_cnt++] = av7110;
- input_register_device(&input_dev);
- input_dev.timer.function = input_repeat_key;
+ if (av_cnt == 1) {
+ init_timer(&keyup_timer);
+ keyup_timer.data = 0;
- av7110_setup_irc_config(NULL, 0x0001);
- av7110_register_irc_handler(av7110_emit_key);
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
- e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
- if (e) {
- e->write_proc = av7110_ir_write_proc;
- e->size = 4 + 256 * sizeof(u16);
+ input_dev->name = "DVB on-card IR receiver";
+
+ set_bit(EV_KEY, input_dev->evbit);
+ set_bit(EV_REP, input_dev->evbit);
+ input_register_keys();
+ input_register_device(input_dev);
+ input_dev->timer.function = input_repeat_key;
+
+ e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
+ if (e) {
+ e->write_proc = av7110_ir_write_proc;
+ e->size = 4 + 256 * sizeof(u16);
+ }
}
- ir_initialized = 1;
+ tasklet_init(&av7110->ir_tasklet, av7110_emit_key, (unsigned long) av7110);
+ av7110->ir_handler = ir_handler;
+
return 0;
}
-void __exit av7110_ir_exit(void)
+void __exit av7110_ir_exit(struct av7110 *av7110)
{
- if (ir_initialized == 0)
+ int i;
+
+ if (av_cnt == 0)
return;
- del_timer_sync(&keyup_timer);
- remove_proc_entry("av7110_ir", NULL);
- av7110_unregister_irc_handler(av7110_emit_key);
- input_unregister_device(&input_dev);
- ir_initialized = 0;
+
+ av7110->ir_handler = NULL;
+ tasklet_kill(&av7110->ir_tasklet);
+ for (i = 0; i < av_cnt; i++)
+ if (av_list[i] == av7110) {
+ av_list[i] = av_list[av_cnt-1];
+ av_list[av_cnt-1] = NULL;
+ break;
+ }
+
+ if (av_cnt == 1) {
+ del_timer_sync(&keyup_timer);
+ remove_proc_entry("av7110_ir", NULL);
+ input_unregister_device(input_dev);
+ }
+
+ av_cnt--;
}
//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
//MODULE_LICENSE("GPL");
-
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index e65fc36e2ce8..6af74f78b3e5 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -70,7 +70,7 @@ static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
return 0;
}
-static struct v4l2_input inputs[2] = {
+static struct v4l2_input inputs[4] = {
{
.index = 0,
.name = "DVB",
@@ -87,6 +87,22 @@ static struct v4l2_input inputs[2] = {
.tuner = 0,
.std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+ }, {
+ .index = 2,
+ .name = "Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .audioset = 0,
+ .tuner = 0,
+ .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .status = 0,
+ }, {
+ .index = 3,
+ .name = "Y/C",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .audioset = 0,
+ .tuner = 0,
+ .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .status = 0,
}
};
@@ -212,24 +228,44 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
}
if (0 != av7110->current_input) {
+ dprintk(1, "switching to analog TV:\n");
adswitch = 1;
source = SAA7146_HPS_SOURCE_PORT_B;
sync = SAA7146_HPS_SYNC_PORT_B;
memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
- dprintk(1, "switching to analog TV\n");
- msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
- msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
- msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
- msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
- if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
- if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
- dprintk(1, "setting band in demodulator failed.\n");
- } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
- saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
+ switch (av7110->current_input) {
+ case 1:
+ dprintk(1, "switching SAA7113 to Analog Tuner Input.\n");
+ msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
+ msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
+ msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
+ msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
+
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
+ if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
+ dprintk(1, "setting band in demodulator failed.\n");
+ } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
+ saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
+ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
+ }
+ if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1)
+ dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+ break;
+ case 2:
+ dprintk(1, "switching SAA7113 to Video AV CVBS Input.\n");
+ if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1)
+ dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+ break;
+ case 3:
+ dprintk(1, "switching SAA7113 to Video AV Y/C Input.\n");
+ if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1)
+ dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num);
+ break;
+ default:
+ dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input.\n");
}
} else {
adswitch = 0;
@@ -300,7 +336,6 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
// FIXME: standard / stereo detection is still broken
msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
-
msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
stereo = (s8)(stereo_det >> 8);
@@ -310,7 +345,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
t->audmode = V4L2_TUNER_MODE_STEREO;
}
else if (stereo < -0x10) {
- /* bilingual*/
+ /* bilingual */
t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
t->audmode = V4L2_TUNER_MODE_LANG1;
}
@@ -344,7 +379,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
fm_matrix = 0x3000; // mono
src = 0x0010;
break;
- default: /* case V4L2_TUNER_MODE_MONO: {*/
+ default: /* case V4L2_TUNER_MODE_MONO: */
dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
fm_matrix = 0x3000; // mono
src = 0x0030;
@@ -406,7 +441,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
if (av7110->analog_tuner_flags) {
- if (i->index < 0 || i->index >= 2)
+ if (i->index < 0 || i->index >= 4)
return -EINVAL;
} else {
if (i->index != 0)
@@ -433,10 +468,9 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
if (!av7110->analog_tuner_flags)
return 0;
- if (input < 0 || input >= 2)
+ if (input < 0 || input >= 4)
return -EINVAL;
- /* FIXME: switch inputs here */
av7110->current_input = input;
return av7110_dvb_c_switch(fh);
}
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 9746d2bb916f..7692cd23f839 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -192,7 +192,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
struct budget_av *budget_av = (struct budget_av *) ca->data;
struct saa7146_dev *saa = budget_av->budget.dev;
- int timeout = 50; // 5 seconds (4.4.6 Ready)
+ int timeout = 500; // 5 seconds (4.4.6 Ready)
if (slot != 0)
return -EINVAL;
@@ -217,7 +217,6 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");
saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
- saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
return -ETIMEDOUT;
}
@@ -276,7 +275,6 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open
{
printk(KERN_INFO "budget-av: cam ejected\n");
saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
- saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
budget_av->slot_status = 0;
}
}
@@ -453,9 +451,9 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra
}
static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
struct dvb_frontend_parameters *params)
{
- struct budget_av *budget_av = (struct budget_av *) fe->dvb->priv;
u32 div;
u8 buf[4];
struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
@@ -481,7 +479,7 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
else if (params->frequency < 2150000)
buf[3] |= 0xC0;
- if (i2c_transfer(&budget_av->budget.i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -745,6 +743,7 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBT_KNC1_PLUS:
// Enable / PowerON Frontend
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
break;
}
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index a1267054bc01..51c30ba68140 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -40,6 +40,7 @@
#include "dvb_ca_en50221.h"
#include "stv0299.h"
+#include "stv0297.h"
#include "tda1004x.h"
#define DEBIADDR_IR 0x1234
@@ -63,7 +64,7 @@
struct budget_ci {
struct budget budget;
- struct input_dev input_dev;
+ struct input_dev *input_dev;
struct tasklet_struct msp430_irq_tasklet;
struct tasklet_struct ciintf_irq_tasklet;
int slot_status;
@@ -144,7 +145,7 @@ static void msp430_ir_debounce(unsigned long data)
static void msp430_ir_interrupt(unsigned long data)
{
struct budget_ci *budget_ci = (struct budget_ci *) data;
- struct input_dev *dev = &budget_ci->input_dev;
+ struct input_dev *dev = budget_ci->input_dev;
unsigned int code =
ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
@@ -180,25 +181,27 @@ static void msp430_ir_interrupt(unsigned long data)
static int msp430_ir_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
+ struct input_dev *input_dev;
int i;
- memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
+ budget_ci->input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
- budget_ci->input_dev.name = budget_ci->ir_dev_name;
- set_bit(EV_KEY, budget_ci->input_dev.evbit);
+ input_dev->name = budget_ci->ir_dev_name;
- for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++)
+ set_bit(EV_KEY, input_dev->evbit);
+ for (i = 0; i < ARRAY_SIZE(key_map); i++)
if (key_map[i])
- set_bit(key_map[i], budget_ci->input_dev.keybit);
+ set_bit(key_map[i], input_dev->keybit);
- input_register_device(&budget_ci->input_dev);
+ input_register_device(budget_ci->input_dev);
- budget_ci->input_dev.timer.function = msp430_ir_debounce;
+ input_dev->timer.function = msp430_ir_debounce;
saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
-
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
return 0;
@@ -207,7 +210,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
static void msp430_ir_deinit(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *dev = &budget_ci->input_dev;
+ struct input_dev *dev = budget_ci->input_dev;
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
@@ -548,9 +551,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
{
- struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
u8 buf[4];
u32 div;
struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
@@ -567,7 +569,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_param
if (params->frequency > 1530000)
buf[3] = 0xc0;
- if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -669,9 +671,9 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
}
static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
struct dvb_frontend_parameters *params)
{
- struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
u32 div;
u8 buf[4];
struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
@@ -697,7 +699,7 @@ static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
else if (params->frequency < 2150000)
buf[3] |= 0xC0;
- if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -848,6 +850,180 @@ static struct tda1004x_config philips_tdm1316l_config = {
.request_firmware = philips_tdm1316l_request_firmware,
};
+static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+ struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
+ u8 tuner_buf[5];
+ struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
+ .flags = 0,
+ .buf = tuner_buf,
+ .len = sizeof(tuner_buf) };
+ int tuner_frequency = 0;
+ u8 band, cp, filter;
+
+ // determine charge pump
+ tuner_frequency = params->frequency + 36125000;
+ if (tuner_frequency < 87000000)
+ return -EINVAL;
+ else if (tuner_frequency < 130000000) {
+ cp = 3;
+ band = 1;
+ } else if (tuner_frequency < 160000000) {
+ cp = 5;
+ band = 1;
+ } else if (tuner_frequency < 200000000) {
+ cp = 6;
+ band = 1;
+ } else if (tuner_frequency < 290000000) {
+ cp = 3;
+ band = 2;
+ } else if (tuner_frequency < 420000000) {
+ cp = 5;
+ band = 2;
+ } else if (tuner_frequency < 480000000) {
+ cp = 6;
+ band = 2;
+ } else if (tuner_frequency < 620000000) {
+ cp = 3;
+ band = 4;
+ } else if (tuner_frequency < 830000000) {
+ cp = 5;
+ band = 4;
+ } else if (tuner_frequency < 895000000) {
+ cp = 7;
+ band = 4;
+ } else
+ return -EINVAL;
+
+ // assume PLL filter should always be 8MHz for the moment.
+ filter = 1;
+
+ // calculate divisor
+ tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
+
+ // setup tuner buffer
+ tuner_buf[0] = tuner_frequency >> 8;
+ tuner_buf[1] = tuner_frequency & 0xff;
+ tuner_buf[2] = 0xc8;
+ tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+ tuner_buf[4] = 0x80;
+
+ stv0297_enable_plli2c(fe);
+ if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+
+ msleep(50);
+
+ stv0297_enable_plli2c(fe);
+ if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
+ return -EIO;
+
+ msleep(1);
+
+ return 0;
+}
+
+static u8 dvbc_philips_tdm1316l_inittab[] = {
+ 0x80, 0x01,
+ 0x80, 0x00,
+ 0x81, 0x01,
+ 0x81, 0x00,
+ 0x00, 0x09,
+ 0x01, 0x69,
+ 0x03, 0x00,
+ 0x04, 0x00,
+ 0x07, 0x00,
+ 0x08, 0x00,
+ 0x20, 0x00,
+ 0x21, 0x40,
+ 0x22, 0x00,
+ 0x23, 0x00,
+ 0x24, 0x40,
+ 0x25, 0x88,
+ 0x30, 0xff,
+ 0x31, 0x00,
+ 0x32, 0xff,
+ 0x33, 0x00,
+ 0x34, 0x50,
+ 0x35, 0x7f,
+ 0x36, 0x00,
+ 0x37, 0x20,
+ 0x38, 0x00,
+ 0x40, 0x1c,
+ 0x41, 0xff,
+ 0x42, 0x29,
+ 0x43, 0x20,
+ 0x44, 0xff,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x49, 0x04,
+ 0x4a, 0x00,
+ 0x4b, 0x7b,
+ 0x52, 0x30,
+ 0x55, 0xae,
+ 0x56, 0x47,
+ 0x57, 0xe1,
+ 0x58, 0x3a,
+ 0x5a, 0x1e,
+ 0x5b, 0x34,
+ 0x60, 0x00,
+ 0x63, 0x00,
+ 0x64, 0x00,
+ 0x65, 0x00,
+ 0x66, 0x00,
+ 0x67, 0x00,
+ 0x68, 0x00,
+ 0x69, 0x00,
+ 0x6a, 0x02,
+ 0x6b, 0x00,
+ 0x70, 0xff,
+ 0x71, 0x00,
+ 0x72, 0x00,
+ 0x73, 0x00,
+ 0x74, 0x0c,
+ 0x80, 0x00,
+ 0x81, 0x00,
+ 0x82, 0x00,
+ 0x83, 0x00,
+ 0x84, 0x04,
+ 0x85, 0x80,
+ 0x86, 0x24,
+ 0x87, 0x78,
+ 0x88, 0x10,
+ 0x89, 0x00,
+ 0x90, 0x01,
+ 0x91, 0x01,
+ 0xa0, 0x04,
+ 0xa1, 0x00,
+ 0xa2, 0x00,
+ 0xb0, 0x91,
+ 0xb1, 0x0b,
+ 0xc0, 0x53,
+ 0xc1, 0x70,
+ 0xc2, 0x12,
+ 0xd0, 0x00,
+ 0xd1, 0x00,
+ 0xd2, 0x00,
+ 0xd3, 0x00,
+ 0xd4, 0x00,
+ 0xd5, 0x00,
+ 0xde, 0x00,
+ 0xdf, 0x00,
+ 0x61, 0x38,
+ 0x62, 0x0a,
+ 0x53, 0x13,
+ 0x59, 0x08,
+ 0xff, 0xff,
+};
+
+static struct stv0297_config dvbc_philips_tdm1316l_config = {
+ .demod_address = 0x1c,
+ .inittab = dvbc_philips_tdm1316l_inittab,
+ .invert = 0,
+ .pll_set = dvbc_philips_tdm1316l_pll_set,
+};
+
+
static void frontend_init(struct budget_ci *budget_ci)
@@ -869,6 +1045,15 @@ static void frontend_init(struct budget_ci *budget_ci)
}
break;
+ case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
+ budget_ci->tuner_pll_address = 0x61;
+ budget_ci->budget.dvb_frontend =
+ stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+ if (budget_ci->budget.dvb_frontend) {
+ break;
+ }
+ break;
+
case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
budget_ci->tuner_pll_address = 0x63;
budget_ci->budget.dvb_frontend =
@@ -878,7 +1063,7 @@ static void frontend_init(struct budget_ci *budget_ci)
}
break;
- case 0x1012: // Hauppauge/TT Nova-T CI budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
+ case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
budget_ci->tuner_pll_address = 0x60;
budget_ci->budget.dvb_frontend =
tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
@@ -966,10 +1151,12 @@ static struct saa7146_extension budget_extension;
MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
+ MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
{
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 8142e26b47f5..b1f21ef0e3b3 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -353,9 +353,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
u8 data[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -370,7 +369,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
if (params->frequency > 1530000) data[3] = 0xc0;
- if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+ if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
return 0;
}
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 9961917e8a7f..43d6c8268642 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -332,9 +332,8 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra
return 0;
}
-static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
{
- struct budget* budget = (struct budget*) fe->dvb->priv;
u8 data[4];
u32 div;
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -349,7 +348,7 @@ static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param
if (params->frequency > 1530000) data[3] = 0xc0;
- if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+ if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
return 0;
}
@@ -481,6 +480,7 @@ static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
static struct s5h1420_config s5h1420_config = {
.demod_address = 0x53,
+ .invert = 1,
.pll_set = s5h1420_pll_set,
};
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index aa43b5fcb8e7..d200ab0ad9e7 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/errno.h>
+#include <linux/jiffies.h>
#include <asm/semaphore.h>
#include "dvb_frontend.h"
@@ -570,7 +571,8 @@ static void ttusb_handle_sec_data(struct ttusb_channel *channel,
const u8 * data, int len);
#endif
-static int numpkt = 0, lastj, numts, numstuff, numsec, numinvalid;
+static int numpkt = 0, numts, numstuff, numsec, numinvalid;
+static unsigned long lastj;
static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
int len)
@@ -779,7 +781,7 @@ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
u8 *data;
int len;
numpkt++;
- if ((jiffies - lastj) >= HZ) {
+ if (time_after_eq(jiffies, lastj + HZ)) {
#if DEBUG > 2
printk
("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
@@ -1299,7 +1301,7 @@ static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32
return 0;
}
-static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
{
struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
u8 buf[4];
@@ -1322,7 +1324,7 @@ static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
if (ttusb->revision == TTUSB_REV_2_2)
buf[3] |= 0x20;
- if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(i2c, &msg, 1) != 1)
return -EIO;
return 0;
@@ -1472,8 +1474,6 @@ static void frontend_init(struct ttusb* ttusb)
static struct i2c_algorithm ttusb_dec_algo = {
- .name = "ttusb dec i2c algorithm",
- .id = I2C_ALGO_BIT,
.master_xfer = master_xfer,
.functionality = functionality,
};
@@ -1525,7 +1525,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
#endif
ttusb->i2c_adap.algo = &ttusb_dec_algo;
ttusb->i2c_adap.algo_data = NULL;
- ttusb->i2c_adap.id = I2C_ALGO_BIT;
result = i2c_add_adapter(&ttusb->i2c_adap);
if (result) {
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 45c9a9a08e4d..832d179f26fa 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/crc32.h>
@@ -153,7 +152,8 @@ struct ttusb_dec {
struct list_head filter_info_list;
spinlock_t filter_info_list_lock;
- struct input_dev rc_input_dev;
+ struct input_dev *rc_input_dev;
+ char rc_phys[64];
int active; /* Loaded successfully */
};
@@ -236,9 +236,9 @@ static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs)
* this should/could be added later ...
* for now lets report each signal as a key down and up*/
dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
- input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1);
- input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0);
- input_sync(&dec->rc_input_dev);
+ input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
+ input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
+ input_sync(dec->rc_input_dev);
}
exit: retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -1182,29 +1182,38 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
(unsigned long)dec);
}
-static void ttusb_init_rc( struct ttusb_dec *dec)
+static int ttusb_init_rc(struct ttusb_dec *dec)
{
+ struct input_dev *input_dev;
u8 b[] = { 0x00, 0x01 };
int i;
- init_input_dev(&dec->rc_input_dev);
+ usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
+ strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
- dec->rc_input_dev.name = "ttusb_dec remote control";
- dec->rc_input_dev.evbit[0] = BIT(EV_KEY);
- dec->rc_input_dev.keycodesize = sizeof(u16);
- dec->rc_input_dev.keycodemax = 0x1a;
- dec->rc_input_dev.keycode = rc_keys;
+ dec->rc_input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->name = "ttusb_dec remote control";
+ input_dev->phys = dec->rc_phys;
+ input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->keycodesize = sizeof(u16);
+ input_dev->keycodemax = 0x1a;
+ input_dev->keycode = rc_keys;
- for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
- set_bit(rc_keys[i], dec->rc_input_dev.keybit);
+ for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
+ set_bit(rc_keys[i], input_dev->keybit);
- input_register_device(&dec->rc_input_dev);
+ input_register_device(input_dev);
- if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
+ if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
printk("%s: usb_submit_urb failed\n",__FUNCTION__);
- }
+
/* enable irq pipe */
ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
+
+ return 0;
}
static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
@@ -1514,7 +1523,7 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
* As the irq is submitted after the interface is changed,
* this is the best method i figured out.
* Any others?*/
- if(dec->interface == TTUSB_DEC_INTERFACE_IN)
+ if (dec->interface == TTUSB_DEC_INTERFACE_IN)
usb_kill_urb(dec->irq_urb);
usb_free_urb(dec->irq_urb);
@@ -1522,7 +1531,10 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
dec->irq_buffer, dec->irq_dma_handle);
- input_unregister_device(&dec->rc_input_dev);
+ if (dec->rc_input_dev) {
+ input_unregister_device(dec->rc_input_dev);
+ dec->rc_input_dev = NULL;
+ }
}
@@ -1660,7 +1672,7 @@ static int ttusb_dec_probe(struct usb_interface *intf,
ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
- if(enable_rc)
+ if (enable_rc)
ttusb_init_rc(dec);
return 0;