mbox series

[0/3] Input: sun4i-lradc-keys: R329 and D1 support

Message ID 20210908034016.24119-1-samuel@sholland.org
Headers show
Series Input: sun4i-lradc-keys: R329 and D1 support | expand

Message

Samuel Holland Sept. 8, 2021, 3:40 a.m. UTC
This series adds R329 and D1 SoC support to the LRADC driver. These SoCs
do not change the register interface, only the platform integration.

I have another series[1] which adds wakeup support to this driver.
It has been reviewed/acked and is waiting to be merged for several
months[2]. That series merges cleanly with this one.

[1]: https://patchwork.kernel.org/project/linux-input/cover/20210805051241.47168-1-samuel@sholland.org/
[2]: https://patchwork.kernel.org/project/linux-input/cover/20210430042003.4591-1-samuel@sholland.org/

Samuel Holland (3):
  dt-bindings: input: sun4i-lradc-keys: Add R329 and D1 compatibles
  Input: sun4i-lradc-keys: Add optional clock/reset support
  Input: sun4i-lradc-keys: Add support for R329 and D1

 .../input/allwinner,sun4i-a10-lradc-keys.yaml | 22 +++++++++++++
 drivers/input/keyboard/sun4i-lradc-keys.c     | 31 +++++++++++++++++++
 2 files changed, 53 insertions(+)

Comments

Maxime Ripard Sept. 14, 2021, 7:28 a.m. UTC | #1
Hi Samuel,

On Tue, Sep 07, 2021 at 10:40:15PM -0500, Samuel Holland wrote:
> Until the R329, the LRADC hardware was always active. Now it requires

> enabling a clock gate and deasserting a reset line. Do this if the clock

> and reset are provided in the device tree, but keep them optional to

> maintain support for the existing binding.

> 

> Signed-off-by: Samuel Holland <samuel@sholland.org>

> ---

>  drivers/input/keyboard/sun4i-lradc-keys.c | 29 +++++++++++++++++++++++

>  1 file changed, 29 insertions(+)

> 

> diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c

> index 4a796bed48ac..50fc18052829 100644

> --- a/drivers/input/keyboard/sun4i-lradc-keys.c

> +++ b/drivers/input/keyboard/sun4i-lradc-keys.c

> @@ -14,6 +14,7 @@

>   * there are no boards known to use channel 1.

>   */

>  

> +#include <linux/clk.h>

>  #include <linux/err.h>

>  #include <linux/init.h>

>  #include <linux/input.h>

> @@ -23,6 +24,7 @@

>  #include <linux/of_platform.h>

>  #include <linux/platform_device.h>

>  #include <linux/regulator/consumer.h>

> +#include <linux/reset.h>

>  #include <linux/slab.h>

>  

>  #define LRADC_CTRL		0x00

> @@ -83,6 +85,8 @@ struct sun4i_lradc_data {

>  	struct device *dev;

>  	struct input_dev *input;

>  	void __iomem *base;

> +	struct clk *clk;

> +	struct reset_control *reset;

>  	struct regulator *vref_supply;

>  	struct sun4i_lradc_keymap *chan0_map;

>  	const struct lradc_variant *variant;

> @@ -140,6 +144,14 @@ static int sun4i_lradc_open(struct input_dev *dev)

>  	if (error)

>  		return error;

>  

> +	error = reset_control_deassert(lradc->reset);

> +	if (error)

> +		goto err_disable_reg;

> +

> +	error = clk_prepare_enable(lradc->clk);

> +	if (error)

> +		goto err_assert_reset;

> +

>  	lradc->vref = regulator_get_voltage(lradc->vref_supply) *

>  		      lradc->variant->divisor_numerator /

>  		      lradc->variant->divisor_denominator;

> @@ -153,6 +165,13 @@ static int sun4i_lradc_open(struct input_dev *dev)

>  	writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);

>  

>  	return 0;

> +

> +err_assert_reset:

> +	reset_control_assert(lradc->reset);

> +err_disable_reg:

> +	regulator_disable(lradc->vref_supply);

> +

> +	return error;

>  }

>  

>  static void sun4i_lradc_close(struct input_dev *dev)

> @@ -164,6 +183,8 @@ static void sun4i_lradc_close(struct input_dev *dev)

>  		SAMPLE_RATE(2), lradc->base + LRADC_CTRL);

>  	writel(0, lradc->base + LRADC_INTC);

>  

> +	clk_disable_unprepare(lradc->clk);

> +	reset_control_assert(lradc->reset);

>  	regulator_disable(lradc->vref_supply);

>  }

>  

> @@ -243,6 +264,14 @@ static int sun4i_lradc_probe(struct platform_device *pdev)

>  		return -EINVAL;

>  	}

>  

> +	lradc->clk = devm_clk_get_optional(dev, NULL);

> +	if (IS_ERR(lradc->clk))

> +		return PTR_ERR(lradc->clk);

> +

> +	lradc->reset = devm_reset_control_get_optional_exclusive(dev, NULL);

> +	if (IS_ERR(lradc->reset))

> +		return PTR_ERR(lradc->reset);

> +


This wouldn't report an error if the clocks are missing on the R329 (and
D1), even though they are required. The way we usually deal with this is
through a flag in the variant structure (at least to guard clk_get /
reset_control_get)

Maxime