This adds support for V4L2 clock and asynchronous subdevice probing.

Signed-off-by: Guennadi Liakhovetski <g.liakhovet...@gmx.de>
---
 drivers/media/i2c/mt9p031.c |   31 +++++++++++++++++++++++++++++--
 1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index e328332..9ba38f5 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -23,7 +23,9 @@
 #include <linux/videodev2.h>
 
 #include <media/mt9p031.h>
+#include <media/v4l2-async.h>
 #include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
@@ -117,6 +119,7 @@ struct mt9p031 {
        struct media_pad pad;
        struct v4l2_rect crop;  /* Sensor window */
        struct v4l2_mbus_framefmt format;
+       struct v4l2_clk *clk;
        struct mt9p031_platform_data *pdata;
        struct mutex power_lock; /* lock to protect power_count */
        int power_count;
@@ -258,6 +261,10 @@ static inline int mt9p031_pll_disable(struct mt9p031 
*mt9p031)
 
 static int mt9p031_power_on(struct mt9p031 *mt9p031)
 {
+       int ret = v4l2_clk_enable(mt9p031->clk);
+       if (ret < 0)
+               return ret;
+
        /* Ensure RESET_BAR is low */
        if (mt9p031->reset != -1) {
                gpio_set_value(mt9p031->reset, 0);
@@ -287,6 +294,8 @@ static void mt9p031_power_off(struct mt9p031 *mt9p031)
 
        if (mt9p031->pdata->set_xclk)
                mt9p031->pdata->set_xclk(&mt9p031->subdev, 0);
+
+       v4l2_clk_disable(mt9p031->clk);
 }
 
 static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
@@ -912,6 +921,7 @@ static int mt9p031_probe(struct i2c_client *client,
 {
        struct mt9p031_platform_data *pdata = client->dev.platform_data;
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+       struct v4l2_clk *clk;
        struct mt9p031 *mt9p031;
        unsigned int i;
        int ret;
@@ -927,11 +937,20 @@ static int mt9p031_probe(struct i2c_client *client,
                return -EIO;
        }
 
+       clk = v4l2_clk_get(&client->dev, "mclk");
+       if (IS_ERR(clk)) {
+               dev_info(&client->dev, "Error %ld getting clock\n", 
PTR_ERR(clk));
+               return -EPROBE_DEFER;
+       }
+
        mt9p031 = kzalloc(sizeof(*mt9p031), GFP_KERNEL);
-       if (mt9p031 == NULL)
-               return -ENOMEM;
+       if (mt9p031 == NULL) {
+               ret = -ENOMEM;
+               goto done;
+       }
 
        mt9p031->pdata = pdata;
+       mt9p031->clk = clk;
        mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
        mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
        mt9p031->model = did->driver_data;
@@ -1010,6 +1029,11 @@ static int mt9p031_probe(struct i2c_client *client,
        }
 
        ret = mt9p031_pll_setup(mt9p031);
+       if (ret < 0)
+               goto done;
+
+       mt9p031->subdev.dev = &client->dev;
+       ret = v4l2_async_register_subdev(&mt9p031->subdev);
 
 done:
        if (ret < 0) {
@@ -1019,6 +1043,7 @@ done:
                v4l2_ctrl_handler_free(&mt9p031->ctrls);
                media_entity_cleanup(&mt9p031->subdev.entity);
                kfree(mt9p031);
+               v4l2_clk_put(clk);
        }
 
        return ret;
@@ -1029,11 +1054,13 @@ static int mt9p031_remove(struct i2c_client *client)
        struct v4l2_subdev *subdev = i2c_get_clientdata(client);
        struct mt9p031 *mt9p031 = to_mt9p031(subdev);
 
+       v4l2_async_unregister_subdev(subdev);
        v4l2_ctrl_handler_free(&mt9p031->ctrls);
        v4l2_device_unregister_subdev(subdev);
        media_entity_cleanup(&subdev->entity);
        if (mt9p031->reset != -1)
                gpio_free(mt9p031->reset);
+       v4l2_clk_put(mt9p031->clk);
        kfree(mt9p031);
 
        return 0;
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to