From 0d8140179715465c4fa976b516e3428bf3fc2e43 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Tue, 11 Jan 2022 13:52:09 +0100 Subject: media: camss: Add regulator_bulk support Add the ability to enable or disable multiple regulators in bulk with camss. This is useful for sm8250, sdm845 and it looks like sdm660 where we have more than one CSI regulator to do at once. It should just work for standalone existing vdda regulators and parts which don't have an explicitly defined CSI regulator. [hverkuil: fix camss-csid.c:163:13: warning: 'ret' may be used uninitialized in this function] Reported-by: Vladimir Zapolskiy Signed-off-by: Bryan O'Donoghue Reviewed-by: Robert Foss Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss/camss-csid.c | 45 +++++++++++++++++--------- 1 file changed, 30 insertions(+), 15 deletions(-) (limited to 'drivers/media/platform/qcom/camss/camss-csid.c') diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 97e0dc3f0cdb..f993f349b66b 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -160,7 +160,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) struct device *dev = camss->dev; struct vfe_device *vfe = &camss->vfe[csid->id]; u32 version = camss->version; - int ret; + int ret = 0; if (on) { if (version == CAMSS_8250 || version == CAMSS_845) { @@ -173,7 +173,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) if (ret < 0) return ret; - ret = csid->vdda ? regulator_enable(csid->vdda) : 0; + ret = regulator_bulk_enable(csid->num_supplies, + csid->supplies); if (ret < 0) { pm_runtime_put_sync(dev); return ret; @@ -181,16 +182,16 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) ret = csid_set_clock_rates(csid); if (ret < 0) { - if (csid->vdda) - regulator_disable(csid->vdda); + regulator_bulk_disable(csid->num_supplies, + csid->supplies); pm_runtime_put_sync(dev); return ret; } ret = camss_enable_clocks(csid->nclocks, csid->clock, dev); if (ret < 0) { - if (csid->vdda) - regulator_disable(csid->vdda); + regulator_bulk_disable(csid->num_supplies, + csid->supplies); pm_runtime_put_sync(dev); return ret; } @@ -201,8 +202,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) if (ret < 0) { disable_irq(csid->irq); camss_disable_clocks(csid->nclocks, csid->clock); - if (csid->vdda) - regulator_disable(csid->vdda); + regulator_bulk_disable(csid->num_supplies, + csid->supplies); pm_runtime_put_sync(dev); return ret; } @@ -211,7 +212,8 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) } else { disable_irq(csid->irq); camss_disable_clocks(csid->nclocks, csid->clock); - ret = csid->vdda ? regulator_disable(csid->vdda) : 0; + regulator_bulk_disable(csid->num_supplies, + csid->supplies); pm_runtime_put_sync(dev); if (version == CAMSS_8250 || version == CAMSS_845) vfe_put(vfe); @@ -656,15 +658,28 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, } /* Regulator */ + for (i = 0; i < ARRAY_SIZE(res->regulators); i++) { + if (res->regulators[i]) + csid->num_supplies++; + } - csid->vdda = NULL; - if (res->regulator[0]) - csid->vdda = devm_regulator_get(dev, res->regulator[0]); - if (IS_ERR(csid->vdda)) { - dev_err(dev, "could not get regulator\n"); - return PTR_ERR(csid->vdda); + if (csid->num_supplies) { + csid->supplies = devm_kmalloc_array(camss->dev, + csid->num_supplies, + sizeof(csid->supplies), + GFP_KERNEL); + if (!csid->supplies) + return -ENOMEM; } + for (i = 0; i < csid->num_supplies; i++) + csid->supplies[i].supply = res->regulators[i]; + + ret = devm_regulator_bulk_get(camss->dev, csid->num_supplies, + csid->supplies); + if (ret) + return ret; + init_completion(&csid->reset_complete); return 0; -- cgit v1.2.3