aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-core/dvbdev.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2018-03-02 10:21:16 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2018-03-06 05:00:31 -0500
commit8f569c0b4e6b6bd5db1d09551b2df87d912f124e (patch)
treef8311565f09f55db349bf9937e46cb9f6ff56c68 /drivers/media/dvb-core/dvbdev.c
parentmedia: em28xx: split up em28xx_dvb_init to reduce stack size (diff)
downloadlinux-dev-8f569c0b4e6b6bd5db1d09551b2df87d912f124e.tar.xz
linux-dev-8f569c0b4e6b6bd5db1d09551b2df87d912f124e.zip
media: dvb-core: add helper functions for I2C binding
The dvb_attach()/dvb_detach() methods are ugly hacks designed to keep using the I2C low-level API. The proper way is to do I2C bus bindings instead. Several modules were already converted to use it. Yet, it is painful to use it, as lots of code need to be duplicated. Make it easier by providing two new helper functions: - dvb_module_probe() - dvb_module_release() Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/dvb-core/dvbdev.c')
-rw-r--r--drivers/media/dvb-core/dvbdev.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 60e9c2ba26be..a840133feacb 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -24,6 +24,7 @@
#include <linux/string.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
@@ -941,6 +942,53 @@ out:
return err;
}
+#ifdef CONFIG_I2C
+struct i2c_client *dvb_module_probe(const char *module_name,
+ const char *name,
+ struct i2c_adapter *adap,
+ unsigned char addr,
+ void *platform_data)
+{
+ struct i2c_client *client;
+ struct i2c_board_info *board_info;
+
+ board_info = kzalloc(sizeof(*board_info), GFP_KERNEL);
+
+ if (name)
+ strlcpy(board_info->type, name, I2C_NAME_SIZE);
+ else
+ strlcpy(board_info->type, module_name, I2C_NAME_SIZE);
+
+ board_info->addr = addr;
+ board_info->platform_data = platform_data;
+ request_module(module_name);
+ client = i2c_new_device(adap, board_info);
+ if (client == NULL || client->dev.driver == NULL) {
+ kfree(board_info);
+ return NULL;
+ }
+
+ if (!try_module_get(client->dev.driver->owner)) {
+ i2c_unregister_device(client);
+ client = NULL;
+ }
+
+ kfree(board_info);
+ return client;
+}
+EXPORT_SYMBOL_GPL(dvb_module_probe);
+
+void dvb_module_release(struct i2c_client *client)
+{
+ if (!client)
+ return;
+
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+}
+EXPORT_SYMBOL_GPL(dvb_module_release);
+#endif
+
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct dvb_device *dvbdev = dev_get_drvdata(dev);