Skip to content

Commit d57bb1e

Browse files
roliver-rpipelwell
authored andcommitted
media: i2c: imx500: GPIO acquire/release semantics
When the imx500 driver is used as part of the 'AI Camera', the poweroff state is never reached as the camera and gpio driver share a regulator. By releasing the GPIOs when they are not in use, 'AI Camera' is able to achieve a powered-down state. Signed-off-by: Richard Oliver <[email protected]>
1 parent 650fc12 commit d57bb1e

File tree

1 file changed

+52
-10
lines changed

1 file changed

+52
-10
lines changed

drivers/media/i2c/imx500.c

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,9 +2412,11 @@ static int imx500_state_transition(struct imx500 *imx500, const u8 *fw,
24122412
}
24132413

24142414
/* Do SPI transfer */
2415-
gpiod_set_value_cansleep(imx500->led_gpio, 1);
2415+
if (imx500->led_gpio)
2416+
gpiod_set_value_cansleep(imx500->led_gpio, 1);
24162417
ret = imx500_spi_write(imx500, data, size);
2417-
gpiod_set_value_cansleep(imx500->led_gpio, 0);
2418+
if (imx500->led_gpio)
2419+
gpiod_set_value_cansleep(imx500->led_gpio, 0);
24182420

24192421
imx500->fw_progress += size;
24202422

@@ -2748,11 +2750,28 @@ static int imx500_power_on(struct device *dev)
27482750
struct imx500 *imx500 = to_imx500(sd);
27492751
int ret;
27502752

2753+
/* Acquire GPIOs first to ensure reset is asserted before power is applied */
2754+
imx500->led_gpio = devm_gpiod_get_optional(dev, "led", GPIOD_OUT_LOW);
2755+
if (IS_ERR(imx500->led_gpio)) {
2756+
ret = PTR_ERR(imx500->led_gpio);
2757+
dev_err(&client->dev, "%s: failed to get led gpio\n", __func__);
2758+
return ret;
2759+
}
2760+
2761+
imx500->reset_gpio =
2762+
devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
2763+
if (IS_ERR(imx500->reset_gpio)) {
2764+
ret = PTR_ERR(imx500->reset_gpio);
2765+
dev_err(&client->dev, "%s: failed to get reset gpio\n",
2766+
__func__);
2767+
goto gpio_led_put;
2768+
}
2769+
27512770
ret = regulator_bulk_enable(IMX500_NUM_SUPPLIES, imx500->supplies);
27522771
if (ret) {
27532772
dev_err(&client->dev, "%s: failed to enable regulators\n",
27542773
__func__);
2755-
return ret;
2774+
goto gpio_reset_put;
27562775
}
27572776

27582777
/* T4 - 1us
@@ -2772,7 +2791,8 @@ static int imx500_power_on(struct device *dev)
27722791
* as 0ms but also "XCLR pin should be set to 'High' after INCK supplied.".
27732792
* T4 and T5 are shown as overlapping.
27742793
*/
2775-
gpiod_set_value_cansleep(imx500->reset_gpio, 1);
2794+
if (imx500->reset_gpio)
2795+
gpiod_set_value_cansleep(imx500->reset_gpio, 1);
27762796

27772797
/* T7 - 9ms
27782798
* "INCK start and CXLR rising till Send Streaming Command wait time"
@@ -2783,6 +2803,16 @@ static int imx500_power_on(struct device *dev)
27832803

27842804
reg_off:
27852805
regulator_bulk_disable(IMX500_NUM_SUPPLIES, imx500->supplies);
2806+
gpio_reset_put:
2807+
if (imx500->reset_gpio) {
2808+
devm_gpiod_put(dev, imx500->reset_gpio);
2809+
imx500->reset_gpio = NULL;
2810+
}
2811+
gpio_led_put:
2812+
if (imx500->led_gpio) {
2813+
devm_gpiod_put(dev, imx500->led_gpio);
2814+
imx500->led_gpio = NULL;
2815+
}
27862816
return ret;
27872817
}
27882818

@@ -2799,7 +2829,19 @@ static int imx500_power_off(struct device *dev)
27992829
* Note, this is not the reverse order of power up.
28002830
*/
28012831
clk_disable_unprepare(imx500->xclk);
2802-
gpiod_set_value_cansleep(imx500->reset_gpio, 0);
2832+
if (imx500->reset_gpio)
2833+
gpiod_set_value_cansleep(imx500->reset_gpio, 0);
2834+
2835+
/* Release GPIOs before disabling regulators */
2836+
if (imx500->reset_gpio) {
2837+
devm_gpiod_put(&client->dev, imx500->reset_gpio);
2838+
imx500->reset_gpio = NULL;
2839+
}
2840+
if (imx500->led_gpio) {
2841+
devm_gpiod_put(&client->dev, imx500->led_gpio);
2842+
imx500->led_gpio = NULL;
2843+
}
2844+
28032845
regulator_bulk_disable(IMX500_NUM_SUPPLIES, imx500->supplies);
28042846

28052847
/* Force reprogramming of the common registers when powered up again. */
@@ -3135,14 +3177,14 @@ static int imx500_probe(struct i2c_client *client)
31353177
return ret;
31363178
}
31373179

3138-
imx500->led_gpio = devm_gpiod_get_optional(dev, "led", GPIOD_OUT_LOW);
3139-
3140-
imx500->reset_gpio =
3141-
devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
3180+
/* GPIOs are acquired in imx500_power_on() to avoid preventing
3181+
* regulator power down when shared with other drivers.
3182+
*/
31423183

31433184
/*
31443185
* The sensor must be powered for imx500_identify_module()
3145-
* to be able to read the CHIP_ID register
3186+
* to be able to read the CHIP_ID register. This also ensures
3187+
* GPIOs are available.
31463188
*/
31473189
ret = imx500_power_on(dev);
31483190
if (ret)

0 commit comments

Comments
 (0)