On 30.05.21 22:44, Fabio Estevam wrote: > On a design where the ADV7180 pin is pulled down, it is not possible > to make it functional unless the GPIO connected to this pin goes > high. > > Add support for the reset GPIO by introducing an optional property > called 'reset-gpios'. > > Note: the reset operation is still performed via software as recommended > by the Analog Devices, but the reset GPIO still needs to go high to make > the chip operational. > > Signed-off-by: Fabio Estevam <festevam@xxxxxxxxx> > --- > drivers/media/i2c/adv7180.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c > index 44bb6fe85644..2811f2c337fa 100644 > --- a/drivers/media/i2c/adv7180.c > +++ b/drivers/media/i2c/adv7180.c > @@ -205,6 +205,7 @@ struct adv7180_state { > struct mutex mutex; /* mutual excl. when accessing chip */ > int irq; > struct gpio_desc *pwdn_gpio; > + struct gpio_desc *reset_gpio; > v4l2_std_id curr_norm; > bool powered; > bool streaming; > @@ -473,13 +474,15 @@ static int adv7180_g_frame_interval(struct v4l2_subdev *sd, > > static void adv7180_set_power_pin(struct adv7180_state *state, bool on) > { > - if (!state->pwdn_gpio) > + if (!state->pwdn_gpio && !state->reset_gpio) > return; > > if (on) { > + gpiod_set_value_cansleep(state->reset_gpio, 0); > gpiod_set_value_cansleep(state->pwdn_gpio, 0); The datasheet specifies a delay of 5 ms between deasserting the PWRDWN and the RESET GPIO. Also this function is named adv7180_set_power_pin() which doesn't fit anymore if we also handle the RESET GPIO here. As I was recently working with the ADV7280-M, I came up with a similar patch: https://git.kontron-electronics.de/linux/linux/-/commit/3619ed166140a0499ada7b14e5f1846a0ed7d18d. What do you think? > usleep_range(5000, 10000); > } else { > + gpiod_set_value_cansleep(state->reset_gpio, 1); > gpiod_set_value_cansleep(state->pwdn_gpio, 1); > } > } > @@ -1338,6 +1341,15 @@ static int adv7180_probe(struct i2c_client *client, > return ret; > } > > + state->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", > + GPIOD_OUT_HIGH); > + if (IS_ERR(state->reset_gpio)) { > + ret = PTR_ERR(state->reset_gpio); > + v4l_err(client, "request for reset pin failed: %d\n", ret); > + return ret; > + } > + > + > if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) { > state->csi_client = i2c_new_dummy_device(client->adapter, > ADV7180_DEFAULT_CSI_I2C_ADDR); >