diff options
Diffstat (limited to 'linux/drivers/media/dvb/dibusb')
-rw-r--r-- | linux/drivers/media/dvb/dibusb/Kconfig | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/Makefile | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb.c | 69 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dibusb/dvb-dibusb.h | 1 |
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) |