diff options
Diffstat (limited to 'drivers/media/video/mt9m001.c')
-rw-r--r-- | drivers/media/video/mt9m001.c | 55 |
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 | ||
118 | static int mt9m001_init(struct soc_camera_device *icd) | 118 | static 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 | ||
134 | static int mt9m001_release(struct soc_camera_device *icd) | 154 | static 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 | ||
301 | static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, | 328 | static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, |