diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-07-18 10:54:04 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 17:04:42 -0300 |
commit | 4bbc6d52e61a8a9c19fcc859c4acab89cb8cd4e5 (patch) | |
tree | 64ce43072ed8fa87bd8f5bc4d8fe5794a0373aef /drivers/media/i2c/soc_camera/mt9m111.c | |
parent | 4ec10bacd6bf08de39ebdba9e75060452cc313e0 (diff) | |
download | blackbird-op-linux-4bbc6d52e61a8a9c19fcc859c4acab89cb8cd4e5.tar.gz blackbird-op-linux-4bbc6d52e61a8a9c19fcc859c4acab89cb8cd4e5.zip |
[media] soc-camera: Push probe-time power management to drivers
Several client drivers access the hardware at probe time, for instance
to read the probe chip ID. Such chips need to be powered up when being
probed.
soc-camera handles this by powering chips up in the soc-camera probe
implementation. However, this will break with non soc-camera hosts that
don't perform the same operations.
Fix the problem by pushing the power up/down from the soc-camera core
down to individual drivers on a needs basis.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c/soc_camera/mt9m111.c')
-rw-r--r-- | drivers/media/i2c/soc_camera/mt9m111.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index e555f7739691..938c5c390eec 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c @@ -796,41 +796,6 @@ static int mt9m111_init(struct mt9m111 *mt9m111) return ret; } -/* - * Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one - */ -static int mt9m111_video_probe(struct i2c_client *client) -{ - struct mt9m111 *mt9m111 = to_mt9m111(client); - s32 data; - int ret; - - data = reg_read(CHIP_VERSION); - - switch (data) { - case 0x143a: /* MT9M111 or MT9M131 */ - mt9m111->model = V4L2_IDENT_MT9M111; - dev_info(&client->dev, - "Detected a MT9M111/MT9M131 chip ID %x\n", data); - break; - case 0x148c: /* MT9M112 */ - mt9m111->model = V4L2_IDENT_MT9M112; - dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data); - break; - default: - dev_err(&client->dev, - "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n", - data); - return -ENODEV; - } - - ret = mt9m111_init(mt9m111); - if (ret) - return ret; - return v4l2_ctrl_handler_setup(&mt9m111->hdl); -} - static int mt9m111_power_on(struct mt9m111 *mt9m111) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); @@ -941,6 +906,51 @@ static struct v4l2_subdev_ops mt9m111_subdev_ops = { .video = &mt9m111_subdev_video_ops, }; +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ +static int mt9m111_video_probe(struct i2c_client *client) +{ + struct mt9m111 *mt9m111 = to_mt9m111(client); + s32 data; + int ret; + + ret = mt9m111_s_power(&mt9m111->subdev, 1); + if (ret < 0) + return ret; + + data = reg_read(CHIP_VERSION); + + switch (data) { + case 0x143a: /* MT9M111 or MT9M131 */ + mt9m111->model = V4L2_IDENT_MT9M111; + dev_info(&client->dev, + "Detected a MT9M111/MT9M131 chip ID %x\n", data); + break; + case 0x148c: /* MT9M112 */ + mt9m111->model = V4L2_IDENT_MT9M112; + dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data); + break; + default: + dev_err(&client->dev, + "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n", + data); + ret = -ENODEV; + goto done; + } + + ret = mt9m111_init(mt9m111); + if (ret) + goto done; + + ret = v4l2_ctrl_handler_setup(&mt9m111->hdl); + +done: + mt9m111_s_power(&mt9m111->subdev, 0); + return ret; +} + static int mt9m111_probe(struct i2c_client *client, const struct i2c_device_id *did) { |