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.c309
1 files changed, 129 insertions, 180 deletions
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 95c2f089605f..29f976afd465 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -148,6 +148,7 @@ enum mt9m111_context {
148}; 148};
149 149
150struct mt9m111 { 150struct mt9m111 {
151 struct v4l2_subdev subdev;
151 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ 152 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
152 enum mt9m111_context context; 153 enum mt9m111_context context;
153 struct v4l2_rect rect; 154 struct v4l2_rect rect;
@@ -164,6 +165,11 @@ struct mt9m111 {
164 unsigned int autowhitebalance:1; 165 unsigned int autowhitebalance:1;
165}; 166};
166 167
168static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
169{
170 return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
171}
172
167static int reg_page_map_set(struct i2c_client *client, const u16 reg) 173static int reg_page_map_set(struct i2c_client *client, const u16 reg)
168{ 174{
169 int ret; 175 int ret;
@@ -227,10 +233,9 @@ static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
227 return mt9m111_reg_write(client, reg, ret & ~data); 233 return mt9m111_reg_write(client, reg, ret & ~data);
228} 234}
229 235
230static int mt9m111_set_context(struct soc_camera_device *icd, 236static int mt9m111_set_context(struct i2c_client *client,
231 enum mt9m111_context ctxt) 237 enum mt9m111_context ctxt)
232{ 238{
233 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
234 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B 239 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
235 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B 240 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
236 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B 241 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -244,11 +249,10 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
244 return reg_write(CONTEXT_CONTROL, valA); 249 return reg_write(CONTEXT_CONTROL, valA);
245} 250}
246 251
247static int mt9m111_setup_rect(struct soc_camera_device *icd, 252static int mt9m111_setup_rect(struct i2c_client *client,
248 struct v4l2_rect *rect) 253 struct v4l2_rect *rect)
249{ 254{
250 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 255 struct mt9m111 *mt9m111 = to_mt9m111(client);
251 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
252 int ret, is_raw_format; 256 int ret, is_raw_format;
253 int width = rect->width; 257 int width = rect->width;
254 int height = rect->height; 258 int height = rect->height;
@@ -290,9 +294,8 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
290 return ret; 294 return ret;
291} 295}
292 296
293static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) 297static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
294{ 298{
295 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
296 int ret; 299 int ret;
297 300
298 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); 301 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -301,20 +304,19 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
301 return ret; 304 return ret;
302} 305}
303 306
304static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) 307static int mt9m111_setfmt_bayer8(struct i2c_client *client)
305{ 308{
306 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); 309 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
307} 310}
308 311
309static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) 312static int mt9m111_setfmt_bayer10(struct i2c_client *client)
310{ 313{
311 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); 314 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP);
312} 315}
313 316
314static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) 317static int mt9m111_setfmt_rgb565(struct i2c_client *client)
315{ 318{
316 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 319 struct mt9m111 *mt9m111 = to_mt9m111(client);
317 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
318 int val = 0; 320 int val = 0;
319 321
320 if (mt9m111->swap_rgb_red_blue) 322 if (mt9m111->swap_rgb_red_blue)
@@ -323,13 +325,12 @@ static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd)
323 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 325 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
324 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; 326 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;
325 327
326 return mt9m111_setup_pixfmt(icd, val); 328 return mt9m111_setup_pixfmt(client, val);
327} 329}
328 330
329static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) 331static int mt9m111_setfmt_rgb555(struct i2c_client *client)
330{ 332{
331 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 333 struct mt9m111 *mt9m111 = to_mt9m111(client);
332 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
333 int val = 0; 334 int val = 0;
334 335
335 if (mt9m111->swap_rgb_red_blue) 336 if (mt9m111->swap_rgb_red_blue)
@@ -338,13 +339,12 @@ static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd)
338 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 339 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
339 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; 340 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;
340 341
341 return mt9m111_setup_pixfmt(icd, val); 342 return mt9m111_setup_pixfmt(client, val);
342} 343}
343 344
344static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) 345static int mt9m111_setfmt_yuv(struct i2c_client *client)
345{ 346{
346 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 347 struct mt9m111 *mt9m111 = to_mt9m111(client);
347 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
348 int val = 0; 348 int val = 0;
349 349
350 if (mt9m111->swap_yuv_cb_cr) 350 if (mt9m111->swap_yuv_cb_cr)
@@ -352,52 +352,22 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
352 if (mt9m111->swap_yuv_y_chromas) 352 if (mt9m111->swap_yuv_y_chromas)
353 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; 353 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
354 354
355 return mt9m111_setup_pixfmt(icd, val); 355 return mt9m111_setup_pixfmt(client, val);
356} 356}
357 357
358static int mt9m111_enable(struct soc_camera_device *icd) 358static int mt9m111_enable(struct i2c_client *client)
359{ 359{
360 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 360 struct mt9m111 *mt9m111 = to_mt9m111(client);
361 struct soc_camera_link *icl = to_soc_camera_link(icd);
362 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
363 int ret; 361 int ret;
364 362
365 if (icl->power) {
366 ret = icl->power(&client->dev, 1);
367 if (ret < 0) {
368 dev_err(icd->vdev->parent,
369 "Platform failed to power-on the camera.\n");
370 return ret;
371 }
372 }
373
374 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); 363 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
375 if (!ret) 364 if (!ret)
376 mt9m111->powered = 1; 365 mt9m111->powered = 1;
377 return ret; 366 return ret;
378} 367}
379 368
380static int mt9m111_disable(struct soc_camera_device *icd) 369static int mt9m111_reset(struct i2c_client *client)
381{
382 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
383 struct soc_camera_link *icl = to_soc_camera_link(icd);
384 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
385 int ret;
386
387 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
388 if (!ret)
389 mt9m111->powered = 0;
390
391 if (icl->power)
392 icl->power(&client->dev, 0);
393
394 return ret;
395}
396
397static int mt9m111_reset(struct soc_camera_device *icd)
398{ 370{
399 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
400 struct soc_camera_link *icl = to_soc_camera_link(icd);
401 int ret; 371 int ret;
402 372
403 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); 373 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -407,22 +377,9 @@ static int mt9m111_reset(struct soc_camera_device *icd)
407 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE 377 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
408 | MT9M111_RESET_RESET_SOC); 378 | MT9M111_RESET_RESET_SOC);
409 379
410 if (icl->reset)
411 icl->reset(&client->dev);
412
413 return ret; 380 return ret;
414} 381}
415 382
416static int mt9m111_start_capture(struct soc_camera_device *icd)
417{
418 return 0;
419}
420
421static int mt9m111_stop_capture(struct soc_camera_device *icd)
422{
423 return 0;
424}
425
426static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) 383static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
427{ 384{
428 struct soc_camera_link *icl = to_soc_camera_link(icd); 385 struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -442,60 +399,59 @@ static int mt9m111_set_crop(struct soc_camera_device *icd,
442 struct v4l2_rect *rect) 399 struct v4l2_rect *rect)
443{ 400{
444 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 401 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
445 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 402 struct mt9m111 *mt9m111 = to_mt9m111(client);
446 int ret; 403 int ret;
447 404
448 dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n", 405 dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
449 __func__, rect->left, rect->top, rect->width, 406 __func__, rect->left, rect->top, rect->width,
450 rect->height); 407 rect->height);
451 408
452 ret = mt9m111_setup_rect(icd, rect); 409 ret = mt9m111_setup_rect(client, rect);
453 if (!ret) 410 if (!ret)
454 mt9m111->rect = *rect; 411 mt9m111->rect = *rect;
455 return ret; 412 return ret;
456} 413}
457 414
458static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) 415static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
459{ 416{
460 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 417 struct mt9m111 *mt9m111 = to_mt9m111(client);
461 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
462 int ret; 418 int ret;
463 419
464 switch (pixfmt) { 420 switch (pixfmt) {
465 case V4L2_PIX_FMT_SBGGR8: 421 case V4L2_PIX_FMT_SBGGR8:
466 ret = mt9m111_setfmt_bayer8(icd); 422 ret = mt9m111_setfmt_bayer8(client);
467 break; 423 break;
468 case V4L2_PIX_FMT_SBGGR16: 424 case V4L2_PIX_FMT_SBGGR16:
469 ret = mt9m111_setfmt_bayer10(icd); 425 ret = mt9m111_setfmt_bayer10(client);
470 break; 426 break;
471 case V4L2_PIX_FMT_RGB555: 427 case V4L2_PIX_FMT_RGB555:
472 ret = mt9m111_setfmt_rgb555(icd); 428 ret = mt9m111_setfmt_rgb555(client);
473 break; 429 break;
474 case V4L2_PIX_FMT_RGB565: 430 case V4L2_PIX_FMT_RGB565:
475 ret = mt9m111_setfmt_rgb565(icd); 431 ret = mt9m111_setfmt_rgb565(client);
476 break; 432 break;
477 case V4L2_PIX_FMT_UYVY: 433 case V4L2_PIX_FMT_UYVY:
478 mt9m111->swap_yuv_y_chromas = 0; 434 mt9m111->swap_yuv_y_chromas = 0;
479 mt9m111->swap_yuv_cb_cr = 0; 435 mt9m111->swap_yuv_cb_cr = 0;
480 ret = mt9m111_setfmt_yuv(icd); 436 ret = mt9m111_setfmt_yuv(client);
481 break; 437 break;
482 case V4L2_PIX_FMT_VYUY: 438 case V4L2_PIX_FMT_VYUY:
483 mt9m111->swap_yuv_y_chromas = 0; 439 mt9m111->swap_yuv_y_chromas = 0;
484 mt9m111->swap_yuv_cb_cr = 1; 440 mt9m111->swap_yuv_cb_cr = 1;
485 ret = mt9m111_setfmt_yuv(icd); 441 ret = mt9m111_setfmt_yuv(client);
486 break; 442 break;
487 case V4L2_PIX_FMT_YUYV: 443 case V4L2_PIX_FMT_YUYV:
488 mt9m111->swap_yuv_y_chromas = 1; 444 mt9m111->swap_yuv_y_chromas = 1;
489 mt9m111->swap_yuv_cb_cr = 0; 445 mt9m111->swap_yuv_cb_cr = 0;
490 ret = mt9m111_setfmt_yuv(icd); 446 ret = mt9m111_setfmt_yuv(client);
491 break; 447 break;
492 case V4L2_PIX_FMT_YVYU: 448 case V4L2_PIX_FMT_YVYU:
493 mt9m111->swap_yuv_y_chromas = 1; 449 mt9m111->swap_yuv_y_chromas = 1;
494 mt9m111->swap_yuv_cb_cr = 1; 450 mt9m111->swap_yuv_cb_cr = 1;
495 ret = mt9m111_setfmt_yuv(icd); 451 ret = mt9m111_setfmt_yuv(client);
496 break; 452 break;
497 default: 453 default:
498 dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); 454 dev_err(&client->dev, "Pixel format not handled : %x\n", pixfmt);
499 ret = -EINVAL; 455 ret = -EINVAL;
500 } 456 }
501 457
@@ -505,11 +461,10 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
505 return ret; 461 return ret;
506} 462}
507 463
508static int mt9m111_set_fmt(struct soc_camera_device *icd, 464static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
509 struct v4l2_format *f)
510{ 465{
511 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 466 struct i2c_client *client = sd->priv;
512 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 467 struct mt9m111 *mt9m111 = to_mt9m111(client);
513 struct v4l2_pix_format *pix = &f->fmt.pix; 468 struct v4l2_pix_format *pix = &f->fmt.pix;
514 struct v4l2_rect rect = { 469 struct v4l2_rect rect = {
515 .left = mt9m111->rect.left, 470 .left = mt9m111->rect.left,
@@ -519,20 +474,19 @@ static int mt9m111_set_fmt(struct soc_camera_device *icd,
519 }; 474 };
520 int ret; 475 int ret;
521 476
522 dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", 477 dev_dbg(&client->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
523 __func__, pix->pixelformat, rect.left, rect.top, rect.width, 478 __func__, pix->pixelformat, rect.left, rect.top, rect.width,
524 rect.height); 479 rect.height);
525 480
526 ret = mt9m111_setup_rect(icd, &rect); 481 ret = mt9m111_setup_rect(client, &rect);
527 if (!ret) 482 if (!ret)
528 ret = mt9m111_set_pixfmt(icd, pix->pixelformat); 483 ret = mt9m111_set_pixfmt(client, pix->pixelformat);
529 if (!ret) 484 if (!ret)
530 mt9m111->rect = rect; 485 mt9m111->rect = rect;
531 return ret; 486 return ret;
532} 487}
533 488
534static int mt9m111_try_fmt(struct soc_camera_device *icd, 489static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
535 struct v4l2_format *f)
536{ 490{
537 struct v4l2_pix_format *pix = &f->fmt.pix; 491 struct v4l2_pix_format *pix = &f->fmt.pix;
538 492
@@ -544,11 +498,11 @@ static int mt9m111_try_fmt(struct soc_camera_device *icd,
544 return 0; 498 return 0;
545} 499}
546 500
547static int mt9m111_get_chip_id(struct soc_camera_device *icd, 501static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
548 struct v4l2_dbg_chip_ident *id) 502 struct v4l2_dbg_chip_ident *id)
549{ 503{
550 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 504 struct i2c_client *client = sd->priv;
551 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 505 struct mt9m111 *mt9m111 = to_mt9m111(client);
552 506
553 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 507 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
554 return -EINVAL; 508 return -EINVAL;
@@ -563,10 +517,10 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd,
563} 517}
564 518
565#ifdef CONFIG_VIDEO_ADV_DEBUG 519#ifdef CONFIG_VIDEO_ADV_DEBUG
566static int mt9m111_get_register(struct soc_camera_device *icd, 520static int mt9m111_g_register(struct v4l2_subdev *sd,
567 struct v4l2_dbg_register *reg) 521 struct v4l2_dbg_register *reg)
568{ 522{
569 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 523 struct i2c_client *client = sd->priv;
570 int val; 524 int val;
571 525
572 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 526 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
@@ -584,10 +538,10 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
584 return 0; 538 return 0;
585} 539}
586 540
587static int mt9m111_set_register(struct soc_camera_device *icd, 541static int mt9m111_s_register(struct v4l2_subdev *sd,
588 struct v4l2_dbg_register *reg) 542 struct v4l2_dbg_register *reg)
589{ 543{
590 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 544 struct i2c_client *client = sd->priv;
591 545
592 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 546 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
593 return -EINVAL; 547 return -EINVAL;
@@ -639,41 +593,24 @@ static const struct v4l2_queryctrl mt9m111_controls[] = {
639 } 593 }
640}; 594};
641 595
642static int mt9m111_get_control(struct soc_camera_device *,
643 struct v4l2_control *);
644static int mt9m111_set_control(struct soc_camera_device *,
645 struct v4l2_control *);
646static int mt9m111_resume(struct soc_camera_device *icd); 596static int mt9m111_resume(struct soc_camera_device *icd);
647static int mt9m111_init(struct soc_camera_device *icd); 597static int mt9m111_init(struct soc_camera_device *icd);
648static int mt9m111_release(struct soc_camera_device *icd); 598static int mt9m111_release(struct soc_camera_device *icd);
649 599
650static struct soc_camera_ops mt9m111_ops = { 600static struct soc_camera_ops mt9m111_ops = {
651 .owner = THIS_MODULE,
652 .init = mt9m111_init, 601 .init = mt9m111_init,
653 .resume = mt9m111_resume, 602 .resume = mt9m111_resume,
654 .release = mt9m111_release, 603 .release = mt9m111_release,
655 .start_capture = mt9m111_start_capture,
656 .stop_capture = mt9m111_stop_capture,
657 .set_crop = mt9m111_set_crop, 604 .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, 605 .query_bus_param = mt9m111_query_bus_param,
661 .set_bus_param = mt9m111_set_bus_param, 606 .set_bus_param = mt9m111_set_bus_param,
662 .controls = mt9m111_controls, 607 .controls = mt9m111_controls,
663 .num_controls = ARRAY_SIZE(mt9m111_controls), 608 .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}; 609};
672 610
673static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) 611static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask)
674{ 612{
675 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 613 struct mt9m111 *mt9m111 = to_mt9m111(client);
676 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
677 int ret; 614 int ret;
678 615
679 if (mt9m111->context == HIGHPOWER) { 616 if (mt9m111->context == HIGHPOWER) {
@@ -691,9 +628,8 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
691 return ret; 628 return ret;
692} 629}
693 630
694static int mt9m111_get_global_gain(struct soc_camera_device *icd) 631static int mt9m111_get_global_gain(struct i2c_client *client)
695{ 632{
696 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
697 int data; 633 int data;
698 634
699 data = reg_read(GLOBAL_GAIN); 635 data = reg_read(GLOBAL_GAIN);
@@ -703,9 +639,9 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
703 return data; 639 return data;
704} 640}
705 641
706static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) 642static int mt9m111_set_global_gain(struct i2c_client *client, int gain)
707{ 643{
708 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 644 struct soc_camera_device *icd = client->dev.platform_data;
709 u16 val; 645 u16 val;
710 646
711 if (gain > 63 * 2 * 2) 647 if (gain > 63 * 2 * 2)
@@ -722,10 +658,9 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
722 return reg_write(GLOBAL_GAIN, val); 658 return reg_write(GLOBAL_GAIN, val);
723} 659}
724 660
725static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) 661static int mt9m111_set_autoexposure(struct i2c_client *client, int on)
726{ 662{
727 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 663 struct mt9m111 *mt9m111 = to_mt9m111(client);
728 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
729 int ret; 664 int ret;
730 665
731 if (on) 666 if (on)
@@ -739,10 +674,9 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
739 return ret; 674 return ret;
740} 675}
741 676
742static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) 677static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on)
743{ 678{
744 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 679 struct mt9m111 *mt9m111 = to_mt9m111(client);
745 struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
746 int ret; 680 int ret;
747 681
748 if (on) 682 if (on)
@@ -756,11 +690,10 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
756 return ret; 690 return ret;
757} 691}
758 692
759static int mt9m111_get_control(struct soc_camera_device *icd, 693static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
760 struct v4l2_control *ctrl)
761{ 694{
762 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 695 struct i2c_client *client = sd->priv;
763 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 696 struct mt9m111 *mt9m111 = to_mt9m111(client);
764 int data; 697 int data;
765 698
766 switch (ctrl->id) { 699 switch (ctrl->id) {
@@ -785,7 +718,7 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
785 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); 718 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
786 break; 719 break;
787 case V4L2_CID_GAIN: 720 case V4L2_CID_GAIN:
788 data = mt9m111_get_global_gain(icd); 721 data = mt9m111_get_global_gain(client);
789 if (data < 0) 722 if (data < 0)
790 return data; 723 return data;
791 ctrl->value = data; 724 ctrl->value = data;
@@ -800,38 +733,36 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
800 return 0; 733 return 0;
801} 734}
802 735
803static int mt9m111_set_control(struct soc_camera_device *icd, 736static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
804 struct v4l2_control *ctrl)
805{ 737{
806 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 738 struct i2c_client *client = sd->priv;
807 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 739 struct mt9m111 *mt9m111 = to_mt9m111(client);
808 const struct v4l2_queryctrl *qctrl; 740 const struct v4l2_queryctrl *qctrl;
809 int ret; 741 int ret;
810 742
811 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); 743 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
812
813 if (!qctrl) 744 if (!qctrl)
814 return -EINVAL; 745 return -EINVAL;
815 746
816 switch (ctrl->id) { 747 switch (ctrl->id) {
817 case V4L2_CID_VFLIP: 748 case V4L2_CID_VFLIP:
818 mt9m111->vflip = ctrl->value; 749 mt9m111->vflip = ctrl->value;
819 ret = mt9m111_set_flip(icd, ctrl->value, 750 ret = mt9m111_set_flip(client, ctrl->value,
820 MT9M111_RMB_MIRROR_ROWS); 751 MT9M111_RMB_MIRROR_ROWS);
821 break; 752 break;
822 case V4L2_CID_HFLIP: 753 case V4L2_CID_HFLIP:
823 mt9m111->hflip = ctrl->value; 754 mt9m111->hflip = ctrl->value;
824 ret = mt9m111_set_flip(icd, ctrl->value, 755 ret = mt9m111_set_flip(client, ctrl->value,
825 MT9M111_RMB_MIRROR_COLS); 756 MT9M111_RMB_MIRROR_COLS);
826 break; 757 break;
827 case V4L2_CID_GAIN: 758 case V4L2_CID_GAIN:
828 ret = mt9m111_set_global_gain(icd, ctrl->value); 759 ret = mt9m111_set_global_gain(client, ctrl->value);
829 break; 760 break;
830 case V4L2_CID_EXPOSURE_AUTO: 761 case V4L2_CID_EXPOSURE_AUTO:
831 ret = mt9m111_set_autoexposure(icd, ctrl->value); 762 ret = mt9m111_set_autoexposure(client, ctrl->value);
832 break; 763 break;
833 case V4L2_CID_AUTO_WHITE_BALANCE: 764 case V4L2_CID_AUTO_WHITE_BALANCE:
834 ret = mt9m111_set_autowhitebalance(icd, ctrl->value); 765 ret = mt9m111_set_autowhitebalance(client, ctrl->value);
835 break; 766 break;
836 default: 767 default:
837 ret = -EINVAL; 768 ret = -EINVAL;
@@ -840,34 +771,34 @@ static int mt9m111_set_control(struct soc_camera_device *icd,
840 return ret; 771 return ret;
841} 772}
842 773
843static int mt9m111_restore_state(struct soc_camera_device *icd) 774static int mt9m111_restore_state(struct i2c_client *client)
844{ 775{
845 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 776 struct mt9m111 *mt9m111 = to_mt9m111(client);
846 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 777 struct soc_camera_device *icd = client->dev.platform_data;
847 778
848 mt9m111_set_context(icd, mt9m111->context); 779 mt9m111_set_context(client, mt9m111->context);
849 mt9m111_set_pixfmt(icd, mt9m111->pixfmt); 780 mt9m111_set_pixfmt(client, mt9m111->pixfmt);
850 mt9m111_setup_rect(icd, &mt9m111->rect); 781 mt9m111_setup_rect(client, &mt9m111->rect);
851 mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 782 mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
852 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); 783 mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
853 mt9m111_set_global_gain(icd, icd->gain); 784 mt9m111_set_global_gain(client, icd->gain);
854 mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 785 mt9m111_set_autoexposure(client, mt9m111->autoexposure);
855 mt9m111_set_autowhitebalance(icd, mt9m111->autowhitebalance); 786 mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance);
856 return 0; 787 return 0;
857} 788}
858 789
859static int mt9m111_resume(struct soc_camera_device *icd) 790static int mt9m111_resume(struct soc_camera_device *icd)
860{ 791{
861 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 792 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
862 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 793 struct mt9m111 *mt9m111 = to_mt9m111(client);
863 int ret = 0; 794 int ret = 0;
864 795
865 if (mt9m111->powered) { 796 if (mt9m111->powered) {
866 ret = mt9m111_enable(icd); 797 ret = mt9m111_enable(client);
867 if (!ret) 798 if (!ret)
868 ret = mt9m111_reset(icd); 799 ret = mt9m111_reset(client);
869 if (!ret) 800 if (!ret)
870 ret = mt9m111_restore_state(icd); 801 ret = mt9m111_restore_state(client);
871 } 802 }
872 return ret; 803 return ret;
873} 804}
@@ -875,17 +806,17 @@ static int mt9m111_resume(struct soc_camera_device *icd)
875static int mt9m111_init(struct soc_camera_device *icd) 806static int mt9m111_init(struct soc_camera_device *icd)
876{ 807{
877 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 808 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
878 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 809 struct mt9m111 *mt9m111 = to_mt9m111(client);
879 int ret; 810 int ret;
880 811
881 mt9m111->context = HIGHPOWER; 812 mt9m111->context = HIGHPOWER;
882 ret = mt9m111_enable(icd); 813 ret = mt9m111_enable(client);
883 if (!ret) 814 if (!ret)
884 ret = mt9m111_reset(icd); 815 ret = mt9m111_reset(client);
885 if (!ret) 816 if (!ret)
886 ret = mt9m111_set_context(icd, mt9m111->context); 817 ret = mt9m111_set_context(client, mt9m111->context);
887 if (!ret) 818 if (!ret)
888 ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 819 ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure);
889 if (ret) 820 if (ret)
890 dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret); 821 dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret);
891 return ret; 822 return ret;
@@ -893,9 +824,14 @@ static int mt9m111_init(struct soc_camera_device *icd)
893 824
894static int mt9m111_release(struct soc_camera_device *icd) 825static int mt9m111_release(struct soc_camera_device *icd)
895{ 826{
827 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
828 struct mt9m111 *mt9m111 = to_mt9m111(client);
896 int ret; 829 int ret;
897 830
898 ret = mt9m111_disable(icd); 831 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
832 if (!ret)
833 mt9m111->powered = 0;
834
899 if (ret < 0) 835 if (ret < 0)
900 dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret); 836 dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret);
901 837
@@ -909,7 +845,7 @@ static int mt9m111_release(struct soc_camera_device *icd)
909static int mt9m111_video_probe(struct soc_camera_device *icd, 845static int mt9m111_video_probe(struct soc_camera_device *icd,
910 struct i2c_client *client) 846 struct i2c_client *client)
911{ 847{
912 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 848 struct mt9m111 *mt9m111 = to_mt9m111(client);
913 s32 data; 849 s32 data;
914 int ret; 850 int ret;
915 851
@@ -921,15 +857,10 @@ static int mt9m111_video_probe(struct soc_camera_device *icd,
921 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 857 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
922 return -ENODEV; 858 return -ENODEV;
923 859
924 /* Switch master clock on */ 860 ret = mt9m111_enable(client);
925 ret = soc_camera_video_start(icd, &client->dev);
926 if (ret)
927 goto evstart;
928
929 ret = mt9m111_enable(icd);
930 if (ret) 861 if (ret)
931 goto ei2c; 862 goto ei2c;
932 ret = mt9m111_reset(icd); 863 ret = mt9m111_reset(client);
933 if (ret) 864 if (ret)
934 goto ei2c; 865 goto ei2c;
935 866
@@ -961,11 +892,29 @@ static int mt9m111_video_probe(struct soc_camera_device *icd,
961 mt9m111->swap_rgb_red_blue = 1; 892 mt9m111->swap_rgb_red_blue = 1;
962 893
963ei2c: 894ei2c:
964 soc_camera_video_stop(icd);
965evstart:
966 return ret; 895 return ret;
967} 896}
968 897
898static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
899 .g_ctrl = mt9m111_g_ctrl,
900 .s_ctrl = mt9m111_s_ctrl,
901 .g_chip_ident = mt9m111_g_chip_ident,
902#ifdef CONFIG_VIDEO_ADV_DEBUG
903 .g_register = mt9m111_g_register,
904 .s_register = mt9m111_s_register,
905#endif
906};
907
908static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
909 .s_fmt = mt9m111_s_fmt,
910 .try_fmt = mt9m111_try_fmt,
911};
912
913static struct v4l2_subdev_ops mt9m111_subdev_ops = {
914 .core = &mt9m111_subdev_core_ops,
915 .video = &mt9m111_subdev_video_ops,
916};
917
969static int mt9m111_probe(struct i2c_client *client, 918static int mt9m111_probe(struct i2c_client *client,
970 const struct i2c_device_id *did) 919 const struct i2c_device_id *did)
971{ 920{
@@ -996,7 +945,7 @@ static int mt9m111_probe(struct i2c_client *client,
996 if (!mt9m111) 945 if (!mt9m111)
997 return -ENOMEM; 946 return -ENOMEM;
998 947
999 i2c_set_clientdata(client, mt9m111); 948 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
1000 949
1001 /* Second stage probe - when a capture adapter is there */ 950 /* Second stage probe - when a capture adapter is there */
1002 icd->ops = &mt9m111_ops; 951 icd->ops = &mt9m111_ops;
@@ -1022,7 +971,7 @@ static int mt9m111_probe(struct i2c_client *client,
1022 971
1023static int mt9m111_remove(struct i2c_client *client) 972static int mt9m111_remove(struct i2c_client *client)
1024{ 973{
1025 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 974 struct mt9m111 *mt9m111 = to_mt9m111(client);
1026 struct soc_camera_device *icd = client->dev.platform_data; 975 struct soc_camera_device *icd = client->dev.platform_data;
1027 976
1028 icd->ops = NULL; 977 icd->ops = NULL;