#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>
        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);
 
 int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
                 int (*func)(struct file *file, unsigned int cmd, void *arg));
 
-/** generic DVB attach function. */
+#ifdef CONFIG_I2C
+
+struct i2c_adapter;
+struct i2c_client;
+/**
+ * dvb_module_probe - helper routine to probe an I2C module
+ *
+ * @module_name:
+ *     Name of the I2C module to be probed
+ * @name:
+ *     Optional name for the I2C module. Used for debug purposes.
+ *     If %NULL, defaults to @module_name.
+ * @adap:
+ *     pointer to &struct i2c_adapter that describes the I2C adapter where
+ *     the module will be bound.
+ * @addr:
+ *     I2C address of the adapter, in 7-bit notation.
+ * @platform_data:
+ *     Platform data to be passed to the I2C module probed.
+ *
+ * This function binds an I2C device into the DVB core. Should be used by
+ * all drivers that use I2C bus to control the hardware. A module bound
+ * with dvb_module_probe() should use dvb_module_release() to unbind.
+ *
+ * Return:
+ *     On success, return an &struct i2c_client, pointing the the bound
+ *     I2C device. %NULL otherwise.
+ *
+ * .. note::
+ *
+ *    In the past, DVB modules (mainly, frontends) were bound via dvb_attach()
+ *    macro, with does an ugly hack, using I2C low level functions. Such
+ *    usage is deprecated and will be removed soon. Instead, use this routine.
+ */
+struct i2c_client *dvb_module_probe(const char *module_name,
+                                   const char *name,
+                                   struct i2c_adapter *adap,
+                                   unsigned char addr,
+                                   void *platform_data);
+
+/**
+ * dvb_module_release - releases an I2C device allocated with
+ *      dvb_module_probe().
+ *
+ * @client: pointer to &struct i2c_client with the I2C client to be released.
+ *         can be %NULL.
+ *
+ * This function should be used to free all resources reserved by
+ * dvb_module_probe() and unbinding the I2C hardware.
+ */
+void dvb_module_release(struct i2c_client *client);
+
+#endif /* CONFIG_I2C */
+
+/* Legacy generic DVB attach function. */
 #ifdef CONFIG_MEDIA_ATTACH
 
 /**
  * the @FUNCTION function there, with @ARGS.
  * As it increments symbol usage cont, at unregister, dvb_detach()
  * should be called.
+ *
+ * .. note::
+ *
+ *    In the past, DVB modules (mainly, frontends) were bound via dvb_attach()
+ *    macro, with does an ugly hack, using I2C low level functions. Such
+ *    usage is deprecated and will be removed soon. Instead, you should use
+ *    dvb_module_probe().
  */
 #define dvb_attach(FUNCTION, ARGS...) ({ \
        void *__r = NULL; \
 
 #define dvb_detach(FUNC)       {}
 
-#endif
+#endif /* CONFIG_MEDIA_ATTACH */
 
 #endif /* #ifndef _DVBDEV_H_ */