From b1aa25b3f69085a580cec1257ee19b44bbbd5cb7 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 15 Jun 2021 18:45:40 +0100 Subject: [PATCH 0448/1085] media: i2c: imx258: Add regulator control The device tree bindings define the relevant regulators for the sensor, so update the driver to request the regulators and control them at the appropriate times. Signed-off-by: Dave Stevenson --- drivers/media/i2c/imx258.c | 42 +++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -507,6 +508,16 @@ static const char * const imx258_test_pa "Pseudorandom Sequence (PN9)", }; +/* regulator supplies */ +static const char * const imx258_supply_name[] = { + /* Supplies can be enabled in any order */ + "vana", /* Analog (2.8V) supply */ + "vdig", /* Digital Core (1.05V) supply */ + "vif", /* IF (1.8V) supply */ +}; + +#define IMX258_NUM_SUPPLIES ARRAY_SIZE(imx258_supply_name) + /* Configurations for supported link frequencies */ #define IMX258_LINK_FREQ_634MHZ 633600000ULL #define IMX258_LINK_FREQ_320MHZ 320000000ULL @@ -614,6 +625,7 @@ struct imx258 { bool streaming; struct clk *clk; + struct regulator_bulk_data supplies[IMX258_NUM_SUPPLIES]; }; static inline struct imx258 *to_imx258(struct v4l2_subdev *_sd) @@ -999,9 +1011,19 @@ static int imx258_power_on(struct device struct imx258 *imx258 = to_imx258(sd); int ret; + ret = regulator_bulk_enable(IMX258_NUM_SUPPLIES, + imx258->supplies); + if (ret) { + dev_err(dev, "%s: failed to enable regulators\n", + __func__); + return ret; + } + ret = clk_prepare_enable(imx258->clk); - if (ret) + if (ret) { dev_err(dev, "failed to enable clock\n"); + regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies); + } return ret; } @@ -1012,6 +1034,7 @@ static int imx258_power_off(struct devic struct imx258 *imx258 = to_imx258(sd); clk_disable_unprepare(imx258->clk); + regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies); return 0; } @@ -1260,6 +1283,19 @@ static void imx258_free_controls(struct mutex_destroy(&imx258->mutex); } +static int imx258_get_regulators(struct imx258 *imx258, + struct i2c_client *client) +{ + unsigned int i; + + for (i = 0; i < IMX258_NUM_SUPPLIES; i++) + imx258->supplies[i].supply = imx258_supply_name[i]; + + return devm_regulator_bulk_get(&client->dev, + IMX258_NUM_SUPPLIES, + imx258->supplies); +} + static int imx258_probe(struct i2c_client *client) { struct imx258 *imx258; @@ -1270,6 +1306,10 @@ static int imx258_probe(struct i2c_clien if (!imx258) return -ENOMEM; + ret = imx258_get_regulators(imx258, client); + if (ret) + return ret; + imx258->clk = devm_clk_get_optional(&client->dev, NULL); if (IS_ERR(imx258->clk)) return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),