aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9v022.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mt9v022.c')
-rw-r--r--drivers/media/video/mt9v022.c434
1 files changed, 255 insertions, 179 deletions
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index dbdcc86ae50d..995607f9d3ba 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -14,13 +14,13 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16 16
17#include <media/v4l2-common.h> 17#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h> 18#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20 20
21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c 21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
22 * The platform has to define i2c_board_info 22 * The platform has to define ctruct i2c_board_info objects and link to them
23 * and call i2c_register_board_info() */ 23 * from struct soc_camera_link */
24 24
25static char *sensor_type; 25static char *sensor_type;
26module_param(sensor_type, charp, S_IRUGO); 26module_param(sensor_type, charp, S_IRUGO);
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
45#define MT9V022_PIXEL_OPERATION_MODE 0x0f 45#define MT9V022_PIXEL_OPERATION_MODE 0x0f
46#define MT9V022_LED_OUT_CONTROL 0x1b 46#define MT9V022_LED_OUT_CONTROL 0x1b
47#define MT9V022_ADC_MODE_CONTROL 0x1c 47#define MT9V022_ADC_MODE_CONTROL 0x1c
48#define MT9V022_ANALOG_GAIN 0x34 48#define MT9V022_ANALOG_GAIN 0x35
49#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 49#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
50#define MT9V022_PIXCLK_FV_LV 0x74 50#define MT9V022_PIXCLK_FV_LV 0x74
51#define MT9V022_DIGITAL_TEST_PATTERN 0x7f 51#define MT9V022_DIGITAL_TEST_PATTERN 0x7f
@@ -55,6 +55,13 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
55/* Progressive scan, master, defaults */ 55/* Progressive scan, master, defaults */
56#define MT9V022_CHIP_CONTROL_DEFAULT 0x188 56#define MT9V022_CHIP_CONTROL_DEFAULT 0x188
57 57
58#define MT9V022_MAX_WIDTH 752
59#define MT9V022_MAX_HEIGHT 480
60#define MT9V022_MIN_WIDTH 48
61#define MT9V022_MIN_HEIGHT 32
62#define MT9V022_COLUMN_SKIP 1
63#define MT9V022_ROW_SKIP 4
64
58static const struct soc_camera_data_format mt9v022_colour_formats[] = { 65static const struct soc_camera_data_format mt9v022_colour_formats[] = {
59 /* Order important: first natively supported, 66 /* Order important: first natively supported,
60 * second supported with a GPIO extender */ 67 * second supported with a GPIO extender */
@@ -85,12 +92,18 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
85}; 92};
86 93
87struct mt9v022 { 94struct mt9v022 {
88 struct i2c_client *client; 95 struct v4l2_subdev subdev;
89 struct soc_camera_device icd; 96 struct v4l2_rect rect; /* Sensor window */
97 __u32 fourcc;
90 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 98 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
91 u16 chip_control; 99 u16 chip_control;
92}; 100};
93 101
102static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
103{
104 return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
105}
106
94static int reg_read(struct i2c_client *client, const u8 reg) 107static int reg_read(struct i2c_client *client, const u8 reg)
95{ 108{
96 s32 data = i2c_smbus_read_word_data(client, reg); 109 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -125,29 +138,11 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
125 return reg_write(client, reg, ret & ~data); 138 return reg_write(client, reg, ret & ~data);
126} 139}
127 140
128static int mt9v022_init(struct soc_camera_device *icd) 141static int mt9v022_init(struct i2c_client *client)
129{ 142{
130 struct i2c_client *client = to_i2c_client(icd->control); 143 struct mt9v022 *mt9v022 = to_mt9v022(client);
131 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
132 struct soc_camera_link *icl = client->dev.platform_data;
133 int ret; 144 int ret;
134 145
135 if (icl->power) {
136 ret = icl->power(&client->dev, 1);
137 if (ret < 0) {
138 dev_err(icd->vdev->parent,
139 "Platform failed to power-on the camera.\n");
140 return ret;
141 }
142 }
143
144 /*
145 * The camera could have been already on, we hard-reset it additionally,
146 * if available. Soft reset is done in video_probe().
147 */
148 if (icl->reset)
149 icl->reset(&client->dev);
150
151 /* Almost the default mode: master, parallel, simultaneous, and an 146 /* Almost the default mode: master, parallel, simultaneous, and an
152 * undocumented bit 0x200, which is present in table 7, but not in 8, 147 * undocumented bit 0x200, which is present in table 7, but not in 8,
153 * plus snapshot mode to disable scan for now */ 148 * plus snapshot mode to disable scan for now */
@@ -161,6 +156,10 @@ static int mt9v022_init(struct soc_camera_device *icd)
161 /* AEC, AGC on */ 156 /* AEC, AGC on */
162 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); 157 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
163 if (!ret) 158 if (!ret)
159 ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
160 if (!ret)
161 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
162 if (!ret)
164 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); 163 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
165 if (!ret) 164 if (!ret)
166 /* default - auto */ 165 /* default - auto */
@@ -171,37 +170,19 @@ static int mt9v022_init(struct soc_camera_device *icd)
171 return ret; 170 return ret;
172} 171}
173 172
174static int mt9v022_release(struct soc_camera_device *icd) 173static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
175{ 174{
176 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 175 struct i2c_client *client = sd->priv;
177 struct soc_camera_link *icl = mt9v022->client->dev.platform_data; 176 struct mt9v022 *mt9v022 = to_mt9v022(client);
178
179 if (icl->power)
180 icl->power(&mt9v022->client->dev, 0);
181
182 return 0;
183}
184 177
185static int mt9v022_start_capture(struct soc_camera_device *icd) 178 if (enable)
186{ 179 /* Switch to master "normal" mode */
187 struct i2c_client *client = to_i2c_client(icd->control); 180 mt9v022->chip_control &= ~0x10;
188 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 181 else
189 /* Switch to master "normal" mode */ 182 /* Switch to snapshot mode */
190 mt9v022->chip_control &= ~0x10; 183 mt9v022->chip_control |= 0x10;
191 if (reg_write(client, MT9V022_CHIP_CONTROL,
192 mt9v022->chip_control) < 0)
193 return -EIO;
194 return 0;
195}
196 184
197static int mt9v022_stop_capture(struct soc_camera_device *icd) 185 if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
198{
199 struct i2c_client *client = to_i2c_client(icd->control);
200 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
201 /* Switch to snapshot mode */
202 mt9v022->chip_control |= 0x10;
203 if (reg_write(client, MT9V022_CHIP_CONTROL,
204 mt9v022->chip_control) < 0)
205 return -EIO; 186 return -EIO;
206 return 0; 187 return 0;
207} 188}
@@ -209,9 +190,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
209static int mt9v022_set_bus_param(struct soc_camera_device *icd, 190static int mt9v022_set_bus_param(struct soc_camera_device *icd,
210 unsigned long flags) 191 unsigned long flags)
211{ 192{
212 struct i2c_client *client = to_i2c_client(icd->control); 193 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
213 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 194 struct mt9v022 *mt9v022 = to_mt9v022(client);
214 struct soc_camera_link *icl = client->dev.platform_data; 195 struct soc_camera_link *icl = to_soc_camera_link(icd);
215 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; 196 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
216 int ret; 197 int ret;
217 u16 pixclk = 0; 198 u16 pixclk = 0;
@@ -255,7 +236,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
255 if (ret < 0) 236 if (ret < 0)
256 return ret; 237 return ret;
257 238
258 dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n", 239 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
259 pixclk, mt9v022->chip_control); 240 pixclk, mt9v022->chip_control);
260 241
261 return 0; 242 return 0;
@@ -263,8 +244,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
263 244
264static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) 245static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
265{ 246{
266 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 247 struct soc_camera_link *icl = to_soc_camera_link(icd);
267 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
268 unsigned int width_flag; 248 unsigned int width_flag;
269 249
270 if (icl->query_bus_param) 250 if (icl->query_bus_param)
@@ -280,60 +260,121 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
280 width_flag; 260 width_flag;
281} 261}
282 262
283static int mt9v022_set_crop(struct soc_camera_device *icd, 263static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
284 struct v4l2_rect *rect)
285{ 264{
286 struct i2c_client *client = to_i2c_client(icd->control); 265 struct i2c_client *client = sd->priv;
266 struct mt9v022 *mt9v022 = to_mt9v022(client);
267 struct v4l2_rect rect = a->c;
268 struct soc_camera_device *icd = client->dev.platform_data;
287 int ret; 269 int ret;
288 270
271 /* Bayer format - even size lengths */
272 if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 ||
273 mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
274 rect.width = ALIGN(rect.width, 2);
275 rect.height = ALIGN(rect.height, 2);
276 /* Let the user play with the starting pixel */
277 }
278
279 soc_camera_limit_side(&rect.left, &rect.width,
280 MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
281
282 soc_camera_limit_side(&rect.top, &rect.height,
283 MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
284
289 /* Like in example app. Contradicts the datasheet though */ 285 /* Like in example app. Contradicts the datasheet though */
290 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); 286 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
291 if (ret >= 0) { 287 if (ret >= 0) {
292 if (ret & 1) /* Autoexposure */ 288 if (ret & 1) /* Autoexposure */
293 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 289 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
294 rect->height + icd->y_skip_top + 43); 290 rect.height + icd->y_skip_top + 43);
295 else 291 else
296 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 292 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
297 rect->height + icd->y_skip_top + 43); 293 rect.height + icd->y_skip_top + 43);
298 } 294 }
299 /* Setup frame format: defaults apart from width and height */ 295 /* Setup frame format: defaults apart from width and height */
300 if (!ret) 296 if (!ret)
301 ret = reg_write(client, MT9V022_COLUMN_START, rect->left); 297 ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
302 if (!ret) 298 if (!ret)
303 ret = reg_write(client, MT9V022_ROW_START, rect->top); 299 ret = reg_write(client, MT9V022_ROW_START, rect.top);
304 if (!ret) 300 if (!ret)
305 /* Default 94, Phytec driver says: 301 /* Default 94, Phytec driver says:
306 * "width + horizontal blank >= 660" */ 302 * "width + horizontal blank >= 660" */
307 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, 303 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
308 rect->width > 660 - 43 ? 43 : 304 rect.width > 660 - 43 ? 43 :
309 660 - rect->width); 305 660 - rect.width);
310 if (!ret) 306 if (!ret)
311 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45); 307 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
312 if (!ret) 308 if (!ret)
313 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width); 309 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
314 if (!ret) 310 if (!ret)
315 ret = reg_write(client, MT9V022_WINDOW_HEIGHT, 311 ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
316 rect->height + icd->y_skip_top); 312 rect.height + icd->y_skip_top);
317 313
318 if (ret < 0) 314 if (ret < 0)
319 return ret; 315 return ret;
320 316
321 dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height); 317 dev_dbg(&client->dev, "Frame %ux%u pixel\n", rect.width, rect.height);
318
319 mt9v022->rect = rect;
320
321 return 0;
322}
323
324static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
325{
326 struct i2c_client *client = sd->priv;
327 struct mt9v022 *mt9v022 = to_mt9v022(client);
328
329 a->c = mt9v022->rect;
330 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
322 331
323 return 0; 332 return 0;
324} 333}
325 334
326static int mt9v022_set_fmt(struct soc_camera_device *icd, 335static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
327 struct v4l2_format *f)
328{ 336{
329 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 337 a->bounds.left = MT9V022_COLUMN_SKIP;
338 a->bounds.top = MT9V022_ROW_SKIP;
339 a->bounds.width = MT9V022_MAX_WIDTH;
340 a->bounds.height = MT9V022_MAX_HEIGHT;
341 a->defrect = a->bounds;
342 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
343 a->pixelaspect.numerator = 1;
344 a->pixelaspect.denominator = 1;
345
346 return 0;
347}
348
349static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
350{
351 struct i2c_client *client = sd->priv;
352 struct mt9v022 *mt9v022 = to_mt9v022(client);
330 struct v4l2_pix_format *pix = &f->fmt.pix; 353 struct v4l2_pix_format *pix = &f->fmt.pix;
331 struct v4l2_rect rect = { 354
332 .left = icd->x_current, 355 pix->width = mt9v022->rect.width;
333 .top = icd->y_current, 356 pix->height = mt9v022->rect.height;
334 .width = pix->width, 357 pix->pixelformat = mt9v022->fourcc;
335 .height = pix->height, 358 pix->field = V4L2_FIELD_NONE;
359 pix->colorspace = V4L2_COLORSPACE_SRGB;
360
361 return 0;
362}
363
364static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
365{
366 struct i2c_client *client = sd->priv;
367 struct mt9v022 *mt9v022 = to_mt9v022(client);
368 struct v4l2_pix_format *pix = &f->fmt.pix;
369 struct v4l2_crop a = {
370 .c = {
371 .left = mt9v022->rect.left,
372 .top = mt9v022->rect.top,
373 .width = pix->width,
374 .height = pix->height,
375 },
336 }; 376 };
377 int ret;
337 378
338 /* The caller provides a supported format, as verified per call to 379 /* The caller provides a supported format, as verified per call to
339 * icd->try_fmt(), datawidth is from our supported format list */ 380 * icd->try_fmt(), datawidth is from our supported format list */
@@ -356,30 +397,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
356 } 397 }
357 398
358 /* No support for scaling on this camera, just crop. */ 399 /* No support for scaling on this camera, just crop. */
359 return mt9v022_set_crop(icd, &rect); 400 ret = mt9v022_s_crop(sd, &a);
401 if (!ret) {
402 pix->width = mt9v022->rect.width;
403 pix->height = mt9v022->rect.height;
404 mt9v022->fourcc = pix->pixelformat;
405 }
406
407 return ret;
360} 408}
361 409
362static int mt9v022_try_fmt(struct soc_camera_device *icd, 410static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
363 struct v4l2_format *f)
364{ 411{
412 struct i2c_client *client = sd->priv;
413 struct soc_camera_device *icd = client->dev.platform_data;
365 struct v4l2_pix_format *pix = &f->fmt.pix; 414 struct v4l2_pix_format *pix = &f->fmt.pix;
415 int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
416 pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
366 417
367 v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */, 418 v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
368 &pix->height, 32 + icd->y_skip_top, 419 MT9V022_MAX_WIDTH, align,
369 480 + icd->y_skip_top, 0, 0); 420 &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top,
421 MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0);
370 422
371 return 0; 423 return 0;
372} 424}
373 425
374static int mt9v022_get_chip_id(struct soc_camera_device *icd, 426static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
375 struct v4l2_dbg_chip_ident *id) 427 struct v4l2_dbg_chip_ident *id)
376{ 428{
377 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 429 struct i2c_client *client = sd->priv;
430 struct mt9v022 *mt9v022 = to_mt9v022(client);
378 431
379 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 432 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
380 return -EINVAL; 433 return -EINVAL;
381 434
382 if (id->match.addr != mt9v022->client->addr) 435 if (id->match.addr != client->addr)
383 return -ENODEV; 436 return -ENODEV;
384 437
385 id->ident = mt9v022->model; 438 id->ident = mt9v022->model;
@@ -389,10 +442,10 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
389} 442}
390 443
391#ifdef CONFIG_VIDEO_ADV_DEBUG 444#ifdef CONFIG_VIDEO_ADV_DEBUG
392static int mt9v022_get_register(struct soc_camera_device *icd, 445static int mt9v022_g_register(struct v4l2_subdev *sd,
393 struct v4l2_dbg_register *reg) 446 struct v4l2_dbg_register *reg)
394{ 447{
395 struct i2c_client *client = to_i2c_client(icd->control); 448 struct i2c_client *client = sd->priv;
396 449
397 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 450 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
398 return -EINVAL; 451 return -EINVAL;
@@ -409,10 +462,10 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
409 return 0; 462 return 0;
410} 463}
411 464
412static int mt9v022_set_register(struct soc_camera_device *icd, 465static int mt9v022_s_register(struct v4l2_subdev *sd,
413 struct v4l2_dbg_register *reg) 466 struct v4l2_dbg_register *reg)
414{ 467{
415 struct i2c_client *client = to_i2c_client(icd->control); 468 struct i2c_client *client = sd->priv;
416 469
417 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 470 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
418 return -EINVAL; 471 return -EINVAL;
@@ -481,41 +534,22 @@ static const struct v4l2_queryctrl mt9v022_controls[] = {
481 } 534 }
482}; 535};
483 536
484static int mt9v022_video_probe(struct soc_camera_device *);
485static void mt9v022_video_remove(struct soc_camera_device *);
486static int mt9v022_get_control(struct soc_camera_device *, struct v4l2_control *);
487static int mt9v022_set_control(struct soc_camera_device *, struct v4l2_control *);
488
489static struct soc_camera_ops mt9v022_ops = { 537static struct soc_camera_ops mt9v022_ops = {
490 .owner = THIS_MODULE,
491 .probe = mt9v022_video_probe,
492 .remove = mt9v022_video_remove,
493 .init = mt9v022_init,
494 .release = mt9v022_release,
495 .start_capture = mt9v022_start_capture,
496 .stop_capture = mt9v022_stop_capture,
497 .set_crop = mt9v022_set_crop,
498 .set_fmt = mt9v022_set_fmt,
499 .try_fmt = mt9v022_try_fmt,
500 .set_bus_param = mt9v022_set_bus_param, 538 .set_bus_param = mt9v022_set_bus_param,
501 .query_bus_param = mt9v022_query_bus_param, 539 .query_bus_param = mt9v022_query_bus_param,
502 .controls = mt9v022_controls, 540 .controls = mt9v022_controls,
503 .num_controls = ARRAY_SIZE(mt9v022_controls), 541 .num_controls = ARRAY_SIZE(mt9v022_controls),
504 .get_control = mt9v022_get_control,
505 .set_control = mt9v022_set_control,
506 .get_chip_id = mt9v022_get_chip_id,
507#ifdef CONFIG_VIDEO_ADV_DEBUG
508 .get_register = mt9v022_get_register,
509 .set_register = mt9v022_set_register,
510#endif
511}; 542};
512 543
513static int mt9v022_get_control(struct soc_camera_device *icd, 544static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
514 struct v4l2_control *ctrl)
515{ 545{
516 struct i2c_client *client = to_i2c_client(icd->control); 546 struct i2c_client *client = sd->priv;
547 const struct v4l2_queryctrl *qctrl;
548 unsigned long range;
517 int data; 549 int data;
518 550
551 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
552
519 switch (ctrl->id) { 553 switch (ctrl->id) {
520 case V4L2_CID_VFLIP: 554 case V4L2_CID_VFLIP:
521 data = reg_read(client, MT9V022_READ_MODE); 555 data = reg_read(client, MT9V022_READ_MODE);
@@ -541,19 +575,35 @@ static int mt9v022_get_control(struct soc_camera_device *icd,
541 return -EIO; 575 return -EIO;
542 ctrl->value = !!(data & 0x2); 576 ctrl->value = !!(data & 0x2);
543 break; 577 break;
578 case V4L2_CID_GAIN:
579 data = reg_read(client, MT9V022_ANALOG_GAIN);
580 if (data < 0)
581 return -EIO;
582
583 range = qctrl->maximum - qctrl->minimum;
584 ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum;
585
586 break;
587 case V4L2_CID_EXPOSURE:
588 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
589 if (data < 0)
590 return -EIO;
591
592 range = qctrl->maximum - qctrl->minimum;
593 ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum;
594
595 break;
544 } 596 }
545 return 0; 597 return 0;
546} 598}
547 599
548static int mt9v022_set_control(struct soc_camera_device *icd, 600static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
549 struct v4l2_control *ctrl)
550{ 601{
551 int data; 602 int data;
552 struct i2c_client *client = to_i2c_client(icd->control); 603 struct i2c_client *client = sd->priv;
553 const struct v4l2_queryctrl *qctrl; 604 const struct v4l2_queryctrl *qctrl;
554 605
555 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); 606 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
556
557 if (!qctrl) 607 if (!qctrl)
558 return -EINVAL; 608 return -EINVAL;
559 609
@@ -580,12 +630,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
580 return -EINVAL; 630 return -EINVAL;
581 else { 631 else {
582 unsigned long range = qctrl->maximum - qctrl->minimum; 632 unsigned long range = qctrl->maximum - qctrl->minimum;
583 /* Datasheet says 16 to 64. autogain only works properly 633 /* Valid values 16 to 64, 32 to 64 must be even. */
584 * after setting gain to maximum 14. Larger values
585 * produce "white fly" noise effect. On the whole,
586 * manually setting analog gain does no good. */
587 unsigned long gain = ((ctrl->value - qctrl->minimum) * 634 unsigned long gain = ((ctrl->value - qctrl->minimum) *
588 10 + range / 2) / range + 4; 635 48 + range / 2) / range + 16;
589 if (gain >= 32) 636 if (gain >= 32)
590 gain &= ~1; 637 gain &= ~1;
591 /* The user wants to set gain manually, hope, she 638 /* The user wants to set gain manually, hope, she
@@ -594,11 +641,10 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
594 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) 641 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
595 return -EIO; 642 return -EIO;
596 643
597 dev_info(&icd->dev, "Setting gain from %d to %lu\n", 644 dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
598 reg_read(client, MT9V022_ANALOG_GAIN), gain); 645 reg_read(client, MT9V022_ANALOG_GAIN), gain);
599 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) 646 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
600 return -EIO; 647 return -EIO;
601 icd->gain = ctrl->value;
602 } 648 }
603 break; 649 break;
604 case V4L2_CID_EXPOSURE: 650 case V4L2_CID_EXPOSURE:
@@ -615,13 +661,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
615 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) 661 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
616 return -EIO; 662 return -EIO;
617 663
618 dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", 664 dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
619 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), 665 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
620 shutter); 666 shutter);
621 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 667 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
622 shutter) < 0) 668 shutter) < 0)
623 return -EIO; 669 return -EIO;
624 icd->exposure = ctrl->value;
625 } 670 }
626 break; 671 break;
627 case V4L2_CID_AUTOGAIN: 672 case V4L2_CID_AUTOGAIN:
@@ -646,11 +691,11 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
646 691
647/* Interface active, can use i2c. If it fails, it can indeed mean, that 692/* Interface active, can use i2c. If it fails, it can indeed mean, that
648 * this wasn't our capture interface, so, we wait for the right one */ 693 * this wasn't our capture interface, so, we wait for the right one */
649static int mt9v022_video_probe(struct soc_camera_device *icd) 694static int mt9v022_video_probe(struct soc_camera_device *icd,
695 struct i2c_client *client)
650{ 696{
651 struct i2c_client *client = to_i2c_client(icd->control); 697 struct mt9v022 *mt9v022 = to_mt9v022(client);
652 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 698 struct soc_camera_link *icl = to_soc_camera_link(icd);
653 struct soc_camera_link *icl = client->dev.platform_data;
654 s32 data; 699 s32 data;
655 int ret; 700 int ret;
656 unsigned long flags; 701 unsigned long flags;
@@ -665,7 +710,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
665 /* must be 0x1311 or 0x1313 */ 710 /* must be 0x1311 or 0x1313 */
666 if (data != 0x1311 && data != 0x1313) { 711 if (data != 0x1311 && data != 0x1313) {
667 ret = -ENODEV; 712 ret = -ENODEV;
668 dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n", 713 dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
669 data); 714 data);
670 goto ei2c; 715 goto ei2c;
671 } 716 }
@@ -677,7 +722,9 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
677 /* 15 clock cycles */ 722 /* 15 clock cycles */
678 udelay(200); 723 udelay(200);
679 if (reg_read(client, MT9V022_RESET)) { 724 if (reg_read(client, MT9V022_RESET)) {
680 dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); 725 dev_err(&client->dev, "Resetting MT9V022 failed!\n");
726 if (ret > 0)
727 ret = -EIO;
681 goto ei2c; 728 goto ei2c;
682 } 729 }
683 730
@@ -694,7 +741,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
694 } 741 }
695 742
696 if (ret < 0) 743 if (ret < 0)
697 goto eisis; 744 goto ei2c;
698 745
699 icd->num_formats = 0; 746 icd->num_formats = 0;
700 747
@@ -716,42 +763,70 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
716 if (flags & SOCAM_DATAWIDTH_8) 763 if (flags & SOCAM_DATAWIDTH_8)
717 icd->num_formats++; 764 icd->num_formats++;
718 765
719 ret = soc_camera_video_start(icd); 766 mt9v022->fourcc = icd->formats->fourcc;
720 if (ret < 0)
721 goto eisis;
722 767
723 dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", 768 dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
724 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? 769 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
725 "monochrome" : "colour"); 770 "monochrome" : "colour");
726 771
727 return 0; 772 ret = mt9v022_init(client);
773 if (ret < 0)
774 dev_err(&client->dev, "Failed to initialise the camera\n");
728 775
729eisis:
730ei2c: 776ei2c:
731 return ret; 777 return ret;
732} 778}
733 779
734static void mt9v022_video_remove(struct soc_camera_device *icd) 780static void mt9v022_video_remove(struct soc_camera_device *icd)
735{ 781{
736 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 782 struct soc_camera_link *icl = to_soc_camera_link(icd);
737 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
738 783
739 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, 784 dev_dbg(&icd->dev, "Video removed: %p, %p\n",
740 icd->dev.parent, icd->vdev); 785 icd->dev.parent, icd->vdev);
741 soc_camera_video_stop(icd);
742 if (icl->free_bus) 786 if (icl->free_bus)
743 icl->free_bus(icl); 787 icl->free_bus(icl);
744} 788}
745 789
790static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
791 .g_ctrl = mt9v022_g_ctrl,
792 .s_ctrl = mt9v022_s_ctrl,
793 .g_chip_ident = mt9v022_g_chip_ident,
794#ifdef CONFIG_VIDEO_ADV_DEBUG
795 .g_register = mt9v022_g_register,
796 .s_register = mt9v022_s_register,
797#endif
798};
799
800static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
801 .s_stream = mt9v022_s_stream,
802 .s_fmt = mt9v022_s_fmt,
803 .g_fmt = mt9v022_g_fmt,
804 .try_fmt = mt9v022_try_fmt,
805 .s_crop = mt9v022_s_crop,
806 .g_crop = mt9v022_g_crop,
807 .cropcap = mt9v022_cropcap,
808};
809
810static struct v4l2_subdev_ops mt9v022_subdev_ops = {
811 .core = &mt9v022_subdev_core_ops,
812 .video = &mt9v022_subdev_video_ops,
813};
814
746static int mt9v022_probe(struct i2c_client *client, 815static int mt9v022_probe(struct i2c_client *client,
747 const struct i2c_device_id *did) 816 const struct i2c_device_id *did)
748{ 817{
749 struct mt9v022 *mt9v022; 818 struct mt9v022 *mt9v022;
750 struct soc_camera_device *icd; 819 struct soc_camera_device *icd = client->dev.platform_data;
751 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 820 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
752 struct soc_camera_link *icl = client->dev.platform_data; 821 struct soc_camera_link *icl;
753 int ret; 822 int ret;
754 823
824 if (!icd) {
825 dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
826 return -EINVAL;
827 }
828
829 icl = to_soc_camera_link(icd);
755 if (!icl) { 830 if (!icl) {
756 dev_err(&client->dev, "MT9V022 driver needs platform data\n"); 831 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
757 return -EINVAL; 832 return -EINVAL;
@@ -767,40 +842,41 @@ static int mt9v022_probe(struct i2c_client *client,
767 if (!mt9v022) 842 if (!mt9v022)
768 return -ENOMEM; 843 return -ENOMEM;
769 844
845 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
846
770 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 847 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
771 mt9v022->client = client;
772 i2c_set_clientdata(client, mt9v022);
773
774 icd = &mt9v022->icd;
775 icd->ops = &mt9v022_ops;
776 icd->control = &client->dev;
777 icd->x_min = 1;
778 icd->y_min = 4;
779 icd->x_current = 1;
780 icd->y_current = 4;
781 icd->width_min = 48;
782 icd->width_max = 752;
783 icd->height_min = 32;
784 icd->height_max = 480;
785 icd->y_skip_top = 1;
786 icd->iface = icl->bus_id;
787
788 ret = soc_camera_device_register(icd);
789 if (ret)
790 goto eisdr;
791 848
792 return 0; 849 icd->ops = &mt9v022_ops;
850 /*
851 * MT9V022 _really_ corrupts the first read out line.
852 * TODO: verify on i.MX31
853 */
854 icd->y_skip_top = 1;
855
856 mt9v022->rect.left = MT9V022_COLUMN_SKIP;
857 mt9v022->rect.top = MT9V022_ROW_SKIP;
858 mt9v022->rect.width = MT9V022_MAX_WIDTH;
859 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
860
861 ret = mt9v022_video_probe(icd, client);
862 if (ret) {
863 icd->ops = NULL;
864 i2c_set_clientdata(client, NULL);
865 kfree(mt9v022);
866 }
793 867
794eisdr:
795 kfree(mt9v022);
796 return ret; 868 return ret;
797} 869}
798 870
799static int mt9v022_remove(struct i2c_client *client) 871static int mt9v022_remove(struct i2c_client *client)
800{ 872{
801 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 873 struct mt9v022 *mt9v022 = to_mt9v022(client);
874 struct soc_camera_device *icd = client->dev.platform_data;
802 875
803 soc_camera_device_unregister(&mt9v022->icd); 876 icd->ops = NULL;
877 mt9v022_video_remove(icd);
878 i2c_set_clientdata(client, NULL);
879 client->driver = NULL;
804 kfree(mt9v022); 880 kfree(mt9v022);
805 881
806 return 0; 882 return 0;