summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/dibusb
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/dvb/dibusb')
-rw-r--r--linux/drivers/media/dvb/dibusb/Kconfig1
-rw-r--r--linux/drivers/media/dvb/dibusb/Makefile2
-rw-r--r--linux/drivers/media/dvb/dibusb/dvb-dibusb.c69
-rw-r--r--linux/drivers/media/dvb/dibusb/dvb-dibusb.h1
4 files changed, 58 insertions, 15 deletions
diff --git a/linux/drivers/media/dvb/dibusb/Kconfig b/linux/drivers/media/dvb/dibusb/Kconfig
index f4eb6566e..afe683681 100644
--- a/linux/drivers/media/dvb/dibusb/Kconfig
+++ b/linux/drivers/media/dvb/dibusb/Kconfig
@@ -2,6 +2,7 @@ config DVB_DIBUSB
tristate "DiBcom/Twinhan/KWorld/Hama/Artec/Compro USB DVB-T devices"
depends on DVB_CORE && USB
select FW_LOADER
+ select DVB_DIB3000MB
help
Support for USB 1.1 DVB-T devices based on a reference design made by
DiBcom (http://www.dibcom.fr).
diff --git a/linux/drivers/media/dvb/dibusb/Makefile b/linux/drivers/media/dvb/dibusb/Makefile
index 72cd6a241..ab990cd3b 100644
--- a/linux/drivers/media/dvb/dibusb/Makefile
+++ b/linux/drivers/media/dvb/dibusb/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
-EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb.c b/linux/drivers/media/dvb/dibusb/dvb-dibusb.c
index f6854f443..88092509c 100644
--- a/linux/drivers/media/dvb/dibusb/dvb-dibusb.c
+++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb.c
@@ -36,9 +36,11 @@
#include "dvb_filter.h"
#include "dvb_net.h"
#include "dvb_frontend.h"
+#include "dib3000mb.h"
#include "dvb-dibusb.h"
+
/* debug */
#ifdef CONFIG_DVB_DIBCOM_DEBUG
@@ -394,22 +396,40 @@ static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
return I2C_FUNC_I2C;
}
-static int dibusb_i2c_client_register (struct i2c_client *i2c)
+static int thomson_cable_eu_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
- struct usb_dibusb *dib = i2c_get_adapdata(i2c->adapter);
- if (i2c->driver->command)
- return i2c->driver->command(i2c,FE_REGISTER,dib->adapter);
- return 0;
-}
+ struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
+ u8 buf[4];
+ struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
+ u32 tfreq = (params->frequency + 36125000) / 62500;
+ int vu,p0,p1,p2;
+
+ if (params->frequency > 403250000)
+ vu = 1, p2 = 1, p1 = 0, p0 = 1;
+ else if (params->frequency > 115750000)
+ vu = 0, p2 = 1, p1 = 1, p0 = 0;
+ else if (params->frequency > 44250000)
+ vu = 0, p2 = 0, p1 = 1, p0 = 1;
+ else
+ return -EINVAL;
-static int dibusb_i2c_client_unregister (struct i2c_client *i2c)
-{
- struct usb_dibusb *dib = i2c_get_adapdata(i2c->adapter);
- if (i2c->driver->command)
- return i2c->driver->command(i2c,FE_UNREGISTER,dib->adapter);
+ buf[0] = (tfreq >> 8) & 0x7f;
+ buf[1] = tfreq & 0xff;
+ buf[2] = 0x8e;
+ buf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
+
+ if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1) return -EIO;
+
+ msleep(1);
return 0;
}
+static struct dib3000mb_config thomson_cable_eu_config = {
+ .demod_address = 0x10,
+ .pll_addr = 0x61,
+ .pll_set = thomson_cable_eu_pll_set,
+};
+
static struct i2c_algorithm dibusb_algo = {
.name = "DiBcom USB i2c algorithm",
.id = I2C_ALGO_BIT,
@@ -417,6 +437,25 @@ static struct i2c_algorithm dibusb_algo = {
.functionality = dibusb_i2c_func,
};
+static void frontend_init(struct usb_dibusb* dib)
+{
+ dib->fe = dib3000mb_attach(&thomson_cable_eu_config, &dib->i2c_adap);
+
+ if (dib->fe == NULL) {
+ printk("dvb-dibusb: A frontend driver was not found for device %04x/%04x\n",
+ dib->udev->descriptor.idVendor,
+ dib->udev->descriptor.idProduct);
+ } else {
+ if (dvb_register_frontend(dib->adapter, dib->fe)) {
+ printk("dvb-dibusb: Frontend registration failed!\n");
+ if (dib->fe->ops->release)
+ dib->fe->ops->release(dib->fe);
+ dib->fe = NULL;
+ }
+ }
+}
+
+
static int dibusb_dvb_init(struct usb_dibusb *dib)
{
int ret;
@@ -430,6 +469,7 @@ static int dibusb_dvb_init(struct usb_dibusb *dib)
deb_info("dvb_register_adapter failed: error %d", ret);
goto err;
}
+ dib->adapter->priv = dib;
strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
@@ -440,8 +480,6 @@ static int dibusb_dvb_init(struct usb_dibusb *dib)
dib->i2c_adap.algo = &dibusb_algo;
dib->i2c_adap.algo_data = NULL;
dib->i2c_adap.id = I2C_ALGO_BIT;
- dib->i2c_adap.client_register = dibusb_i2c_client_register,
- dib->i2c_adap.client_unregister = dibusb_i2c_client_unregister,
i2c_set_adapdata(&dib->i2c_adap, dib);
@@ -472,7 +510,9 @@ static int dibusb_dvb_init(struct usb_dibusb *dib)
}
dvb_net_init(dib->adapter, &dib->dvb_net, &dib->demux.dmx);
-
+
+ frontend_init(dib);
+
goto success;
err_dmx_dev:
dvb_dmx_release(&dib->demux);
@@ -495,6 +535,7 @@ static int dibusb_dvb_exit(struct usb_dibusb *dib)
dib->demux.dmx.close(&dib->demux.dmx);
dvb_dmxdev_release(&dib->dmxdev);
dvb_dmx_release(&dib->demux);
+ if (dib->fe != NULL) dvb_unregister_frontend(dib->fe);
i2c_del_adapter(&dib->i2c_adap);
dvb_unregister_adapter(dib->adapter);
diff --git a/linux/drivers/media/dvb/dibusb/dvb-dibusb.h b/linux/drivers/media/dvb/dibusb/dvb-dibusb.h
index 4d33dc469..b2b12a774 100644
--- a/linux/drivers/media/dvb/dibusb/dvb-dibusb.h
+++ b/linux/drivers/media/dvb/dibusb/dvb-dibusb.h
@@ -164,6 +164,7 @@ struct usb_dibusb {
struct dmxdev dmxdev;
struct dvb_demux demux;
struct dvb_net dvb_net;
+ struct dvb_frontend* fe;
};
#define COMMAND_PIPE usb_sndbulkpipe(dib->udev, 0x01)