aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9m111.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mt9m111.c')
-rw-r--r--drivers/media/video/mt9m111.c524
1 files changed, 271 insertions, 253 deletions
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index fc5e2de03766..90da699601ea 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -148,12 +148,12 @@ enum mt9m111_context {
148}; 148};
149 149
150struct mt9m111 { 150struct mt9m111 {
151 struct i2c_client *client; 151 struct v4l2_subdev subdev;
152 struct soc_camera_device icd;
153 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ 152 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
154 enum mt9m111_context context; 153 enum mt9m111_context context;
155 struct v4l2_rect rect; 154 struct v4l2_rect rect;
156 u32 pixfmt; 155 u32 pixfmt;
156 unsigned int gain;
157 unsigned char autoexposure; 157 unsigned char autoexposure;
158 unsigned char datawidth; 158 unsigned char datawidth;
159 unsigned int powered:1; 159 unsigned int powered:1;
@@ -166,6 +166,11 @@ struct mt9m111 {
166 unsigned int autowhitebalance:1; 166 unsigned int autowhitebalance:1;
167}; 167};
168 168
169static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
170{
171 return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
172}
173
169static int reg_page_map_set(struct i2c_client *client, const u16 reg) 174static int reg_page_map_set(struct i2c_client *client, const u16 reg)
170{ 175{
171 int ret; 176 int ret;
@@ -190,7 +195,7 @@ static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
190 195
191 ret = reg_page_map_set(client, reg); 196 ret = reg_page_map_set(client, reg);
192 if (!ret) 197 if (!ret)
193 ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); 198 ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff));
194 199
195 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); 200 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret);
196 return ret; 201 return ret;
@@ -203,7 +208,7 @@ static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
203 208
204 ret = reg_page_map_set(client, reg); 209 ret = reg_page_map_set(client, reg);
205 if (!ret) 210 if (!ret)
206 ret = i2c_smbus_write_word_data(client, (reg & 0xff), 211 ret = i2c_smbus_write_word_data(client, reg & 0xff,
207 swab16(data)); 212 swab16(data));
208 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); 213 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
209 return ret; 214 return ret;
@@ -229,10 +234,9 @@ static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
229 return mt9m111_reg_write(client, reg, ret & ~data); 234 return mt9m111_reg_write(client, reg, ret & ~data);
230} 235}
231 236
232static int mt9m111_set_context(struct soc_camera_device *icd, 237static int mt9m111_set_context(struct i2c_client *client,
233 enum mt9m111_context ctxt) 238 enum mt9m111_context ctxt)
234{ 239{
235 struct i2c_client *client = to_i2c_client(icd->control);
236 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B 240 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
237 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B 241 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
238 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B 242 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -246,17 +250,16 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
246 return reg_write(CONTEXT_CONTROL, valA); 250 return reg_write(CONTEXT_CONTROL, valA);
247} 251}
248 252
249static int mt9m111_setup_rect(struct soc_camera_device *icd, 253static int mt9m111_setup_rect(struct i2c_client *client,
250 struct v4l2_rect *rect) 254 struct v4l2_rect *rect)
251{ 255{
252 struct i2c_client *client = to_i2c_client(icd->control); 256 struct mt9m111 *mt9m111 = to_mt9m111(client);
253 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
254 int ret, is_raw_format; 257 int ret, is_raw_format;
255 int width = rect->width; 258 int width = rect->width;
256 int height = rect->height; 259 int height = rect->height;
257 260
258 if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) 261 if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
259 || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) 262 mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)
260 is_raw_format = 1; 263 is_raw_format = 1;
261 else 264 else
262 is_raw_format = 0; 265 is_raw_format = 0;
@@ -292,9 +295,8 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
292 return ret; 295 return ret;
293} 296}
294 297
295static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) 298static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
296{ 299{
297 struct i2c_client *client = to_i2c_client(icd->control);
298 int ret; 300 int ret;
299 301
300 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); 302 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -303,19 +305,19 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
303 return ret; 305 return ret;
304} 306}
305 307
306static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) 308static int mt9m111_setfmt_bayer8(struct i2c_client *client)
307{ 309{
308 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); 310 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
309} 311}
310 312
311static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) 313static int mt9m111_setfmt_bayer10(struct i2c_client *client)
312{ 314{
313 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); 315 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP);
314} 316}
315 317
316static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) 318static int mt9m111_setfmt_rgb565(struct i2c_client *client)
317{ 319{
318 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 320 struct mt9m111 *mt9m111 = to_mt9m111(client);
319 int val = 0; 321 int val = 0;
320 322
321 if (mt9m111->swap_rgb_red_blue) 323 if (mt9m111->swap_rgb_red_blue)
@@ -324,12 +326,12 @@ static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd)
324 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 326 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
325 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; 327 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;
326 328
327 return mt9m111_setup_pixfmt(icd, val); 329 return mt9m111_setup_pixfmt(client, val);
328} 330}
329 331
330static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) 332static int mt9m111_setfmt_rgb555(struct i2c_client *client)
331{ 333{
332 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 334 struct mt9m111 *mt9m111 = to_mt9m111(client);
333 int val = 0; 335 int val = 0;
334 336
335 if (mt9m111->swap_rgb_red_blue) 337 if (mt9m111->swap_rgb_red_blue)
@@ -338,12 +340,12 @@ static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd)
338 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 340 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
339 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; 341 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;
340 342
341 return mt9m111_setup_pixfmt(icd, val); 343 return mt9m111_setup_pixfmt(client, val);
342} 344}
343 345
344static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) 346static int mt9m111_setfmt_yuv(struct i2c_client *client)
345{ 347{
346 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 348 struct mt9m111 *mt9m111 = to_mt9m111(client);
347 int val = 0; 349 int val = 0;
348 350
349 if (mt9m111->swap_yuv_cb_cr) 351 if (mt9m111->swap_yuv_cb_cr)
@@ -351,52 +353,22 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
351 if (mt9m111->swap_yuv_y_chromas) 353 if (mt9m111->swap_yuv_y_chromas)
352 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; 354 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
353 355
354 return mt9m111_setup_pixfmt(icd, val); 356 return mt9m111_setup_pixfmt(client, val);
355} 357}
356 358
357static int mt9m111_enable(struct soc_camera_device *icd) 359static int mt9m111_enable(struct i2c_client *client)
358{ 360{
359 struct i2c_client *client = to_i2c_client(icd->control); 361 struct mt9m111 *mt9m111 = to_mt9m111(client);
360 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
361 struct soc_camera_link *icl = client->dev.platform_data;
362 int ret; 362 int ret;
363 363
364 if (icl->power) {
365 ret = icl->power(&client->dev, 1);
366 if (ret < 0) {
367 dev_err(icd->vdev->parent,
368 "Platform failed to power-on the camera.\n");
369 return ret;
370 }
371 }
372
373 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); 364 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
374 if (!ret) 365 if (!ret)
375 mt9m111->powered = 1; 366 mt9m111->powered = 1;
376 return ret; 367 return ret;
377} 368}
378 369
379static int mt9m111_disable(struct soc_camera_device *icd) 370static int mt9m111_reset(struct i2c_client *client)
380{
381 struct i2c_client *client = to_i2c_client(icd->control);
382 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
383 struct soc_camera_link *icl = client->dev.platform_data;
384 int ret;
385
386 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
387 if (!ret)
388 mt9m111->powered = 0;
389
390 if (icl->power)
391 icl->power(&client->dev, 0);
392
393 return ret;
394}
395
396static int mt9m111_reset(struct soc_camera_device *icd)
397{ 371{
398 struct i2c_client *client = to_i2c_client(icd->control);
399 struct soc_camera_link *icl = client->dev.platform_data;
400 int ret; 372 int ret;
401 373
402 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); 374 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -406,26 +378,12 @@ static int mt9m111_reset(struct soc_camera_device *icd)
406 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE 378 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
407 | MT9M111_RESET_RESET_SOC); 379 | MT9M111_RESET_RESET_SOC);
408 380
409 if (icl->reset)
410 icl->reset(&client->dev);
411
412 return ret; 381 return ret;
413} 382}
414 383
415static int mt9m111_start_capture(struct soc_camera_device *icd)
416{
417 return 0;
418}
419
420static int mt9m111_stop_capture(struct soc_camera_device *icd)
421{
422 return 0;
423}
424
425static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) 384static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
426{ 385{
427 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 386 struct soc_camera_link *icl = to_soc_camera_link(icd);
428 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
429 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | 387 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
430 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | 388 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
431 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8; 389 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
@@ -438,62 +396,126 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
438 return 0; 396 return 0;
439} 397}
440 398
441static int mt9m111_set_crop(struct soc_camera_device *icd, 399static int mt9m111_make_rect(struct i2c_client *client,
442 struct v4l2_rect *rect) 400 struct v4l2_rect *rect)
443{ 401{
444 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 402 struct mt9m111 *mt9m111 = to_mt9m111(client);
403
404 if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
405 mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) {
406 /* Bayer format - even size lengths */
407 rect->width = ALIGN(rect->width, 2);
408 rect->height = ALIGN(rect->height, 2);
409 /* Let the user play with the starting pixel */
410 }
411
412 /* FIXME: the datasheet doesn't specify minimum sizes */
413 soc_camera_limit_side(&rect->left, &rect->width,
414 MT9M111_MIN_DARK_COLS, 2, MT9M111_MAX_WIDTH);
415
416 soc_camera_limit_side(&rect->top, &rect->height,
417 MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT);
418
419 return mt9m111_setup_rect(client, rect);
420}
421
422static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
423{
424 struct v4l2_rect rect = a->c;
425 struct i2c_client *client = sd->priv;
426 struct mt9m111 *mt9m111 = to_mt9m111(client);
445 int ret; 427 int ret;
446 428
447 dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n", 429 dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
448 __func__, rect->left, rect->top, rect->width, 430 __func__, rect.left, rect.top, rect.width, rect.height);
449 rect->height);
450 431
451 ret = mt9m111_setup_rect(icd, rect); 432 ret = mt9m111_make_rect(client, &rect);
452 if (!ret) 433 if (!ret)
453 mt9m111->rect = *rect; 434 mt9m111->rect = rect;
454 return ret; 435 return ret;
455} 436}
456 437
457static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) 438static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
458{ 439{
459 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 440 struct i2c_client *client = sd->priv;
441 struct mt9m111 *mt9m111 = to_mt9m111(client);
442
443 a->c = mt9m111->rect;
444 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
445
446 return 0;
447}
448
449static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
450{
451 a->bounds.left = MT9M111_MIN_DARK_COLS;
452 a->bounds.top = MT9M111_MIN_DARK_ROWS;
453 a->bounds.width = MT9M111_MAX_WIDTH;
454 a->bounds.height = MT9M111_MAX_HEIGHT;
455 a->defrect = a->bounds;
456 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
457 a->pixelaspect.numerator = 1;
458 a->pixelaspect.denominator = 1;
459
460 return 0;
461}
462
463static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
464{
465 struct i2c_client *client = sd->priv;
466 struct mt9m111 *mt9m111 = to_mt9m111(client);
467 struct v4l2_pix_format *pix = &f->fmt.pix;
468
469 pix->width = mt9m111->rect.width;
470 pix->height = mt9m111->rect.height;
471 pix->pixelformat = mt9m111->pixfmt;
472 pix->field = V4L2_FIELD_NONE;
473 pix->colorspace = V4L2_COLORSPACE_SRGB;
474
475 return 0;
476}
477
478static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
479{
480 struct mt9m111 *mt9m111 = to_mt9m111(client);
460 int ret; 481 int ret;
461 482
462 switch (pixfmt) { 483 switch (pixfmt) {
463 case V4L2_PIX_FMT_SBGGR8: 484 case V4L2_PIX_FMT_SBGGR8:
464 ret = mt9m111_setfmt_bayer8(icd); 485 ret = mt9m111_setfmt_bayer8(client);
465 break; 486 break;
466 case V4L2_PIX_FMT_SBGGR16: 487 case V4L2_PIX_FMT_SBGGR16:
467 ret = mt9m111_setfmt_bayer10(icd); 488 ret = mt9m111_setfmt_bayer10(client);
468 break; 489 break;
469 case V4L2_PIX_FMT_RGB555: 490 case V4L2_PIX_FMT_RGB555:
470 ret = mt9m111_setfmt_rgb555(icd); 491 ret = mt9m111_setfmt_rgb555(client);
471 break; 492 break;
472 case V4L2_PIX_FMT_RGB565: 493 case V4L2_PIX_FMT_RGB565:
473 ret = mt9m111_setfmt_rgb565(icd); 494 ret = mt9m111_setfmt_rgb565(client);
474 break; 495 break;
475 case V4L2_PIX_FMT_UYVY: 496 case V4L2_PIX_FMT_UYVY:
476 mt9m111->swap_yuv_y_chromas = 0; 497 mt9m111->swap_yuv_y_chromas = 0;
477 mt9m111->swap_yuv_cb_cr = 0; 498 mt9m111->swap_yuv_cb_cr = 0;
478 ret = mt9m111_setfmt_yuv(icd); 499 ret = mt9m111_setfmt_yuv(client);
479 break; 500 break;
480 case V4L2_PIX_FMT_VYUY: 501 case V4L2_PIX_FMT_VYUY:
481 mt9m111->swap_yuv_y_chromas = 0; 502 mt9m111->swap_yuv_y_chromas = 0;
482 mt9m111->swap_yuv_cb_cr = 1; 503 mt9m111->swap_yuv_cb_cr = 1;
483 ret = mt9m111_setfmt_yuv(icd); 504 ret = mt9m111_setfmt_yuv(client);
484 break; 505 break;
485 case V4L2_PIX_FMT_YUYV: 506 case V4L2_PIX_FMT_YUYV:
486 mt9m111->swap_yuv_y_chromas = 1; 507 mt9m111->swap_yuv_y_chromas = 1;
487 mt9m111->swap_yuv_cb_cr = 0; 508 mt9m111->swap_yuv_cb_cr = 0;
488 ret = mt9m111_setfmt_yuv(icd); 509 ret = mt9m111_setfmt_yuv(client);
489 break; 510 break;
490 case V4L2_PIX_FMT_YVYU: 511 case V4L2_PIX_FMT_YVYU:
491 mt9m111->swap_yuv_y_chromas = 1; 512 mt9m111->swap_yuv_y_chromas = 1;
492 mt9m111->swap_yuv_cb_cr = 1; 513 mt9m111->swap_yuv_cb_cr = 1;
493 ret = mt9m111_setfmt_yuv(icd); 514 ret = mt9m111_setfmt_yuv(client);
494 break; 515 break;
495 default: 516 default:
496 dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); 517 dev_err(&client->dev, "Pixel format not handled : %x\n",
518 pixfmt);
497 ret = -EINVAL; 519 ret = -EINVAL;
498 } 520 }
499 521
@@ -503,10 +525,10 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
503 return ret; 525 return ret;
504} 526}
505 527
506static int mt9m111_set_fmt(struct soc_camera_device *icd, 528static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
507 struct v4l2_format *f)
508{ 529{
509 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 530 struct i2c_client *client = sd->priv;
531 struct mt9m111 *mt9m111 = to_mt9m111(client);
510 struct v4l2_pix_format *pix = &f->fmt.pix; 532 struct v4l2_pix_format *pix = &f->fmt.pix;
511 struct v4l2_rect rect = { 533 struct v4l2_rect rect = {
512 .left = mt9m111->rect.left, 534 .left = mt9m111->rect.left,
@@ -516,40 +538,56 @@ static int mt9m111_set_fmt(struct soc_camera_device *icd,
516 }; 538 };
517 int ret; 539 int ret;
518 540
519 dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", 541 dev_dbg(&client->dev,
520 __func__, pix->pixelformat, rect.left, rect.top, rect.width, 542 "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
521 rect.height); 543 pix->pixelformat, rect.left, rect.top, rect.width, rect.height);
522 544
523 ret = mt9m111_setup_rect(icd, &rect); 545 ret = mt9m111_make_rect(client, &rect);
524 if (!ret) 546 if (!ret)
525 ret = mt9m111_set_pixfmt(icd, pix->pixelformat); 547 ret = mt9m111_set_pixfmt(client, pix->pixelformat);
526 if (!ret) 548 if (!ret)
527 mt9m111->rect = rect; 549 mt9m111->rect = rect;
528 return ret; 550 return ret;
529} 551}
530 552
531static int mt9m111_try_fmt(struct soc_camera_device *icd, 553static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
532 struct v4l2_format *f)
533{ 554{
534 struct v4l2_pix_format *pix = &f->fmt.pix; 555 struct v4l2_pix_format *pix = &f->fmt.pix;
556 bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
557 pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
558
559 /*
560 * With Bayer format enforce even side lengths, but let the user play
561 * with the starting pixel
562 */
535 563
536 if (pix->height > MT9M111_MAX_HEIGHT) 564 if (pix->height > MT9M111_MAX_HEIGHT)
537 pix->height = MT9M111_MAX_HEIGHT; 565 pix->height = MT9M111_MAX_HEIGHT;
566 else if (pix->height < 2)
567 pix->height = 2;
568 else if (bayer)
569 pix->height = ALIGN(pix->height, 2);
570
538 if (pix->width > MT9M111_MAX_WIDTH) 571 if (pix->width > MT9M111_MAX_WIDTH)
539 pix->width = MT9M111_MAX_WIDTH; 572 pix->width = MT9M111_MAX_WIDTH;
573 else if (pix->width < 2)
574 pix->width = 2;
575 else if (bayer)
576 pix->width = ALIGN(pix->width, 2);
540 577
541 return 0; 578 return 0;
542} 579}
543 580
544static int mt9m111_get_chip_id(struct soc_camera_device *icd, 581static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
545 struct v4l2_dbg_chip_ident *id) 582 struct v4l2_dbg_chip_ident *id)
546{ 583{
547 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 584 struct i2c_client *client = sd->priv;
585 struct mt9m111 *mt9m111 = to_mt9m111(client);
548 586
549 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 587 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
550 return -EINVAL; 588 return -EINVAL;
551 589
552 if (id->match.addr != mt9m111->client->addr) 590 if (id->match.addr != client->addr)
553 return -ENODEV; 591 return -ENODEV;
554 592
555 id->ident = mt9m111->model; 593 id->ident = mt9m111->model;
@@ -559,11 +597,11 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd,
559} 597}
560 598
561#ifdef CONFIG_VIDEO_ADV_DEBUG 599#ifdef CONFIG_VIDEO_ADV_DEBUG
562static int mt9m111_get_register(struct soc_camera_device *icd, 600static int mt9m111_g_register(struct v4l2_subdev *sd,
563 struct v4l2_dbg_register *reg) 601 struct v4l2_dbg_register *reg)
564{ 602{
603 struct i2c_client *client = sd->priv;
565 int val; 604 int val;
566 struct i2c_client *client = to_i2c_client(icd->control);
567 605
568 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 606 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
569 return -EINVAL; 607 return -EINVAL;
@@ -580,10 +618,10 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
580 return 0; 618 return 0;
581} 619}
582 620
583static int mt9m111_set_register(struct soc_camera_device *icd, 621static int mt9m111_s_register(struct v4l2_subdev *sd,
584 struct v4l2_dbg_register *reg) 622 struct v4l2_dbg_register *reg)
585{ 623{
586 struct i2c_client *client = to_i2c_client(icd->control); 624 struct i2c_client *client = sd->priv;
587 625
588 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 626 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
589 return -EINVAL; 627 return -EINVAL;
@@ -635,45 +673,21 @@ static const struct v4l2_queryctrl mt9m111_controls[] = {
635 } 673 }
636}; 674};
637 675
638static int mt9m111_video_probe(struct soc_camera_device *);
639static void mt9m111_video_remove(struct soc_camera_device *);
640static int mt9m111_get_control(struct soc_camera_device *,
641 struct v4l2_control *);
642static int mt9m111_set_control(struct soc_camera_device *,
643 struct v4l2_control *);
644static int mt9m111_resume(struct soc_camera_device *icd); 676static int mt9m111_resume(struct soc_camera_device *icd);
645static int mt9m111_init(struct soc_camera_device *icd); 677static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state);
646static int mt9m111_release(struct soc_camera_device *icd);
647 678
648static struct soc_camera_ops mt9m111_ops = { 679static struct soc_camera_ops mt9m111_ops = {
649 .owner = THIS_MODULE, 680 .suspend = mt9m111_suspend,
650 .probe = mt9m111_video_probe,
651 .remove = mt9m111_video_remove,
652 .init = mt9m111_init,
653 .resume = mt9m111_resume, 681 .resume = mt9m111_resume,
654 .release = mt9m111_release,
655 .start_capture = mt9m111_start_capture,
656 .stop_capture = mt9m111_stop_capture,
657 .set_crop = mt9m111_set_crop,
658 .set_fmt = mt9m111_set_fmt,
659 .try_fmt = mt9m111_try_fmt,
660 .query_bus_param = mt9m111_query_bus_param, 682 .query_bus_param = mt9m111_query_bus_param,
661 .set_bus_param = mt9m111_set_bus_param, 683 .set_bus_param = mt9m111_set_bus_param,
662 .controls = mt9m111_controls, 684 .controls = mt9m111_controls,
663 .num_controls = ARRAY_SIZE(mt9m111_controls), 685 .num_controls = ARRAY_SIZE(mt9m111_controls),
664 .get_control = mt9m111_get_control,
665 .set_control = mt9m111_set_control,
666 .get_chip_id = mt9m111_get_chip_id,
667#ifdef CONFIG_VIDEO_ADV_DEBUG
668 .get_register = mt9m111_get_register,
669 .set_register = mt9m111_set_register,
670#endif
671}; 686};
672 687
673static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) 688static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask)
674{ 689{
675 struct i2c_client *client = to_i2c_client(icd->control); 690 struct mt9m111 *mt9m111 = to_mt9m111(client);
676 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
677 int ret; 691 int ret;
678 692
679 if (mt9m111->context == HIGHPOWER) { 693 if (mt9m111->context == HIGHPOWER) {
@@ -691,9 +705,8 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
691 return ret; 705 return ret;
692} 706}
693 707
694static int mt9m111_get_global_gain(struct soc_camera_device *icd) 708static int mt9m111_get_global_gain(struct i2c_client *client)
695{ 709{
696 struct i2c_client *client = to_i2c_client(icd->control);
697 int data; 710 int data;
698 711
699 data = reg_read(GLOBAL_GAIN); 712 data = reg_read(GLOBAL_GAIN);
@@ -703,15 +716,15 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
703 return data; 716 return data;
704} 717}
705 718
706static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) 719static int mt9m111_set_global_gain(struct i2c_client *client, int gain)
707{ 720{
708 struct i2c_client *client = to_i2c_client(icd->control); 721 struct mt9m111 *mt9m111 = to_mt9m111(client);
709 u16 val; 722 u16 val;
710 723
711 if (gain > 63 * 2 * 2) 724 if (gain > 63 * 2 * 2)
712 return -EINVAL; 725 return -EINVAL;
713 726
714 icd->gain = gain; 727 mt9m111->gain = gain;
715 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) 728 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
716 val = (1 << 10) | (1 << 9) | (gain / 4); 729 val = (1 << 10) | (1 << 9) | (gain / 4);
717 else if ((gain >= 64) && (gain < 64 * 2)) 730 else if ((gain >= 64) && (gain < 64 * 2))
@@ -722,10 +735,9 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
722 return reg_write(GLOBAL_GAIN, val); 735 return reg_write(GLOBAL_GAIN, val);
723} 736}
724 737
725static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) 738static int mt9m111_set_autoexposure(struct i2c_client *client, int on)
726{ 739{
727 struct i2c_client *client = to_i2c_client(icd->control); 740 struct mt9m111 *mt9m111 = to_mt9m111(client);
728 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
729 int ret; 741 int ret;
730 742
731 if (on) 743 if (on)
@@ -739,10 +751,9 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
739 return ret; 751 return ret;
740} 752}
741 753
742static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) 754static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on)
743{ 755{
744 struct i2c_client *client = to_i2c_client(icd->control); 756 struct mt9m111 *mt9m111 = to_mt9m111(client);
745 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
746 int ret; 757 int ret;
747 758
748 if (on) 759 if (on)
@@ -756,11 +767,10 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
756 return ret; 767 return ret;
757} 768}
758 769
759static int mt9m111_get_control(struct soc_camera_device *icd, 770static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
760 struct v4l2_control *ctrl)
761{ 771{
762 struct i2c_client *client = to_i2c_client(icd->control); 772 struct i2c_client *client = sd->priv;
763 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 773 struct mt9m111 *mt9m111 = to_mt9m111(client);
764 int data; 774 int data;
765 775
766 switch (ctrl->id) { 776 switch (ctrl->id) {
@@ -785,7 +795,7 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
785 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); 795 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
786 break; 796 break;
787 case V4L2_CID_GAIN: 797 case V4L2_CID_GAIN:
788 data = mt9m111_get_global_gain(icd); 798 data = mt9m111_get_global_gain(client);
789 if (data < 0) 799 if (data < 0)
790 return data; 800 return data;
791 ctrl->value = data; 801 ctrl->value = data;
@@ -800,37 +810,36 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
800 return 0; 810 return 0;
801} 811}
802 812
803static int mt9m111_set_control(struct soc_camera_device *icd, 813static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
804 struct v4l2_control *ctrl)
805{ 814{
806 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 815 struct i2c_client *client = sd->priv;
816 struct mt9m111 *mt9m111 = to_mt9m111(client);
807 const struct v4l2_queryctrl *qctrl; 817 const struct v4l2_queryctrl *qctrl;
808 int ret; 818 int ret;
809 819
810 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); 820 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
811
812 if (!qctrl) 821 if (!qctrl)
813 return -EINVAL; 822 return -EINVAL;
814 823
815 switch (ctrl->id) { 824 switch (ctrl->id) {
816 case V4L2_CID_VFLIP: 825 case V4L2_CID_VFLIP:
817 mt9m111->vflip = ctrl->value; 826 mt9m111->vflip = ctrl->value;
818 ret = mt9m111_set_flip(icd, ctrl->value, 827 ret = mt9m111_set_flip(client, ctrl->value,
819 MT9M111_RMB_MIRROR_ROWS); 828 MT9M111_RMB_MIRROR_ROWS);
820 break; 829 break;
821 case V4L2_CID_HFLIP: 830 case V4L2_CID_HFLIP:
822 mt9m111->hflip = ctrl->value; 831 mt9m111->hflip = ctrl->value;
823 ret = mt9m111_set_flip(icd, ctrl->value, 832 ret = mt9m111_set_flip(client, ctrl->value,
824 MT9M111_RMB_MIRROR_COLS); 833 MT9M111_RMB_MIRROR_COLS);
825 break; 834 break;
826 case V4L2_CID_GAIN: 835 case V4L2_CID_GAIN:
827 ret = mt9m111_set_global_gain(icd, ctrl->value); 836 ret = mt9m111_set_global_gain(client, ctrl->value);
828 break; 837 break;
829 case V4L2_CID_EXPOSURE_AUTO: 838 case V4L2_CID_EXPOSURE_AUTO:
830 ret = mt9m111_set_autoexposure(icd, ctrl->value); 839 ret = mt9m111_set_autoexposure(client, ctrl->value);
831 break; 840 break;
832 case V4L2_CID_AUTO_WHITE_BALANCE: 841 case V4L2_CID_AUTO_WHITE_BALANCE:
833 ret = mt9m111_set_autowhitebalance(icd, ctrl->value); 842 ret = mt9m111_set_autowhitebalance(client, ctrl->value);
834 break; 843 break;
835 default: 844 default:
836 ret = -EINVAL; 845 ret = -EINVAL;
@@ -839,62 +848,62 @@ static int mt9m111_set_control(struct soc_camera_device *icd,
839 return ret; 848 return ret;
840} 849}
841 850
842static int mt9m111_restore_state(struct soc_camera_device *icd) 851static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state)
843{ 852{
844 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 853 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
845 854 struct mt9m111 *mt9m111 = to_mt9m111(client);
846 mt9m111_set_context(icd, mt9m111->context); 855
847 mt9m111_set_pixfmt(icd, mt9m111->pixfmt); 856 mt9m111->gain = mt9m111_get_global_gain(client);
848 mt9m111_setup_rect(icd, &mt9m111->rect); 857
849 mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 858 return 0;
850 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); 859}
851 mt9m111_set_global_gain(icd, icd->gain); 860
852 mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 861static int mt9m111_restore_state(struct i2c_client *client)
853 mt9m111_set_autowhitebalance(icd, mt9m111->autowhitebalance); 862{
863 struct mt9m111 *mt9m111 = to_mt9m111(client);
864
865 mt9m111_set_context(client, mt9m111->context);
866 mt9m111_set_pixfmt(client, mt9m111->pixfmt);
867 mt9m111_setup_rect(client, &mt9m111->rect);
868 mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
869 mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
870 mt9m111_set_global_gain(client, mt9m111->gain);
871 mt9m111_set_autoexposure(client, mt9m111->autoexposure);
872 mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance);
854 return 0; 873 return 0;
855} 874}
856 875
857static int mt9m111_resume(struct soc_camera_device *icd) 876static int mt9m111_resume(struct soc_camera_device *icd)
858{ 877{
859 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 878 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
879 struct mt9m111 *mt9m111 = to_mt9m111(client);
860 int ret = 0; 880 int ret = 0;
861 881
862 if (mt9m111->powered) { 882 if (mt9m111->powered) {
863 ret = mt9m111_enable(icd); 883 ret = mt9m111_enable(client);
864 if (!ret) 884 if (!ret)
865 ret = mt9m111_reset(icd); 885 ret = mt9m111_reset(client);
866 if (!ret) 886 if (!ret)
867 ret = mt9m111_restore_state(icd); 887 ret = mt9m111_restore_state(client);
868 } 888 }
869 return ret; 889 return ret;
870} 890}
871 891
872static int mt9m111_init(struct soc_camera_device *icd) 892static int mt9m111_init(struct i2c_client *client)
873{ 893{
874 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 894 struct mt9m111 *mt9m111 = to_mt9m111(client);
875 int ret; 895 int ret;
876 896
877 mt9m111->context = HIGHPOWER; 897 mt9m111->context = HIGHPOWER;
878 ret = mt9m111_enable(icd); 898 ret = mt9m111_enable(client);
879 if (!ret) 899 if (!ret)
880 ret = mt9m111_reset(icd); 900 ret = mt9m111_reset(client);
881 if (!ret) 901 if (!ret)
882 ret = mt9m111_set_context(icd, mt9m111->context); 902 ret = mt9m111_set_context(client, mt9m111->context);
883 if (!ret) 903 if (!ret)
884 ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 904 ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure);
885 if (ret) 905 if (ret)
886 dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret); 906 dev_err(&client->dev, "mt9m11x init failed: %d\n", ret);
887 return ret;
888}
889
890static int mt9m111_release(struct soc_camera_device *icd)
891{
892 int ret;
893
894 ret = mt9m111_disable(icd);
895 if (ret < 0)
896 dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret);
897
898 return ret; 907 return ret;
899} 908}
900 909
@@ -902,10 +911,10 @@ static int mt9m111_release(struct soc_camera_device *icd)
902 * Interface active, can use i2c. If it fails, it can indeed mean, that 911 * Interface active, can use i2c. If it fails, it can indeed mean, that
903 * this wasn't our capture interface, so, we wait for the right one 912 * this wasn't our capture interface, so, we wait for the right one
904 */ 913 */
905static int mt9m111_video_probe(struct soc_camera_device *icd) 914static int mt9m111_video_probe(struct soc_camera_device *icd,
915 struct i2c_client *client)
906{ 916{
907 struct i2c_client *client = to_i2c_client(icd->control); 917 struct mt9m111 *mt9m111 = to_mt9m111(client);
908 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
909 s32 data; 918 s32 data;
910 int ret; 919 int ret;
911 920
@@ -917,10 +926,13 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
917 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 926 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
918 return -ENODEV; 927 return -ENODEV;
919 928
920 ret = mt9m111_enable(icd); 929 mt9m111->autoexposure = 1;
921 if (ret) 930 mt9m111->autowhitebalance = 1;
922 goto ei2c; 931
923 ret = mt9m111_reset(icd); 932 mt9m111->swap_rgb_even_odd = 1;
933 mt9m111->swap_rgb_red_blue = 1;
934
935 ret = mt9m111_init(client);
924 if (ret) 936 if (ret)
925 goto ei2c; 937 goto ei2c;
926 938
@@ -935,7 +947,7 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
935 break; 947 break;
936 default: 948 default:
937 ret = -ENODEV; 949 ret = -ENODEV;
938 dev_err(&icd->dev, 950 dev_err(&client->dev,
939 "No MT9M11x chip detected, register read %x\n", data); 951 "No MT9M11x chip detected, register read %x\n", data);
940 goto ei2c; 952 goto ei2c;
941 } 953 }
@@ -943,42 +955,51 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
943 icd->formats = mt9m111_colour_formats; 955 icd->formats = mt9m111_colour_formats;
944 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); 956 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);
945 957
946 dev_info(&icd->dev, "Detected a MT9M11x chip ID %x\n", data); 958 dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data);
947 959
948 ret = soc_camera_video_start(icd);
949 if (ret)
950 goto eisis;
951
952 mt9m111->autoexposure = 1;
953 mt9m111->autowhitebalance = 1;
954
955 mt9m111->swap_rgb_even_odd = 1;
956 mt9m111->swap_rgb_red_blue = 1;
957
958 return 0;
959eisis:
960ei2c: 960ei2c:
961 return ret; 961 return ret;
962} 962}
963 963
964static void mt9m111_video_remove(struct soc_camera_device *icd) 964static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
965{ 965 .g_ctrl = mt9m111_g_ctrl,
966 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 966 .s_ctrl = mt9m111_s_ctrl,
967 .g_chip_ident = mt9m111_g_chip_ident,
968#ifdef CONFIG_VIDEO_ADV_DEBUG
969 .g_register = mt9m111_g_register,
970 .s_register = mt9m111_s_register,
971#endif
972};
967 973
968 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr, 974static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
969 mt9m111->icd.dev.parent, mt9m111->icd.vdev); 975 .s_fmt = mt9m111_s_fmt,
970 soc_camera_video_stop(&mt9m111->icd); 976 .g_fmt = mt9m111_g_fmt,
971} 977 .try_fmt = mt9m111_try_fmt,
978 .s_crop = mt9m111_s_crop,
979 .g_crop = mt9m111_g_crop,
980 .cropcap = mt9m111_cropcap,
981};
982
983static struct v4l2_subdev_ops mt9m111_subdev_ops = {
984 .core = &mt9m111_subdev_core_ops,
985 .video = &mt9m111_subdev_video_ops,
986};
972 987
973static int mt9m111_probe(struct i2c_client *client, 988static int mt9m111_probe(struct i2c_client *client,
974 const struct i2c_device_id *did) 989 const struct i2c_device_id *did)
975{ 990{
976 struct mt9m111 *mt9m111; 991 struct mt9m111 *mt9m111;
977 struct soc_camera_device *icd; 992 struct soc_camera_device *icd = client->dev.platform_data;
978 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 993 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
979 struct soc_camera_link *icl = client->dev.platform_data; 994 struct soc_camera_link *icl;
980 int ret; 995 int ret;
981 996
997 if (!icd) {
998 dev_err(&client->dev, "MT9M11x: missing soc-camera data!\n");
999 return -EINVAL;
1000 }
1001
1002 icl = to_soc_camera_link(icd);
982 if (!icl) { 1003 if (!icl) {
983 dev_err(&client->dev, "MT9M11x driver needs platform data\n"); 1004 dev_err(&client->dev, "MT9M11x driver needs platform data\n");
984 return -EINVAL; 1005 return -EINVAL;
@@ -994,38 +1015,35 @@ static int mt9m111_probe(struct i2c_client *client,
994 if (!mt9m111) 1015 if (!mt9m111)
995 return -ENOMEM; 1016 return -ENOMEM;
996 1017
997 mt9m111->client = client; 1018 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
998 i2c_set_clientdata(client, mt9m111);
999 1019
1000 /* Second stage probe - when a capture adapter is there */ 1020 /* Second stage probe - when a capture adapter is there */
1001 icd = &mt9m111->icd; 1021 icd->ops = &mt9m111_ops;
1002 icd->ops = &mt9m111_ops; 1022 icd->y_skip_top = 0;
1003 icd->control = &client->dev; 1023
1004 icd->x_min = MT9M111_MIN_DARK_COLS; 1024 mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
1005 icd->y_min = MT9M111_MIN_DARK_ROWS; 1025 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
1006 icd->x_current = icd->x_min; 1026 mt9m111->rect.width = MT9M111_MAX_WIDTH;
1007 icd->y_current = icd->y_min; 1027 mt9m111->rect.height = MT9M111_MAX_HEIGHT;
1008 icd->width_min = MT9M111_MIN_DARK_ROWS; 1028
1009 icd->width_max = MT9M111_MAX_WIDTH; 1029 ret = mt9m111_video_probe(icd, client);
1010 icd->height_min = MT9M111_MIN_DARK_COLS; 1030 if (ret) {
1011 icd->height_max = MT9M111_MAX_HEIGHT; 1031 icd->ops = NULL;
1012 icd->y_skip_top = 0; 1032 i2c_set_clientdata(client, NULL);
1013 icd->iface = icl->bus_id; 1033 kfree(mt9m111);
1014 1034 }
1015 ret = soc_camera_device_register(icd);
1016 if (ret)
1017 goto eisdr;
1018 return 0;
1019 1035
1020eisdr:
1021 kfree(mt9m111);
1022 return ret; 1036 return ret;
1023} 1037}
1024 1038
1025static int mt9m111_remove(struct i2c_client *client) 1039static int mt9m111_remove(struct i2c_client *client)
1026{ 1040{
1027 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 1041 struct mt9m111 *mt9m111 = to_mt9m111(client);
1028 soc_camera_device_unregister(&mt9m111->icd); 1042 struct soc_camera_device *icd = client->dev.platform_data;
1043
1044 icd->ops = NULL;
1045 i2c_set_clientdata(client, NULL);
1046 client->driver = NULL;
1029 kfree(mt9m111); 1047 kfree(mt9m111);
1030 1048
1031 return 0; 1049 return 0;