Re: [PATCH v2 12/16] iio: adc: ad7768-1: Add GPIO controller support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 27 Jan 2025 12:13:45 -0300
Jonathan Santos <Jonathan.Santos@xxxxxxxxxx> wrote:

> From: Sergiu Cuciurean <sergiu.cuciurean@xxxxxxxxxx>
> 
> The AD7768-1 has the ability to control other local hardware (such as gain
> stages),to power down other blocks in the signal chain, or read local
> status signals over the SPI interface.
> 
> This change exports the AD7768-1's four gpios and makes them accessible
> at an upper layer.
> 
> Co-developed-by: Jonathan Santos <Jonathan.Santos@xxxxxxxxxx>
> Signed-off-by: Jonathan Santos <Jonathan.Santos@xxxxxxxxxx>
> Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@xxxxxxxxxx>
As David observed, the direct mode release calls are missing.

Also, there are a few places where you wrap lines much shorter than needed.

> +static int ad7768_gpio_direction_output(struct gpio_chip *chip,
> +					unsigned int offset, int value)
> +{
> +	struct iio_dev *indio_dev = gpiochip_get_data(chip);
> +	struct ad7768_state *st = iio_priv(indio_dev);
> +	int ret;
> +
> +	ret = iio_device_claim_direct_mode(indio_dev);
> +	if (ret)
> +		return ret;
> +
> +	return regmap_update_bits(st->regmap,
> +				  AD7768_REG_GPIO_CONTROL,
> +				  BIT(offset),
> +				  AD7768_GPIO_OUTPUT(offset));
Again, wrap less.

> +}
> +
> +static int ad7768_gpio_get(struct gpio_chip *chip, unsigned int offset)
> +{
> +	struct iio_dev *indio_dev = gpiochip_get_data(chip);
> +	struct ad7768_state *st = iio_priv(indio_dev);
> +	unsigned int val;
> +	int ret;
> +
> +	ret = iio_device_claim_direct_mode(indio_dev);
You aren't releasing it.  That should have deadlocked the second time
you called this.

> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_read(st->regmap, AD7768_REG_GPIO_CONTROL, &val);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (val & BIT(offset))
> +		ret = regmap_read(st->regmap, AD7768_REG_GPIO_WRITE, &val);
> +	else
> +		ret = regmap_read(st->regmap, AD7768_REG_GPIO_READ, &val);
> +	if (ret < 0)
> +		return ret;
> +
> +	return !!(val & BIT(offset));
> +}
> +
> +static void ad7768_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
> +{
> +	struct iio_dev *indio_dev = gpiochip_get_data(chip);
> +	struct ad7768_state *st = iio_priv(indio_dev);
> +	unsigned int val;
> +	int ret;
> +
> +	ret = iio_device_claim_direct_mode(indio_dev);
As above, needs a matching release.  May mean you want to factor
out the guts of this as a helper function so you can still do
direct returns on error.

> +	if (ret)
> +		return;
> +
> +	ret = regmap_read(st->regmap, AD7768_REG_GPIO_CONTROL, &val);
> +	if (ret < 0)
> +		return;
> +
> +	if (val & BIT(offset))
> +		regmap_update_bits(st->regmap,
> +				   AD7768_REG_GPIO_WRITE,
> +				   BIT(offset),
> +				   (value << offset));
	Wrap a little less and drop the unnecessary brackets.

		regmap_update_bits(st->regmap, AD7768_REG_GPIO_WRITE,
				   BIT(offset), value << offset);
Also, check return value?

> +}
> +

> +
> +static int ad7768_gpio_init(struct iio_dev *indio_dev)
> +{
> +	struct ad7768_state *st = iio_priv(indio_dev);
> +	int ret;
> +
> +	ret = regmap_write(st->regmap, AD7768_REG_GPIO_CONTROL,
> +			   AD7768_GPIO_UNIVERSAL_EN);
> +	if (ret < 0)
> +		return ret;
> +
> +	st->gpio_avail_map = AD7768_GPIO_CONTROL_MSK;
> +	st->gpiochip.label = "ad7768_1_gpios";
> +	st->gpiochip.base = -1;
> +	st->gpiochip.ngpio = 4;
> +	st->gpiochip.parent = &st->spi->dev;
> +	st->gpiochip.can_sleep = true;
> +	st->gpiochip.direction_input = ad7768_gpio_direction_input;
> +	st->gpiochip.direction_output = ad7768_gpio_direction_output;
> +	st->gpiochip.get = ad7768_gpio_get;
> +	st->gpiochip.set = ad7768_gpio_set;
> +	st->gpiochip.request = ad7768_gpio_request;
> +	st->gpiochip.owner = THIS_MODULE;
Might not be worth it but I'd be tempted to do

	st->gpiochip = (struct gpio_chip) {
		.label = "ad7768_1_gpios",
		.base = -1,
		.ngpio = 4,
...
	};
perhaps.  This one is entirely up to your preference.
> +
> +	return gpiochip_add_data(&st->gpiochip, indio_dev);
> +}
> +




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux