aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9m111.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:43:33 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:35 -0400
commit979ea1ddf80ac7383acdea03471355ca62702539 (patch)
tree2ee4c73eb672c1ee8167ed7e0906bac6f3b00e69 /drivers/media/video/mt9m111.c
parent0bab829de1ab60d8c3cbf7e402192bb9446840b7 (diff)
V4L/DVB (12510): soc-camera: (partially) convert to v4l2-(sub)dev API
Convert the soc-camera framework to use the v4l2-(sub)dev API. Start using v4l2-subdev operations. Only a part of the interface between the soc_camera core, soc_camera host drivers on one side and soc_camera device drivers on the other side is replaced so far. The rest of the interface will be replaced in incremental steps, and will require extensions and, possibly, modifications to the v4l2-subdev code. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
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 95c2f089605..29f976afd46 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;