summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBhanu Murthy V <bmurthyv@nvidia.com>2018-08-29 18:21:55 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2019-01-09 03:17:04 -0500
commit0e15664e4eda6e09c799d1d0fb7c791fb59b257c (patch)
treee337d7ecc5882975b101fe95f296749cc9a79143
parent647118deb4c0682d1205e4707c4bc6759e05c2ff (diff)
drivers: camera: Move v4l2 subdev ops to tegracam
Move all v4l2 initialization to common framework, ensures most of the duplicated code in sensor drivers reduced. Now sensor drivers will have control and core ops for all operations. New ops - set_mode, start_streaming and stop_streaming are added to modularize sensor drivers. Update current sensor drivers with the new modifications. Bug 2101376 Change-Id: Ic4070bde28f3dce61430af9ecded0541cda2f6fe Signed-off-by: Bhanu Murthy V <bmurthyv@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1810324 (cherry picked from commit e5801b45ee0ca88a4d3ea6e98ac24800f1971806) Reviewed-on: https://git-master.nvidia.com/r/1961293 Tested-by: Vincent Chung <vincentc@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: Frank Chen <frankc@nvidia.com> Reviewed-by: Frank Chen <frankc@nvidia.com> Reviewed-by: David Bang <dbang@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/media/i2c/imx185.c186
-rw-r--r--drivers/media/i2c/imx268.c179
-rw-r--r--drivers/media/i2c/imx318.c181
-rw-r--r--drivers/media/platform/tegra/camera/Makefile2
-rw-r--r--drivers/media/platform/tegra/camera/tegracam_core.c88
-rw-r--r--drivers/media/platform/tegra/camera/tegracam_ctrls.c69
-rw-r--r--drivers/media/platform/tegra/camera/tegracam_v4l2.c189
-rw-r--r--include/media/camera_common.h4
-rw-r--r--include/media/tegracam_core.h4
9 files changed, 398 insertions, 504 deletions
diff --git a/drivers/media/i2c/imx185.c b/drivers/media/i2c/imx185.c
index 5c9536cd7..9fef03a53 100644
--- a/drivers/media/i2c/imx185.c
+++ b/drivers/media/i2c/imx185.c
@@ -591,165 +591,77 @@ error:
591 return ret; 591 return ret;
592} 592}
593 593
594static struct camera_common_sensor_ops imx185_common_ops = { 594static int imx185_set_mode(struct tegracam_device *tc_dev)
595 .numfrmfmts = ARRAY_SIZE(imx185_frmfmt),
596 .frmfmt_table = imx185_frmfmt,
597 .power_on = imx185_power_on,
598 .power_off = imx185_power_off,
599 .write_reg = imx185_write_reg,
600 .read_reg = imx185_read_reg,
601 .parse_dt = imx185_parse_dt,
602 .power_get = imx185_power_get,
603 .power_put = imx185_power_put,
604};
605
606static int imx185_s_stream(struct v4l2_subdev *sd, int enable)
607{ 595{
608 struct i2c_client *client = v4l2_get_subdevdata(sd); 596 struct imx185 *priv = (struct imx185 *)tegracam_get_privdata(tc_dev);
609 struct device *dev = &client->dev; 597 struct camera_common_data *s_data = tc_dev->s_data;
610 struct camera_common_data *s_data = to_camera_common_data(dev);
611 struct imx185 *priv = (struct imx185 *)s_data->priv;
612 struct v4l2_ext_controls ctrls;
613 struct v4l2_ext_control control[3];
614 int err; 598 int err;
615 599
616 dev_dbg(dev, "%s++ enable %d\n", __func__, enable);
617
618 trace_imx185_s_stream(sd->name, enable, s_data->mode);
619 if (!enable) {
620 err = imx185_write_table(priv,
621 mode_table[IMX185_MODE_STOP_STREAM]);
622
623 if (err)
624 return err;
625
626 /* SW_RESET will have no ACK */
627 regmap_write(s_data->regmap, IMX185_SW_RESET_ADDR, 0x01);
628
629 /* Wait for one frame to make sure sensor is set to
630 * software standby in V-blank
631 *
632 * delay = frame length rows * Tline (10 us)
633 */
634 usleep_range(priv->frame_length * 10,
635 priv->frame_length * 10 + 1000);
636 return 0;
637 }
638 err = imx185_write_table(priv, mode_table[s_data->mode_prop_idx]); 600 err = imx185_write_table(priv, mode_table[s_data->mode_prop_idx]);
639 if (err) 601 if (err)
640 goto exit; 602 return err;
641 603
642 if (s_data->override_enable) { 604 return 0;
643 /* write list of override regs for the asking gain, */ 605}
644 /* frame rate and exposure time */ 606
645 memset(&ctrls, 0, sizeof(ctrls)); 607static int imx185_start_streaming(struct tegracam_device *tc_dev)
646#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 9, 0) 608{
647 ctrls.which = V4L2_CTRL_ID2WHICH(TEGRA_CAMERA_CID_GAIN); 609 struct imx185 *priv = (struct imx185 *)tegracam_get_privdata(tc_dev);
648#else 610 int err;
649 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(TEGRA_CAMERA_CID_GAIN);
650#endif
651 ctrls.count = 3;
652 ctrls.controls = control;
653
654 control[0].id = TEGRA_CAMERA_CID_GAIN;
655 control[1].id = TEGRA_CAMERA_CID_FRAME_RATE;
656 control[2].id = TEGRA_CAMERA_CID_EXPOSURE;
657
658 err = v4l2_g_ext_ctrls(s_data->ctrl_handler, &ctrls);
659 if (err == 0) {
660 err |= imx185_set_gain(priv->tc_dev, control[0].value64);
661 if (err)
662 dev_err(dev, "%s: error gain override\n",
663 __func__);
664
665 err |= imx185_set_frame_rate(priv->tc_dev,
666 control[1].value64);
667 if (err)
668 dev_err(dev,
669 "%s: error frame length override\n",
670 __func__);
671
672 err |= imx185_set_exposure(priv->tc_dev, control[2].value64);
673 if (err)
674 dev_err(dev, "%s: error exposure override\n",
675 __func__);
676
677 } else {
678 dev_err(dev, "%s: faile to get overrides\n", __func__);
679 }
680 }
681 611
682 if (test_mode) { 612 if (test_mode) {
683 err = imx185_write_table(priv, 613 err = imx185_write_table(priv,
684 mode_table[IMX185_MODE_TEST_PATTERN]); 614 mode_table[IMX185_MODE_TEST_PATTERN]);
685 if (err) 615 if (err)
686 goto exit; 616 return err;
687 } 617 }
688 618
689 err = imx185_write_table(priv, mode_table[IMX185_MODE_START_STREAM]); 619 err = imx185_write_table(priv,
620 mode_table[IMX185_MODE_START_STREAM]);
690 if (err) 621 if (err)
691 goto exit; 622 return err;
692 623
693 return 0; 624 return 0;
694exit:
695 dev_err(dev, "%s: error setting stream\n", __func__);
696 return err;
697} 625}
698 626
699static int imx185_g_input_status(struct v4l2_subdev *sd, u32 *status) 627static int imx185_stop_streaming(struct tegracam_device *tc_dev)
700{ 628{
701 struct i2c_client *client = v4l2_get_subdevdata(sd); 629 struct camera_common_data *s_data = tc_dev->s_data;
702 struct camera_common_data *s_data = to_camera_common_data(&client->dev); 630 struct imx185 *priv = (struct imx185 *)tegracam_get_privdata(tc_dev);
703 struct camera_common_power_rail *pw = s_data->power; 631 int err;
704
705 *status = pw->state == SWITCH_ON;
706 return 0;
707}
708
709static struct v4l2_subdev_video_ops imx185_subdev_video_ops = {
710 .s_stream = imx185_s_stream,
711 .g_mbus_config = camera_common_g_mbus_config,
712 .g_input_status = imx185_g_input_status,
713};
714
715static struct v4l2_subdev_core_ops imx185_subdev_core_ops = {
716 .s_power = camera_common_s_power,
717};
718 632
719static int imx185_get_fmt(struct v4l2_subdev *sd, 633 err = imx185_write_table(priv, mode_table[IMX185_MODE_STOP_STREAM]);
720 struct v4l2_subdev_pad_config *cfg, 634 if (err)
721 struct v4l2_subdev_format *format) 635 return err;
722{
723 return camera_common_g_fmt(sd, &format->format);
724}
725 636
726static int imx185_set_fmt(struct v4l2_subdev *sd, 637 /* SW_RESET will have no ACK */
727 struct v4l2_subdev_pad_config *cfg, 638 imx185_write_reg(s_data, IMX185_SW_RESET_ADDR, 0x01);
728 struct v4l2_subdev_format *format)
729{
730 int ret;
731 639
732 if (format->which == V4L2_SUBDEV_FORMAT_TRY) 640 /*
733 ret = camera_common_try_fmt(sd, &format->format); 641 * Wait for one frame to make sure sensor is set to
734 else 642 * software standby in V-blank
735 ret = camera_common_s_fmt(sd, &format->format); 643 *
644 * delay = frame length rows * Tline (10 us)
645 */
646 usleep_range(priv->frame_length * 10, priv->frame_length * 10 + 1000);
736 647
737 return ret; 648 return 0;
738} 649}
739 650