From: Wenjia Zhou Date: Mon, 5 Jun 2017 23:05:00 +0000 (-0700) Subject: media:camera: Fix s_stream and s_power sequence X-Git-Url: https://rtime.felk.cvut.cz/gitweb/hercules2020/nv-tegra/linux-4.4.git/commitdiff_plain/410dc3e204ca353d66a61689abaaf65bef24879d media:camera: Fix s_stream and s_power sequence Bug 1920440 Bug 200295634 Change-Id: I1f268b709821f327aad9d426e0544370824beae3 Signed-off-by: Wenjia Zhou Reviewed-on: http://git-master/r/1479671 (cherry picked from commit 37351f2e9ad9056755b949a59f5c817cddcbb606) Reviewed-on: http://git-master/r/1490063 GVS: Gerrit_Virtual_Submit Reviewed-by: Bhanu Murthy V Reviewed-by: Jihoon Bang --- diff --git a/drivers/media/platform/tegra/camera/csi/csi.c b/drivers/media/platform/tegra/camera/csi/csi.c index e33165318299..0939b2eaaaef 100644 --- a/drivers/media/platform/tegra/camera/csi/csi.c +++ b/drivers/media/platform/tegra/camera/csi/csi.c @@ -76,11 +76,13 @@ int tegra_csi_power(struct tegra_csi_device *csi, int enable) int err = 0; if (enable) { + tegra_mipi_bias_pad_enable(); err = csi->fops->csi_power_on(csi); if (!err) atomic_inc(&csi->power_ref); } else { err = csi->fops->csi_power_off(csi); + tegra_mipi_bias_pad_disable(); if (!err) atomic_dec(&csi->power_ref); } @@ -166,13 +168,10 @@ static int tegra_csi_s_stream(struct v4l2_subdev *subdev, int enable) ret = update_video_source(csi, enable, chan->pg_mode); if (ret) return ret; - if (!chan->pg_mode) { - if (enable) { - tegra_mipi_bias_pad_enable(); + if (!chan->pg_mode) + if (enable) csi->fops->mipical(chan); - } else - tegra_mipi_bias_pad_disable(); - } + if (tegra_chan->bypass) { atomic_set(&chan->is_streaming, enable); return 0; @@ -192,7 +191,6 @@ start_fail: update_video_source(csi, 0, chan->pg_mode); for (i = 0; i < tegra_chan->valid_ports; i++) tegra_csi_stop_streaming(chan, i); - tegra_mipi_bias_pad_disable(); return ret; } diff --git a/drivers/media/platform/tegra/camera/vi/channel.c b/drivers/media/platform/tegra/camera/vi/channel.c index de901d5fd0d7..22ff1af3b0db 100644 --- a/drivers/media/platform/tegra/camera/vi/channel.c +++ b/drivers/media/platform/tegra/camera/vi/channel.c @@ -536,21 +536,36 @@ int tegra_channel_set_stream(struct tegra_channel *chan, bool on) { int num_sd; int ret = 0; + int err = 0; + struct v4l2_subdev *sd; if (atomic_read(&chan->is_streaming) == on) return 0; - for (num_sd = chan->num_subdevs - 1; num_sd >= 0; num_sd--) { - struct v4l2_subdev *sd = chan->subdev[num_sd]; - int err = 0; + if (on) { + /* Enable CSI before sensor. Reason is as follows: + * CSI is able to catch the very first clk transition. + * Ensure mipi calibration is done before transmission/first frame data. + * TODO:Ensure deskew is setup properly before first deskew sync signal. + */ + for (num_sd = 0; num_sd < chan->num_subdevs; num_sd++) { + sd = chan->subdev[num_sd]; - err = v4l2_subdev_call(sd, video, s_stream, on); - if (!ret && err < 0 && err != -ENOIOCTLCMD) - ret = err; + err = v4l2_subdev_call(sd, video, s_stream, on); + if (!ret && err < 0 && err != -ENOIOCTLCMD) + ret = err; + } + } else { + for (num_sd = chan->num_subdevs - 1; num_sd >= 0; num_sd--) { + sd = chan->subdev[num_sd]; + + err = v4l2_subdev_call(sd, video, s_stream, on); + if (!ret && err < 0 && err != -ENOIOCTLCMD) + ret = err; + } } atomic_set(&chan->is_streaming, on); - return ret; } @@ -558,14 +573,25 @@ int tegra_channel_set_power(struct tegra_channel *chan, bool on) { int num_sd; int ret = 0; + int err = 0; + struct v4l2_subdev *sd; - for (num_sd = 0; num_sd < chan->num_subdevs; num_sd++) { - struct v4l2_subdev *sd = chan->subdev[num_sd]; - int err = 0; + if (on) { + for (num_sd = 0; num_sd < chan->num_subdevs; num_sd++) { + sd = chan->subdev[num_sd]; - err = v4l2_subdev_call(sd, core, s_power, on); - if (!ret && err < 0 && err != -ENOIOCTLCMD) - ret = err; + err = v4l2_subdev_call(sd, core, s_power, on); + if (!ret && err < 0 && err != -ENOIOCTLCMD) + ret = err; + } + } else { + for (num_sd = chan->num_subdevs - 1; num_sd >= 0; num_sd--) { + sd = chan->subdev[num_sd]; + + err = v4l2_subdev_call(sd, core, s_power, on); + if (!ret && err < 0 && err != -ENOIOCTLCMD) + ret = err; + } } return ret;