aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/cx231xx/cx231xx-dvb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/usb/cx231xx/cx231xx-dvb.c')
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c382
1 files changed, 103 insertions, 279 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index 67ed66712d05..89357cb08b1a 100644
--- a/drivers/media/usb/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c
@@ -23,8 +23,12 @@
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
#include <media/v4l2-common.h>
-#include <media/videobuf-vmalloc.h>
#include <media/tuner.h>
#include "xc5000.h"
@@ -156,10 +160,8 @@ static struct tda18271_config pv_tda18271_config = {
};
static struct lgdt3306a_config hauppauge_955q_lgdt3306a_config = {
- .i2c_addr = 0x59,
.qam_if_khz = 4000,
.vsb_if_khz = 3250,
- .deny_i2c_rptr = 1,
.spectral_inversion = 1,
.mpeg_mode = LGDT3306A_MPEG_SERIAL,
.tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE,
@@ -600,7 +602,6 @@ fail_adapter:
static void unregister_dvb(struct cx231xx_dvb *dvb)
{
- struct i2c_client *client;
dvb_net_release(&dvb->net);
dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
@@ -613,23 +614,15 @@ static void unregister_dvb(struct cx231xx_dvb *dvb)
dvb_frontend_detach(dvb->frontend[1]);
dvb_frontend_detach(dvb->frontend[0]);
dvb_unregister_adapter(&dvb->adapter);
+
/* remove I2C tuner */
- client = dvb->i2c_client_tuner;
- if (client) {
- module_put(client->dev.driver->owner);
- i2c_unregister_device(client);
- }
- /* remove I2C demod */
- client = dvb->i2c_client_demod[1];
- if (client) {
- module_put(client->dev.driver->owner);
- i2c_unregister_device(client);
- }
- client = dvb->i2c_client_demod[0];
- if (client) {
- module_put(client->dev.driver->owner);
- i2c_unregister_device(client);
- }
+ dvb_module_release(dvb->i2c_client_tuner);
+ dvb->i2c_client_tuner = NULL;
+ /* remove I2C demod(s) */
+ dvb_module_release(dvb->i2c_client_demod[1]);
+ dvb->i2c_client_demod[1] = NULL;
+ dvb_module_release(dvb->i2c_client_demod[0]);
+ dvb->i2c_client_demod[0] = NULL;
}
static int dvb_init(struct cx231xx *dev)
@@ -638,6 +631,8 @@ static int dvb_init(struct cx231xx *dev)
struct cx231xx_dvb *dvb;
struct i2c_adapter *tuner_i2c;
struct i2c_adapter *demod_i2c;
+ struct i2c_client *client;
+ struct i2c_adapter *adapter;
if (!dev->board.has_dvb) {
/* This device does not support the extension */
@@ -728,7 +723,7 @@ static int dvb_init(struct cx231xx *dev)
dvb->frontend[0]->callback = cx231xx_tuner_callback;
if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0],
- 0x60, tuner_i2c,
+ dev->board.tuner_addr, tuner_i2c,
&cnxt_rde253s_tunerconfig)) {
result = -EINVAL;
goto out_free;
@@ -752,7 +747,7 @@ static int dvb_init(struct cx231xx *dev)
dvb->frontend[0]->callback = cx231xx_tuner_callback;
if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0],
- 0x60, tuner_i2c,
+ dev->board.tuner_addr, tuner_i2c,
&cnxt_rde253s_tunerconfig)) {
result = -EINVAL;
goto out_free;
@@ -779,41 +774,27 @@ static int dvb_init(struct cx231xx *dev)
dvb->frontend[0]->callback = cx231xx_tuner_callback;
dvb_attach(tda18271_attach, dev->dvb->frontend[0],
- 0x60, tuner_i2c,
+ dev->board.tuner_addr, tuner_i2c,
&hcw_tda18271_config);
break;
case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
{
- struct i2c_client *client;
- struct i2c_board_info info;
- struct si2165_platform_data si2165_pdata;
+ struct si2165_platform_data si2165_pdata = {};
/* attach demod */
- memset(&si2165_pdata, 0, sizeof(si2165_pdata));
si2165_pdata.fe = &dev->dvb->frontend[0];
si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
si2165_pdata.ref_freq_hz = 16000000;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "si2165", I2C_NAME_SIZE);
- info.addr = 0x64;
- info.platform_data = &si2165_pdata;
- request_module(info.type);
- client = i2c_new_device(demod_i2c, &info);
- if (!client || !client->dev.driver || !dev->dvb->frontend[0]) {
- dev_err(dev->dev,
- "Failed to attach SI2165 front end\n");
- result = -EINVAL;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2165", NULL, demod_i2c,
+ dev->board.demod_addr,
+ &si2165_pdata);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dvb->i2c_client_demod[0] = client;
dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
@@ -822,8 +803,7 @@ static int dvb_init(struct cx231xx *dev)
dvb->frontend[0]->callback = cx231xx_tuner_callback;
dvb_attach(tda18271_attach, dev->dvb->frontend[0],
- 0x60,
- tuner_i2c,
+ dev->board.tuner_addr, tuner_i2c,
&hcw_tda18271_config);
dev->cx231xx_reset_analog_tuner = NULL;
@@ -831,74 +811,45 @@ static int dvb_init(struct cx231xx *dev)
}
case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx:
{
- struct i2c_client *client;
- struct i2c_board_info info;
- struct si2165_platform_data si2165_pdata;
- struct si2157_config si2157_config;
+ struct si2165_platform_data si2165_pdata = {};
+ struct si2157_config si2157_config = {};
/* attach demod */
- memset(&si2165_pdata, 0, sizeof(si2165_pdata));
si2165_pdata.fe = &dev->dvb->frontend[0];
si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT;
si2165_pdata.ref_freq_hz = 24000000;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "si2165", I2C_NAME_SIZE);
- info.addr = 0x64;
- info.platform_data = &si2165_pdata;
- request_module(info.type);
- client = i2c_new_device(demod_i2c, &info);
- if (!client || !client->dev.driver || !dev->dvb->frontend[0]) {
- dev_err(dev->dev,
- "Failed to attach SI2165 front end\n");
- result = -EINVAL;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2165", NULL, demod_i2c,
+ dev->board.demod_addr,
+ &si2165_pdata);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dvb->i2c_client_demod[0] = client;
- memset(&info, 0, sizeof(struct i2c_board_info));
-
dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
/* define general-purpose callback pointer */
dvb->frontend[0]->callback = cx231xx_tuner_callback;
/* attach tuner */
- memset(&si2157_config, 0, sizeof(si2157_config));
si2157_config.fe = dev->dvb->frontend[0];
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
si2157_config.mdev = dev->media_dev;
#endif
si2157_config.if_port = 1;
si2157_config.inversion = true;
- strlcpy(info.type, "si2157", I2C_NAME_SIZE);
- info.addr = 0x60;
- info.platform_data = &si2157_config;
- request_module("si2157");
-
- client = i2c_new_device(
- tuner_i2c,
- &info);
- if (client == NULL || client->dev.driver == NULL) {
- dvb_frontend_detach(dev->dvb->frontend[0]);
- result = -ENODEV;
- goto out_free;
- }
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
- dvb_frontend_detach(dev->dvb->frontend[0]);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2157", NULL, tuner_i2c,
+ dev->board.tuner_addr,
+ &si2157_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dev->cx231xx_reset_analog_tuner = NULL;
dev->dvb->i2c_client_tuner = client;
@@ -906,23 +857,22 @@ static int dvb_init(struct cx231xx *dev)
}
case CX231XX_BOARD_HAUPPAUGE_955Q:
{
- struct i2c_client *client;
- struct i2c_board_info info;
- struct si2157_config si2157_config;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
+ struct si2157_config si2157_config = {};
+ struct lgdt3306a_config lgdt3306a_config = {};
- dev->dvb->frontend[0] = dvb_attach(lgdt3306a_attach,
- &hauppauge_955q_lgdt3306a_config,
- demod_i2c
- );
+ lgdt3306a_config = hauppauge_955q_lgdt3306a_config;
+ lgdt3306a_config.fe = &dev->dvb->frontend[0];
+ lgdt3306a_config.i2c_adapter = &adapter;
- if (!dev->dvb->frontend[0]) {
- dev_err(dev->dev,
- "Failed to attach LGDT3306A frontend.\n");
- result = -EINVAL;
+ /* perform probe/init/attach */
+ client = dvb_module_probe("lgdt3306a", NULL, demod_i2c,
+ dev->board.demod_addr,
+ &lgdt3306a_config);
+ if (!client) {
+ result = -ENODEV;
goto out_free;
}
+ dvb->i2c_client_demod[0] = client;
dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
@@ -930,34 +880,21 @@ static int dvb_init(struct cx231xx *dev)
dvb->frontend[0]->callback = cx231xx_tuner_callback;
/* attach tuner */
- memset(&si2157_config, 0, sizeof(si2157_config));
si2157_config.fe = dev->dvb->frontend[0];
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
si2157_config.mdev = dev->media_dev;
#endif
si2157_config.if_port = 1;
si2157_config.inversion = true;
- strlcpy(info.type, "si2157", I2C_NAME_SIZE);
- info.addr = 0x60;
- info.platform_data = &si2157_config;
- request_module("si2157");
-
- client = i2c_new_device(
- tuner_i2c,
- &info);
- if (client == NULL || client->dev.driver == NULL) {
- dvb_frontend_detach(dev->dvb->frontend[0]);
- result = -ENODEV;
- goto out_free;
- }
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
- dvb_frontend_detach(dev->dvb->frontend[0]);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2157", NULL, tuner_i2c,
+ dev->board.tuner_addr,
+ &si2157_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dev->cx231xx_reset_analog_tuner = NULL;
dev->dvb->i2c_client_tuner = client;
@@ -985,7 +922,7 @@ static int dvb_init(struct cx231xx *dev)
dvb->frontend[0]->callback = cx231xx_tuner_callback;
dvb_attach(tda18271_attach, dev->dvb->frontend[0],
- 0x60, tuner_i2c,
+ dev->board.tuner_addr, tuner_i2c,
&pv_tda18271_config);
break;
@@ -993,9 +930,6 @@ static int dvb_init(struct cx231xx *dev)
{
struct si2157_config si2157_config = {};
struct si2168_config si2168_config = {};
- struct i2c_board_info info = {};
- struct i2c_client *client;
- struct i2c_adapter *adapter;
/* attach demodulator chip */
si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */
@@ -1003,24 +937,14 @@ static int dvb_init(struct cx231xx *dev)
si2168_config.i2c_adapter = &adapter;
si2168_config.ts_clock_inv = true;
- strlcpy(info.type, "si2168", sizeof(info.type));
- info.addr = dev->board.demod_addr;
- info.platform_data = &si2168_config;
-
- request_module(info.type);
- client = i2c_new_device(demod_i2c, &info);
-
- if (client == NULL || client->dev.driver == NULL) {
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2168", NULL, demod_i2c,
+ dev->board.demod_addr,
+ &si2168_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
- result = -ENODEV;
- goto out_free;
- }
-
dvb->i2c_client_demod[0] = client;
/* attach tuner chip */
@@ -1031,37 +955,20 @@ static int dvb_init(struct cx231xx *dev)
si2157_config.if_port = 1;
si2157_config.inversion = false;
- memset(&info, 0, sizeof(info));
- strlcpy(info.type, "si2157", sizeof(info.type));
- info.addr = dev->board.tuner_addr;
- info.platform_data = &si2157_config;
-
- request_module(info.type);
- client = i2c_new_device(tuner_i2c, &info);
-
- if (client == NULL || client->dev.driver == NULL) {
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
- result = -ENODEV;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2157", NULL, tuner_i2c,
+ dev->board.tuner_addr,
+ &si2157_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dev->cx231xx_reset_analog_tuner = NULL;
dev->dvb->i2c_client_tuner = client;
break;
}
case CX231XX_BOARD_ASTROMETA_T2HYBRID:
{
- struct i2c_client *client;
- struct i2c_board_info info = {};
struct mn88473_config mn88473_config = {};
/* attach demodulator chip */
@@ -1069,24 +976,14 @@ static int dvb_init(struct cx231xx *dev)
mn88473_config.xtal = 25000000;
mn88473_config.fe = &dev->dvb->frontend[0];
- strlcpy(info.type, "mn88473", sizeof(info.type));
- info.addr = dev->board.demod_addr;
- info.platform_data = &mn88473_config;
-
- request_module(info.type);
- client = i2c_new_device(demod_i2c, &info);
-
- if (client == NULL || client->dev.driver == NULL) {
- result = -ENODEV;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("mn88473", NULL, demod_i2c,
+ dev->board.demod_addr,
+ &mn88473_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dvb->i2c_client_demod[0] = client;
/* define general-purpose callback pointer */
@@ -1100,9 +997,6 @@ static int dvb_init(struct cx231xx *dev)
}
case CX231XX_BOARD_HAUPPAUGE_935C:
{
- struct i2c_client *client;
- struct i2c_adapter *adapter;
- struct i2c_board_info info = {};
struct si2157_config si2157_config = {};
struct si2168_config si2168_config = {};
@@ -1112,25 +1006,14 @@ static int dvb_init(struct cx231xx *dev)
si2168_config.i2c_adapter = &adapter;
si2168_config.ts_clock_inv = true;
- strlcpy(info.type, "si2168", sizeof(info.type));
- info.addr = dev->board.demod_addr;
- info.platform_data = &si2168_config;
-
- request_module(info.type);
- client = i2c_new_device(demod_i2c, &info);
- if (client == NULL || client->dev.driver == NULL) {
- result = -ENODEV;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- dev_err(dev->dev,
- "Failed to attach %s frontend.\n", info.type);
- i2c_unregister_device(client);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2168", NULL, demod_i2c,
+ dev->board.demod_addr,
+ &si2168_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dvb->i2c_client_demod[0] = client;
dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
@@ -1145,40 +1028,21 @@ static int dvb_init(struct cx231xx *dev)
si2157_config.if_port = 1;
si2157_config.inversion = true;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "si2157", I2C_NAME_SIZE);
- info.addr = dev->board.tuner_addr;
- info.platform_data = &si2157_config;
- request_module("si2157");
-
- client = i2c_new_device(adapter, &info);
- if (client == NULL || client->dev.driver == NULL) {
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
- result = -ENODEV;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- dev_err(dev->dev,
- "Failed to obtain %s tuner.\n", info.type);
- i2c_unregister_device(client);
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2157", NULL, tuner_i2c,
+ dev->board.tuner_addr,
+ &si2157_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dev->cx231xx_reset_analog_tuner = NULL;
dev->dvb->i2c_client_tuner = client;
break;
}
case CX231XX_BOARD_HAUPPAUGE_975:
{
- struct i2c_client *client;
- struct i2c_adapter *adapter;
struct i2c_adapter *adapter2;
- struct i2c_board_info info = {};
struct si2157_config si2157_config = {};
struct lgdt3306a_config lgdt3306a_config = {};
struct si2168_config si2168_config = {};
@@ -1187,27 +1051,15 @@ static int dvb_init(struct cx231xx *dev)
lgdt3306a_config = hauppauge_955q_lgdt3306a_config;
lgdt3306a_config.fe = &dev->dvb->frontend[0];
lgdt3306a_config.i2c_adapter = &adapter;
- lgdt3306a_config.deny_i2c_rptr = 0;
-
- strlcpy(info.type, "lgdt3306a", sizeof(info.type));
- info.addr = dev->board.demod_addr;
- info.platform_data = &lgdt3306a_config;
-
- request_module(info.type);
- client = i2c_new_device(demod_i2c, &info);
- if (client == NULL || client->dev.driver == NULL) {
- result = -ENODEV;
- goto out_free;
- }
- if (!try_module_get(client->dev.driver->owner)) {
- dev_err(dev->dev,
- "Failed to attach %s frontend.\n", info.type);
- i2c_unregister_device(client);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("lgdt3306a", NULL, demod_i2c,
+ dev->board.demod_addr,
+ &lgdt3306a_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dvb->i2c_client_demod[0] = client;
/* attach second demodulator chip */
@@ -1216,30 +1068,14 @@ static int dvb_init(struct cx231xx *dev)
si2168_config.i2c_adapter = &adapter2;
si2168_config.ts_clock_inv = true;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "si2168", sizeof(info.type));
- info.addr = dev->board.demod_addr2;
- info.platform_data = &si2168_config;
-
- request_module(info.type);
- client = i2c_new_device(adapter, &info);
- if (client == NULL || client->dev.driver == NULL) {
- dev_err(dev->dev,
- "Failed to attach %s frontend.\n", info.type);
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
- result = -ENODEV;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- i2c_unregister_device(client);
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2168", NULL, adapter,
+ dev->board.demod_addr2,
+ &si2168_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dvb->i2c_client_demod[1] = client;
dvb->frontend[1]->id = 1;
@@ -1255,34 +1091,14 @@ static int dvb_init(struct cx231xx *dev)
si2157_config.if_port = 1;
si2157_config.inversion = true;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "si2157", I2C_NAME_SIZE);
- info.addr = dev->board.tuner_addr;
- info.platform_data = &si2157_config;
- request_module("si2157");
-
- client = i2c_new_device(adapter, &info);
- if (client == NULL || client->dev.driver == NULL) {
- module_put(dvb->i2c_client_demod[1]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[1]);
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
- result = -ENODEV;
- goto out_free;
- }
-
- if (!try_module_get(client->dev.driver->owner)) {
- dev_err(dev->dev,
- "Failed to obtain %s tuner.\n", info.type);
- i2c_unregister_device(client);
- module_put(dvb->i2c_client_demod[1]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[1]);
- module_put(dvb->i2c_client_demod[0]->dev.driver->owner);
- i2c_unregister_device(dvb->i2c_client_demod[0]);
+ /* perform probe/init/attach */
+ client = dvb_module_probe("si2157", NULL, adapter,
+ dev->board.tuner_addr,
+ &si2157_config);
+ if (!client) {
result = -ENODEV;
goto out_free;
}
-
dev->cx231xx_reset_analog_tuner = NULL;
dvb->i2c_client_tuner = client;
@@ -1321,6 +1137,14 @@ ret:
return result;
out_free:
+ /* remove I2C tuner */
+ dvb_module_release(dvb->i2c_client_tuner);
+ dvb->i2c_client_tuner = NULL;
+ /* remove I2C demod(s) */
+ dvb_module_release(dvb->i2c_client_demod[1]);
+ dvb->i2c_client_demod[1] = NULL;
+ dvb_module_release(dvb->i2c_client_demod[0]);
+ dvb->i2c_client_demod[0] = NULL;
kfree(dvb);
dev->dvb = NULL;
goto ret;