aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9m001.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mt9m001.c')
-rw-r--r--drivers/media/video/mt9m001.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 554d2295484e..0c524376b67e 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -117,24 +117,51 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg,
117 117
118static int mt9m001_init(struct soc_camera_device *icd) 118static int mt9m001_init(struct soc_camera_device *icd)
119{ 119{
120 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
121 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
120 int ret; 122 int ret;
121 123
122 /* Disable chip, synchronous option update */
123 dev_dbg(icd->vdev->parent, "%s\n", __func__); 124 dev_dbg(icd->vdev->parent, "%s\n", __func__);
124 125
125 ret = reg_write(icd, MT9M001_RESET, 1); 126 if (icl->power) {
126 if (ret >= 0) 127 ret = icl->power(&mt9m001->client->dev, 1);
127 ret = reg_write(icd, MT9M001_RESET, 0); 128 if (ret < 0) {
128 if (ret >= 0) 129 dev_err(icd->vdev->parent,
130 "Platform failed to power-on the camera.\n");
131 return ret;
132 }
133 }
134
135 /* The camera could have been already on, we reset it additionally */
136 if (icl->reset)
137 ret = icl->reset(&mt9m001->client->dev);
138 else
139 ret = -ENODEV;
140
141 if (ret < 0) {
142 /* Either no platform reset, or platform reset failed */
143 ret = reg_write(icd, MT9M001_RESET, 1);
144 if (!ret)
145 ret = reg_write(icd, MT9M001_RESET, 0);
146 }
147 /* Disable chip, synchronous option update */
148 if (!ret)
129 ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); 149 ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
130 150
131 return ret >= 0 ? 0 : -EIO; 151 return ret;
132} 152}
133 153
134static int mt9m001_release(struct soc_camera_device *icd) 154static int mt9m001_release(struct soc_camera_device *icd)
135{ 155{
156 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
157 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
158
136 /* Disable the chip */ 159 /* Disable the chip */
137 reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); 160 reg_write(icd, MT9M001_OUTPUT_CONTROL, 0);
161
162 if (icl->power)
163 icl->power(&mt9m001->client->dev, 0);
164
138 return 0; 165 return 0;
139} 166}
140 167
@@ -267,24 +294,24 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd,
267 294
268 /* Blanking and start values - default... */ 295 /* Blanking and start values - default... */
269 ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); 296 ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank);
270 if (ret >= 0) 297 if (!ret)
271 ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); 298 ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank);
272 299
273 /* The caller provides a supported format, as verified per 300 /* The caller provides a supported format, as verified per
274 * call to icd->try_fmt_cap() */ 301 * call to icd->try_fmt_cap() */
275 if (ret >= 0) 302 if (!ret)
276 ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); 303 ret = reg_write(icd, MT9M001_COLUMN_START, rect->left);
277 if (ret >= 0) 304 if (!ret)
278 ret = reg_write(icd, MT9M001_ROW_START, rect->top); 305 ret = reg_write(icd, MT9M001_ROW_START, rect->top);
279 if (ret >= 0) 306 if (!ret)
280 ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); 307 ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1);
281 if (ret >= 0) 308 if (!ret)
282 ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, 309 ret = reg_write(icd, MT9M001_WINDOW_HEIGHT,
283 rect->height + icd->y_skip_top - 1); 310 rect->height + icd->y_skip_top - 1);
284 if (ret >= 0 && mt9m001->autoexposure) { 311 if (!ret && mt9m001->autoexposure) {
285 ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, 312 ret = reg_write(icd, MT9M001_SHUTTER_WIDTH,
286 rect->height + icd->y_skip_top + vblank); 313 rect->height + icd->y_skip_top + vblank);
287 if (ret >= 0) { 314 if (!ret) {
288 const struct v4l2_queryctrl *qctrl = 315 const struct v4l2_queryctrl *qctrl =
289 soc_camera_find_qctrl(icd->ops, 316 soc_camera_find_qctrl(icd->ops,
290 V4L2_CID_EXPOSURE); 317 V4L2_CID_EXPOSURE);
@@ -295,7 +322,7 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd,
295 } 322 }
296 } 323 }
297 324
298 return ret < 0 ? ret : 0; 325 return ret;
299} 326}
300 327
301static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, 328static int mt9m001_try_fmt_cap(struct soc_camera_device *icd,