diff options
Diffstat (limited to 'drivers/media/pci/ddbridge')
-rw-r--r-- | drivers/media/pci/ddbridge/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/pci/ddbridge/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/pci/ddbridge/ddbridge-ci.c | 53 | ||||
-rw-r--r-- | drivers/media/pci/ddbridge/ddbridge-core.c | 36 | ||||
-rw-r--r-- | drivers/media/pci/ddbridge/ddbridge.h | 1 |
5 files changed, 50 insertions, 44 deletions
diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index f43d0b83fc0c..a422dde2f34a 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig @@ -13,6 +13,7 @@ config DVB_DDBRIDGE select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT + select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT ---help--- Support for cards with the Digital Devices PCI express bridge: - Octopus PCIe Bridge diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index f58fdec50eab..745b37d07558 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile @@ -10,6 +10,3 @@ obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o ccflags-y += -Idrivers/media/dvb-frontends/ ccflags-y += -Idrivers/media/tuners/ - -# For the staging CI driver cxd2099 -ccflags-y += -Idrivers/staging/media/cxd2099/ diff --git a/drivers/media/pci/ddbridge/ddbridge-ci.c b/drivers/media/pci/ddbridge/ddbridge-ci.c index 5828111487b0..a9dbc4ebf94f 100644 --- a/drivers/media/pci/ddbridge/ddbridge-ci.c +++ b/drivers/media/pci/ddbridge/ddbridge-ci.c @@ -172,6 +172,7 @@ static void ci_attach(struct ddb_port *port) memcpy(&ci->en, &en_templ, sizeof(en_templ)); ci->en.data = ci; port->en = &ci->en; + port->en_freedata = 1; ci->port = port; ci->nr = port->nr - 2; } @@ -304,6 +305,7 @@ static void ci_xo2_attach(struct ddb_port *port) memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ)); ci->en.data = ci; port->en = &ci->en; + port->en_freedata = 1; ci->port = port; ci->nr = port->nr - 2; ci->port->creg = 0; @@ -311,38 +313,58 @@ static void ci_xo2_attach(struct ddb_port *port) write_creg(ci, 0x08, 0x08); } -static struct cxd2099_cfg cxd_cfg = { +static const struct cxd2099_cfg cxd_cfgtmpl = { .bitrate = 72000, - .adr = 0x40, .polarity = 1, .clock_mode = 1, .max_i2c = 512, }; +static int ci_cxd2099_attach(struct ddb_port *port, u32 bitrate) +{ + struct cxd2099_cfg cxd_cfg = cxd_cfgtmpl; + struct i2c_client *client; + + cxd_cfg.bitrate = bitrate; + cxd_cfg.en = &port->en; + + client = dvb_module_probe("cxd2099", NULL, &port->i2c->adap, + 0x40, &cxd_cfg); + if (!client) + goto err; + + port->dvb[0].i2c_client[0] = client; + port->en_freedata = 0; + return 0; + +err: + dev_err(port->dev->dev, "CXD2099AR attach failed\n"); + return -ENODEV; +} + int ddb_ci_attach(struct ddb_port *port, u32 bitrate) { + int ret; + switch (port->type) { case DDB_CI_EXTERNAL_SONY: - cxd_cfg.bitrate = bitrate; - port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); - if (!port->en) + ret = ci_cxd2099_attach(port, bitrate); + if (ret) return -ENODEV; break; - case DDB_CI_EXTERNAL_XO2: case DDB_CI_EXTERNAL_XO2_B: ci_xo2_attach(port); - if (!port->en) - return -ENODEV; break; - case DDB_CI_INTERNAL: ci_attach(port); - if (!port->en) - return -ENODEV; break; + default: + return -ENODEV; } + if (!port->en) + return -ENODEV; dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1); return 0; } @@ -353,7 +375,14 @@ void ddb_ci_detach(struct ddb_port *port) dvb_unregister_device(port->dvb[0].dev); if (port->en) { dvb_ca_en50221_release(port->en); - kfree(port->en->data); + + dvb_module_release(port->dvb[0].i2c_client[0]); + port->dvb[0].i2c_client[0] = NULL; + + /* free alloc'ed memory if needed */ + if (port->en_freedata) + kfree(port->en->data); + port->en = NULL; } } diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index f9bee36f1cad..90687eff5909 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -999,37 +999,21 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype) .if_dvbt2_8 = 4000, .if_dvbc = 5000, }; - struct i2c_board_info board_info = { - .type = "tda18212", - .platform_data = &config, - }; - - if (input->nr & 1) - board_info.addr = 0x63; - else - board_info.addr = 0x60; + u8 addr = (input->nr & 1) ? 0x63 : 0x60; /* due to a hardware quirk with the I2C gate on the stv0367+tda18212 * combo, the tda18212 must be probed by reading it's id _twice_ when * cold started, or it very likely will fail. */ if (porttype == DDB_TUNER_DVBCT_ST) - tuner_tda18212_ping(input, board_info.addr); - - request_module(board_info.type); - - /* perform tuner init/attach */ - client = i2c_new_device(adapter, &board_info); - if (!client || !client->dev.driver) - goto err; + tuner_tda18212_ping(input, addr); - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); + /* perform tuner probe/init/attach */ + client = dvb_module_probe("tda18212", NULL, adapter, addr, &config); + if (!client) goto err; - } dvb->i2c_client[0] = client; - return 0; err: dev_err(dev, "TDA18212 tuner not found. Device is not fully operational.\n"); @@ -1253,7 +1237,6 @@ static void dvb_input_detach(struct ddb_input *input) { struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; struct dvb_demux *dvbdemux = &dvb->demux; - struct i2c_client *client; switch (dvb->attached) { case 0x31: @@ -1263,13 +1246,8 @@ static void dvb_input_detach(struct ddb_input *input) dvb_unregister_frontend(dvb->fe); /* fallthrough */ case 0x30: - client = dvb->i2c_client[0]; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - dvb->i2c_client[0] = NULL; - client = NULL; - } + dvb_module_release(dvb->i2c_client[0]); + dvb->i2c_client[0] = NULL; if (dvb->fe2) dvb_frontend_detach(dvb->fe2); diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 095457737bc1..f223dc6c9963 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -276,6 +276,7 @@ struct ddb_port { struct ddb_input *input[2]; struct ddb_output *output; struct dvb_ca_en50221 *en; + u8 en_freedata; struct ddb_dvb dvb[2]; u32 gap; u32 obr; |