Commit 65d9e14a authored by Steve Longerbeam's avatar Steve Longerbeam Committed by Mauro Carvalho Chehab
Browse files

[media] media: adv7180: add power pin control



Some targets control the ADV7180 power pin via a gpio, so add
optional support for "powerdown" pin control.

Signed-off-by: default avatarSteve Longerbeam <steve_longerbeam@mentor.com>
Tested-by: default avatarTim Harvey <tharvey@gateworks.com>
Acked-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent ce5d6290
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@ Required Properties :
		"adi,adv7282"
		"adi,adv7282-m"

Optional Properties :
- powerdown-gpios: reference to the GPIO connected to the powerdown pin,
  if any.


Example:

	i2c0@1c22000 {
+1 −1
Original line number Diff line number Diff line
@@ -187,7 +187,7 @@ comment "Video decoders"

config VIDEO_ADV7180
	tristate "Analog Devices ADV7180 decoder"
	depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
	depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
	---help---
	  Support for the Analog Devices ADV7180 video decoder.

+27 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
#include <linux/videodev2.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
@@ -213,6 +214,7 @@ struct adv7180_state {
	struct media_pad	pad;
	struct mutex		mutex; /* mutual excl. when accessing chip */
	int			irq;
	struct gpio_desc	*pwdn_gpio;
	v4l2_std_id		curr_norm;
	bool			powered;
	bool			streaming;
@@ -463,6 +465,19 @@ static int adv7180_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
	return 0;
}

static void adv7180_set_power_pin(struct adv7180_state *state, bool on)
{
	if (!state->pwdn_gpio)
		return;

	if (on) {
		gpiod_set_value_cansleep(state->pwdn_gpio, 0);
		usleep_range(5000, 10000);
	} else {
		gpiod_set_value_cansleep(state->pwdn_gpio, 1);
	}
}

static int adv7180_set_power(struct adv7180_state *state, bool on)
{
	u8 val;
@@ -1210,6 +1225,8 @@ static int init_device(struct adv7180_state *state)

	mutex_lock(&state->mutex);

	adv7180_set_power_pin(state, true);

	adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
	usleep_range(5000, 10000);

@@ -1279,6 +1296,14 @@ static int adv7180_probe(struct i2c_client *client,
	state->field = V4L2_FIELD_INTERLACED;
	state->chip_info = (struct adv7180_chip_info *)id->driver_data;

	state->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
						   GPIOD_OUT_HIGH);
	if (IS_ERR(state->pwdn_gpio)) {
		ret = PTR_ERR(state->pwdn_gpio);
		v4l_err(client, "request for power pin failed: %d\n", ret);
		return ret;
	}

	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
		state->csi_client = i2c_new_dummy(client->adapter,
				ADV7180_DEFAULT_CSI_I2C_ADDR);
@@ -1370,6 +1395,8 @@ static int adv7180_remove(struct i2c_client *client)
	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
		i2c_unregister_device(state->csi_client);

	adv7180_set_power_pin(state, false);

	mutex_destroy(&state->mutex);

	return 0;