aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9v022.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mt9v022.c')
-rw-r--r--drivers/media/video/mt9v022.c448
1 files changed, 186 insertions, 262 deletions
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 51b0fccbfe7..690ee0d42ee 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -13,10 +13,13 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16#include <linux/module.h>
16 17
18#include <media/soc_camera.h>
19#include <media/soc_mediabus.h>
17#include <media/v4l2-subdev.h> 20#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h> 21#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h> 22#include <media/v4l2-ctrls.h>
20 23
21/* 24/*
22 * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c 25 * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
@@ -100,6 +103,17 @@ static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
100 103
101struct mt9v022 { 104struct mt9v022 {
102 struct v4l2_subdev subdev; 105 struct v4l2_subdev subdev;
106 struct v4l2_ctrl_handler hdl;
107 struct {
108 /* exposure/auto-exposure cluster */
109 struct v4l2_ctrl *autoexposure;
110 struct v4l2_ctrl *exposure;
111 };
112 struct {
113 /* gain/auto-gain cluster */
114 struct v4l2_ctrl *autogain;
115 struct v4l2_ctrl *gain;
116 };
103 struct v4l2_rect rect; /* Sensor window */ 117 struct v4l2_rect rect; /* Sensor window */
104 const struct mt9v022_datafmt *fmt; 118 const struct mt9v022_datafmt *fmt;
105 const struct mt9v022_datafmt *fmts; 119 const struct mt9v022_datafmt *fmts;
@@ -178,6 +192,8 @@ static int mt9v022_init(struct i2c_client *client)
178 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); 192 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
179 if (!ret) 193 if (!ret)
180 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0); 194 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
195 if (!ret)
196 return v4l2_ctrl_handler_setup(&mt9v022->hdl);
181 197
182 return ret; 198 return ret;
183} 199}
@@ -199,78 +215,6 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
199 return 0; 215 return 0;
200} 216}
201 217
202static int mt9v022_set_bus_param(struct soc_camera_device *icd,
203 unsigned long flags)
204{
205 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
206 struct mt9v022 *mt9v022 = to_mt9v022(client);
207 struct soc_camera_link *icl = to_soc_camera_link(icd);
208 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
209 int ret;
210 u16 pixclk = 0;
211
212 /* Only one width bit may be set */
213 if (!is_power_of_2(width_flag))
214 return -EINVAL;
215
216 if (icl->set_bus_param) {
217 ret = icl->set_bus_param(icl, width_flag);
218 if (ret)
219 return ret;
220 } else {
221 /*
222 * Without board specific bus width settings we only support the
223 * sensors native bus width
224 */
225 if (width_flag != SOCAM_DATAWIDTH_10)
226 return -EINVAL;
227 }
228
229 flags = soc_camera_apply_sensor_flags(icl, flags);
230
231 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
232 pixclk |= 0x10;
233
234 if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
235 pixclk |= 0x1;
236
237 if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
238 pixclk |= 0x2;
239
240 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
241 if (ret < 0)
242 return ret;
243
244 if (!(flags & SOCAM_MASTER))
245 mt9v022->chip_control &= ~0x8;
246
247 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
248 if (ret < 0)
249 return ret;
250
251 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
252 pixclk, mt9v022->chip_control);
253
254 return 0;
255}
256
257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
258{
259 struct soc_camera_link *icl = to_soc_camera_link(icd);
260 unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
261 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
262 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
263 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
264 SOCAM_DATA_ACTIVE_HIGH;
265
266 if (icl->query_bus_param)
267 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
268 else
269 flags |= SOCAM_DATAWIDTH_10;
270
271 return soc_camera_apply_sensor_flags(icl, flags);
272}
273
274static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 218static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
275{ 219{
276 struct i2c_client *client = v4l2_get_subdevdata(sd); 220 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -389,7 +333,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
389 333
390 /* 334 /*
391 * The caller provides a supported format, as verified per call to 335 * The caller provides a supported format, as verified per call to
392 * icd->try_fmt(), datawidth is from our supported format list 336 * .try_mbus_fmt(), datawidth is from our supported format list
393 */ 337 */
394 switch (mf->code) { 338 switch (mf->code) {
395 case V4L2_MBUS_FMT_Y8_1X8: 339 case V4L2_MBUS_FMT_Y8_1X8:
@@ -502,236 +446,131 @@ static int mt9v022_s_register(struct v4l2_subdev *sd,
502} 446}
503#endif 447#endif
504 448
505static const struct v4l2_queryctrl mt9v022_controls[] = { 449static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
506 {
507 .id = V4L2_CID_VFLIP,
508 .type = V4L2_CTRL_TYPE_BOOLEAN,
509 .name = "Flip Vertically",
510 .minimum = 0,
511 .maximum = 1,
512 .step = 1,
513 .default_value = 0,
514 }, {
515 .id = V4L2_CID_HFLIP,
516 .type = V4L2_CTRL_TYPE_BOOLEAN,
517 .name = "Flip Horizontally",
518 .minimum = 0,
519 .maximum = 1,
520 .step = 1,
521 .default_value = 0,
522 }, {
523 .id = V4L2_CID_GAIN,
524 .type = V4L2_CTRL_TYPE_INTEGER,
525 .name = "Analog Gain",
526 .minimum = 64,
527 .maximum = 127,
528 .step = 1,
529 .default_value = 64,
530 .flags = V4L2_CTRL_FLAG_SLIDER,
531 }, {
532 .id = V4L2_CID_EXPOSURE,
533 .type = V4L2_CTRL_TYPE_INTEGER,
534 .name = "Exposure",
535 .minimum = 1,
536 .maximum = 255,
537 .step = 1,
538 .default_value = 255,
539 .flags = V4L2_CTRL_FLAG_SLIDER,
540 }, {
541 .id = V4L2_CID_AUTOGAIN,
542 .type = V4L2_CTRL_TYPE_BOOLEAN,
543 .name = "Automatic Gain",
544 .minimum = 0,
545 .maximum = 1,
546 .step = 1,
547 .default_value = 1,
548 }, {
549 .id = V4L2_CID_EXPOSURE_AUTO,
550 .type = V4L2_CTRL_TYPE_BOOLEAN,
551 .name = "Automatic Exposure",
552 .minimum = 0,
553 .maximum = 1,
554 .step = 1,
555 .default_value = 1,
556 }
557};
558
559static struct soc_camera_ops mt9v022_ops = {
560 .set_bus_param = mt9v022_set_bus_param,
561 .query_bus_param = mt9v022_query_bus_param,
562 .controls = mt9v022_controls,
563 .num_controls = ARRAY_SIZE(mt9v022_controls),
564};
565
566static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
567{ 450{
451 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
452 struct mt9v022, hdl);
453 struct v4l2_subdev *sd = &mt9v022->subdev;
568 struct i2c_client *client = v4l2_get_subdevdata(sd); 454 struct i2c_client *client = v4l2_get_subdevdata(sd);
569 const struct v4l2_queryctrl *qctrl; 455 struct v4l2_ctrl *gain = mt9v022->gain;
456 struct v4l2_ctrl *exp = mt9v022->exposure;
570 unsigned long range; 457 unsigned long range;
571 int data; 458 int data;
572 459
573 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
574
575 switch (ctrl->id) { 460 switch (ctrl->id) {
576 case V4L2_CID_VFLIP:
577 data = reg_read(client, MT9V022_READ_MODE);
578 if (data < 0)
579 return -EIO;
580 ctrl->value = !!(data & 0x10);
581 break;
582 case V4L2_CID_HFLIP:
583 data = reg_read(client, MT9V022_READ_MODE);
584 if (data < 0)
585 return -EIO;
586 ctrl->value = !!(data & 0x20);
587 break;
588 case V4L2_CID_EXPOSURE_AUTO:
589 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
590 if (data < 0)
591 return -EIO;
592 ctrl->value = !!(data & 0x1);
593 break;
594 case V4L2_CID_AUTOGAIN: 461 case V4L2_CID_AUTOGAIN:
595 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
596 if (data < 0)
597 return -EIO;
598 ctrl->value = !!(data & 0x2);
599 break;
600 case V4L2_CID_GAIN:
601 data = reg_read(client, MT9V022_ANALOG_GAIN); 462 data = reg_read(client, MT9V022_ANALOG_GAIN);
602 if (data < 0) 463 if (data < 0)
603 return -EIO; 464 return -EIO;
604 465
605 range = qctrl->maximum - qctrl->minimum; 466 range = gain->maximum - gain->minimum;
606 ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum; 467 gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
607 468 return 0;
608 break; 469 case V4L2_CID_EXPOSURE_AUTO:
609 case V4L2_CID_EXPOSURE:
610 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH); 470 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
611 if (data < 0) 471 if (data < 0)
612 return -EIO; 472 return -EIO;
613 473
614 range = qctrl->maximum - qctrl->minimum; 474 range = exp->maximum - exp->minimum;
615 ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum; 475 exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
616 476 return 0;
617 break;
618 } 477 }
619 return 0; 478 return -EINVAL;
620} 479}
621 480
622static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 481static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
623{ 482{
624 int data; 483 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
484 struct mt9v022, hdl);
485 struct v4l2_subdev *sd = &mt9v022->subdev;
625 struct i2c_client *client = v4l2_get_subdevdata(sd); 486 struct i2c_client *client = v4l2_get_subdevdata(sd);
626 const struct v4l2_queryctrl *qctrl; 487 int data;
627
628 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
629 if (!qctrl)
630 return -EINVAL;
631 488
632 switch (ctrl->id) { 489 switch (ctrl->id) {
633 case V4L2_CID_VFLIP: 490 case V4L2_CID_VFLIP:
634 if (ctrl->value) 491 if (ctrl->val)
635 data = reg_set(client, MT9V022_READ_MODE, 0x10); 492 data = reg_set(client, MT9V022_READ_MODE, 0x10);
636 else 493 else
637 data = reg_clear(client, MT9V022_READ_MODE, 0x10); 494 data = reg_clear(client, MT9V022_READ_MODE, 0x10);
638 if (data < 0) 495 if (data < 0)
639 return -EIO; 496 return -EIO;
640 break; 497 return 0;
641 case V4L2_CID_HFLIP: 498 case V4L2_CID_HFLIP:
642 if (ctrl->value) 499 if (ctrl->val)
643 data = reg_set(client, MT9V022_READ_MODE, 0x20); 500 data = reg_set(client, MT9V022_READ_MODE, 0x20);
644 else 501 else
645 data = reg_clear(client, MT9V022_READ_MODE, 0x20); 502 data = reg_clear(client, MT9V022_READ_MODE, 0x20);
646 if (data < 0) 503 if (data < 0)
647 return -EIO; 504 return -EIO;
648 break; 505 return 0;
649 case V4L2_CID_GAIN: 506 case V4L2_CID_AUTOGAIN:
650 /* mt9v022 has minimum == default */ 507 if (ctrl->val) {
651 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) 508 if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
652 return -EINVAL; 509 return -EIO;
653 else { 510 } else {
654 unsigned long range = qctrl->maximum - qctrl->minimum; 511 struct v4l2_ctrl *gain = mt9v022->gain;
512 /* mt9v022 has minimum == default */
513 unsigned long range = gain->maximum - gain->minimum;
655 /* Valid values 16 to 64, 32 to 64 must be even. */ 514 /* Valid values 16 to 64, 32 to 64 must be even. */
656 unsigned long gain = ((ctrl->value - qctrl->minimum) * 515 unsigned long gain_val = ((gain->val - gain->minimum) *
657 48 + range / 2) / range + 16; 516 48 + range / 2) / range + 16;
658 if (gain >= 32) 517
659 gain &= ~1; 518 if (gain_val >= 32)
519 gain_val &= ~1;
520
660 /* 521 /*
661 * The user wants to set gain manually, hope, she 522 * The user wants to set gain manually, hope, she
662 * knows, what she's doing... Switch AGC off. 523 * knows, what she's doing... Switch AGC off.
663 */ 524 */
664
665 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) 525 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
666 return -EIO; 526 return -EIO;
667 527
668 dev_dbg(&client->dev, "Setting gain from %d to %lu\n", 528 dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
669 reg_read(client, MT9V022_ANALOG_GAIN), gain); 529 reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
670 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) 530 if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
671 return -EIO; 531 return -EIO;
672 } 532 }
673 break; 533 return 0;
674 case V4L2_CID_EXPOSURE: 534 case V4L2_CID_EXPOSURE_AUTO:
675 /* mt9v022 has maximum == default */ 535 if (ctrl->val == V4L2_EXPOSURE_AUTO) {
676 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) 536 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
677 return -EINVAL; 537 } else {
678 else { 538 struct v4l2_ctrl *exp = mt9v022->exposure;
679 unsigned long range = qctrl->maximum - qctrl->minimum; 539 unsigned long range = exp->maximum - exp->minimum;
680 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 540 unsigned long shutter = ((exp->val - exp->minimum) *
681 479 + range / 2) / range + 1; 541 479 + range / 2) / range + 1;
542
682 /* 543 /*
683 * The user wants to set shutter width manually, hope, 544 * The user wants to set shutter width manually, hope,
684 * she knows, what she's doing... Switch AEC off. 545 * she knows, what she's doing... Switch AEC off.
685 */ 546 */
686 547 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
687 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) 548 if (data < 0)
688 return -EIO; 549 return -EIO;
689
690 dev_dbg(&client->dev, "Shutter width from %d to %lu\n", 550 dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
691 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), 551 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
692 shutter); 552 shutter);
693 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 553 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
694 shutter) < 0) 554 shutter) < 0)
695 return -EIO; 555 return -EIO;
696 } 556 }
697 break; 557 return 0;
698 case V4L2_CID_AUTOGAIN:
699 if (ctrl->value)
700 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
701 else
702 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
703 if (data < 0)
704 return -EIO;
705 break;
706 case V4L2_CID_EXPOSURE_AUTO:
707 if (ctrl->value)
708 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
709 else
710 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
711 if (data < 0)
712 return -EIO;
713 break;
714 } 558 }
715 return 0; 559 return -EINVAL;
716} 560}
717 561
718/* 562/*
719 * Interface active, can use i2c. If it fails, it can indeed mean, that 563 * Interface active, can use i2c. If it fails, it can indeed mean, that
720 * this wasn't our capture interface, so, we wait for the right one 564 * this wasn't our capture interface, so, we wait for the right one
721 */ 565 */
722static int mt9v022_video_probe(struct soc_camera_device *icd, 566static int mt9v022_video_probe(struct i2c_client *client)
723 struct i2c_client *client)
724{ 567{
725 struct mt9v022 *mt9v022 = to_mt9v022(client); 568 struct mt9v022 *mt9v022 = to_mt9v022(client);
726 struct soc_camera_link *icl = to_soc_camera_link(icd); 569 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
727 s32 data; 570 s32 data;
728 int ret; 571 int ret;
729 unsigned long flags; 572 unsigned long flags;
730 573
731 /* We must have a parent by now. And it cannot be a wrong one. */
732 BUG_ON(!icd->parent ||
733 to_soc_camera_host(icd->parent)->nr != icd->iface);
734
735 /* Read out the chip version register */ 574 /* Read out the chip version register */
736 data = reg_read(client, MT9V022_CHIP_VERSION); 575 data = reg_read(client, MT9V022_CHIP_VERSION);
737 576
@@ -805,16 +644,6 @@ ei2c:
805 return ret; 644 return ret;
806} 645}
807 646
808static void mt9v022_video_remove(struct soc_camera_device *icd)
809{
810 struct soc_camera_link *icl = to_soc_camera_link(icd);
811
812 dev_dbg(icd->pdev, "Video removed: %p, %p\n",
813 icd->parent, icd->vdev);
814 if (icl->free_bus)
815 icl->free_bus(icl);
816}
817
818static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) 647static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
819{ 648{
820 struct i2c_client *client = v4l2_get_subdevdata(sd); 649 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -825,9 +654,12 @@ static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
825 return 0; 654 return 0;
826} 655}
827 656
657static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
658 .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
659 .s_ctrl = mt9v022_s_ctrl,
660};
661
828static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { 662static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
829 .g_ctrl = mt9v022_g_ctrl,
830 .s_ctrl = mt9v022_s_ctrl,
831 .g_chip_ident = mt9v022_g_chip_ident, 663 .g_chip_ident = mt9v022_g_chip_ident,
832#ifdef CONFIG_VIDEO_ADV_DEBUG 664#ifdef CONFIG_VIDEO_ADV_DEBUG
833 .g_register = mt9v022_g_register, 665 .g_register = mt9v022_g_register,
@@ -848,6 +680,72 @@ static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
848 return 0; 680 return 0;
849} 681}
850 682
683static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
684 struct v4l2_mbus_config *cfg)
685{
686 struct i2c_client *client = v4l2_get_subdevdata(sd);
687 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
688
689 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
690 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
691 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
692 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
693 V4L2_MBUS_DATA_ACTIVE_HIGH;
694 cfg->type = V4L2_MBUS_PARALLEL;
695 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
696
697 return 0;
698}
699
700static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
701 const struct v4l2_mbus_config *cfg)
702{
703 struct i2c_client *client = v4l2_get_subdevdata(sd);
704 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
705 struct mt9v022 *mt9v022 = to_mt9v022(client);
706 unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
707 unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
708 int ret;
709 u16 pixclk = 0;
710
711 if (icl->set_bus_param) {
712 ret = icl->set_bus_param(icl, 1 << (bps - 1));
713 if (ret)
714 return ret;
715 } else if (bps != 10) {
716 /*
717 * Without board specific bus width settings we only support the
718 * sensors native bus width
719 */
720 return -EINVAL;
721 }
722
723 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
724 pixclk |= 0x10;
725
726 if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
727 pixclk |= 0x1;
728
729 if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
730 pixclk |= 0x2;
731
732 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
733 if (ret < 0)
734 return ret;
735
736 if (!(flags & V4L2_MBUS_MASTER))
737 mt9v022->chip_control &= ~0x8;
738
739 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
740 if (ret < 0)
741 return ret;
742
743 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
744 pixclk, mt9v022->chip_control);
745
746 return 0;
747}
748
851static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { 749static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
852 .s_stream = mt9v022_s_stream, 750 .s_stream = mt9v022_s_stream,
853 .s_mbus_fmt = mt9v022_s_fmt, 751 .s_mbus_fmt = mt9v022_s_fmt,
@@ -857,6 +755,8 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
857 .g_crop = mt9v022_g_crop, 755 .g_crop = mt9v022_g_crop,
858 .cropcap = mt9v022_cropcap, 756 .cropcap = mt9v022_cropcap,
859 .enum_mbus_fmt = mt9v022_enum_fmt, 757 .enum_mbus_fmt = mt9v022_enum_fmt,
758 .g_mbus_config = mt9v022_g_mbus_config,
759 .s_mbus_config = mt9v022_s_mbus_config,
860}; 760};
861 761
862static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { 762static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
@@ -873,17 +773,10 @@ static int mt9v022_probe(struct i2c_client *client,
873 const struct i2c_device_id *did) 773 const struct i2c_device_id *did)
874{ 774{
875 struct mt9v022 *mt9v022; 775 struct mt9v022 *mt9v022;
876 struct soc_camera_device *icd = client->dev.platform_data; 776 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
877 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 777 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
878 struct soc_camera_link *icl;
879 int ret; 778 int ret;
880 779
881 if (!icd) {
882 dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
883 return -EINVAL;
884 }
885
886 icl = to_soc_camera_link(icd);
887 if (!icl) { 780 if (!icl) {
888 dev_err(&client->dev, "MT9V022 driver needs platform data\n"); 781 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
889 return -EINVAL; 782 return -EINVAL;
@@ -900,10 +793,39 @@ static int mt9v022_probe(struct i2c_client *client,
900 return -ENOMEM; 793 return -ENOMEM;
901 794
902 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops); 795 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
796 v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
797 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
798 V4L2_CID_VFLIP, 0, 1, 1, 0);
799 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
800 V4L2_CID_HFLIP, 0, 1, 1, 0);
801 mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
802 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
803 mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
804 V4L2_CID_GAIN, 0, 127, 1, 64);
805
806 /*
807 * Simulated autoexposure. If enabled, we calculate shutter width
808 * ourselves in the driver based on vertical blanking and frame width
809 */
810 mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
811 &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
812 V4L2_EXPOSURE_AUTO);
813 mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
814 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
815
816 mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
817 if (mt9v022->hdl.error) {
818 int err = mt9v022->hdl.error;
819
820 kfree(mt9v022);
821 return err;
822 }
823 v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
824 V4L2_EXPOSURE_MANUAL, true);
825 v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
903 826
904 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 827 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
905 828
906 icd->ops = &mt9v022_ops;
907 /* 829 /*
908 * MT9V022 _really_ corrupts the first read out line. 830 * MT9V022 _really_ corrupts the first read out line.
909 * TODO: verify on i.MX31 831 * TODO: verify on i.MX31
@@ -914,9 +836,9 @@ static int mt9v022_probe(struct i2c_client *client,
914 mt9v022->rect.width = MT9V022_MAX_WIDTH; 836 mt9v022->rect.width = MT9V022_MAX_WIDTH;
915 mt9v022->rect.height = MT9V022_MAX_HEIGHT; 837 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
916 838
917 ret = mt9v022_video_probe(icd, client); 839 ret = mt9v022_video_probe(client);
918 if (ret) { 840 if (ret) {
919 icd->ops = NULL; 841 v4l2_ctrl_handler_free(&mt9v022->hdl);
920 kfree(mt9v022); 842 kfree(mt9v022);
921 } 843 }
922 844
@@ -926,10 +848,12 @@ static int mt9v022_probe(struct i2c_client *client,
926static int mt9v022_remove(struct i2c_client *client) 848static int mt9v022_remove(struct i2c_client *client)
927{ 849{
928 struct mt9v022 *mt9v022 = to_mt9v022(client); 850 struct mt9v022 *mt9v022 = to_mt9v022(client);
929 struct soc_camera_device *icd = client->dev.platform_data; 851 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
930 852
931 icd->ops = NULL; 853 v4l2_device_unregister_subdev(&mt9v022->subdev);
932 mt9v022_video_remove(icd); 854 if (icl->free_bus)
855 icl->free_bus(icl);
856 v4l2_ctrl_handler_free(&mt9v022->hdl);
933 kfree(mt9v022); 857 kfree(mt9v022);
934 858
935 return 0; 859 return 0;