forked from dlink-dir_819/openwrt
		
	Add u-boot bootloader based on 2023.01 to support D1-based boards, currently: - Dongshan Nezha STU - LicheePi RV Dock - MangoPi MQ-Pro - Nezha D1 Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
		
			
				
	
	
		
			376 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			376 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 697eb56ed8c9b3814ddbd87ae0c6e749ccafc9e3 Mon Sep 17 00:00:00 2001
 | |
| From: Samuel Holland <samuel@sholland.org>
 | |
| Date: Sat, 28 Aug 2021 00:27:19 -0500
 | |
| Subject: [PATCH 50/90] gpio: axp: Select variant from compatible at runtime
 | |
| 
 | |
| There are three major variants of the AXP PMIC GPIO functionality (plus
 | |
| PMICs with no GPIOs at all). Except for GPIO3 on the AXP209, which uses
 | |
| a different register layout, it is straightforward to support all three
 | |
| variants with a single driver. Do this, and in the process remove the
 | |
| GPIO-related definitions from the PMIC-specific headers, and therefore
 | |
| the dependency on AXP_PMIC_BUS.
 | |
| 
 | |
| Signed-off-by: Samuel Holland <samuel@sholland.org>
 | |
| ---
 | |
|  drivers/gpio/Kconfig    |   1 -
 | |
|  drivers/gpio/axp_gpio.c | 137 +++++++++++++++++++++-------------------
 | |
|  drivers/power/axp209.c  |   6 +-
 | |
|  drivers/power/axp221.c  |   4 +-
 | |
|  include/axp152.h        |  10 ---
 | |
|  include/axp209.h        |  16 ++---
 | |
|  include/axp221.h        |  13 ++--
 | |
|  include/axp809.h        |   8 ---
 | |
|  include/axp818.h        |   8 ---
 | |
|  9 files changed, 89 insertions(+), 114 deletions(-)
 | |
| 
 | |
| --- a/drivers/gpio/Kconfig
 | |
| +++ b/drivers/gpio/Kconfig
 | |
| @@ -107,7 +107,6 @@ config ALTERA_PIO
 | |
|  config AXP_GPIO
 | |
|  	bool "X-Powers AXP PMICs GPIO driver"
 | |
|  	depends on DM_GPIO && PMIC_AXP
 | |
| -	depends on AXP_PMIC_BUS
 | |
|  	help
 | |
|  	  This driver supports the GPIO pins on
 | |
|  	  X-Powers AXP152, AXP2xx, and AXP8xx PMICs.
 | |
| --- a/drivers/gpio/axp_gpio.c
 | |
| +++ b/drivers/gpio/axp_gpio.c
 | |
| @@ -7,110 +7,117 @@
 | |
|  
 | |
|  #include <common.h>
 | |
|  #include <asm/gpio.h>
 | |
| -#include <axp_pmic.h>
 | |
|  #include <dm.h>
 | |
| +#include <dm/device-internal.h>
 | |
|  #include <errno.h>
 | |
|  #include <power/pmic.h>
 | |
|  
 | |
|  #define AXP_GPIO_PREFIX			"AXP0-"
 | |
|  #define AXP_GPIO_COUNT			4
 | |
|  
 | |
| -static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
 | |
| -
 | |
| -static u8 axp_get_gpio_ctrl_reg(unsigned pin)
 | |
| -{
 | |
| -	switch (pin) {
 | |
| -	case 0: return AXP_GPIO0_CTRL;
 | |
| -	case 1: return AXP_GPIO1_CTRL;
 | |
| -#ifdef AXP_GPIO2_CTRL
 | |
| -	case 2: return AXP_GPIO2_CTRL;
 | |
| -#endif
 | |
| -#ifdef AXP_GPIO3_CTRL
 | |
| -	case 3: return AXP_GPIO3_CTRL;
 | |
| -#endif
 | |
| -	}
 | |
| -	return 0;
 | |
| -}
 | |
| -
 | |
| -static int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
 | |
| -{
 | |
| -	u8 reg;
 | |
| -
 | |
| -	reg = axp_get_gpio_ctrl_reg(pin);
 | |
| -	if (reg == 0)
 | |
| -		return -EINVAL;
 | |
| -
 | |
| -	return pmic_reg_write(dev->parent, reg, AXP_GPIO_CTRL_INPUT);
 | |
| -}
 | |
| -
 | |
| -static int axp_gpio_direction_output(struct udevice *dev, unsigned pin,
 | |
| -				     int val)
 | |
| -{
 | |
| -	u8 reg;
 | |
| -
 | |
| -	reg = axp_get_gpio_ctrl_reg(pin);
 | |
| -	if (reg == 0)
 | |
| -		return -EINVAL;
 | |
| -
 | |
| -	return pmic_reg_write(dev->parent, reg,
 | |
| -			      val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
 | |
| -				    AXP_GPIO_CTRL_OUTPUT_LOW);
 | |
| -}
 | |
| +#define AXP_GPIO_CTRL_MASK		0x7
 | |
| +#define AXP_GPIO_CTRL_OUTPUT_LOW	0
 | |
| +#define AXP_GPIO_CTRL_OUTPUT_HIGH	1
 | |
| +
 | |
| +struct axp_gpio_desc {
 | |
| +	const u8	*pins;
 | |
| +	u8		npins;
 | |
| +	u8		status_reg;
 | |
| +	u8		status_offset;
 | |
| +	u8		input_mux;
 | |
| +};
 | |
|  
 | |
|  static int axp_gpio_get_value(struct udevice *dev, unsigned pin)
 | |
|  {
 | |
| -	u8 reg, mask;
 | |
| +	const struct axp_gpio_desc *desc = dev_get_priv(dev);
 | |
|  	int ret;
 | |
|  
 | |
| -	reg = axp_get_gpio_ctrl_reg(pin);
 | |
| -	if (reg == 0)
 | |
| -		return -EINVAL;
 | |
| -
 | |
| -	ret = pmic_reg_read(dev->parent, AXP_GPIO_STATE);
 | |
| +	ret = pmic_reg_read(dev->parent, desc->status_reg);
 | |
|  	if (ret < 0)
 | |
|  		return ret;
 | |
|  
 | |
| -	mask = 1 << (pin + AXP_GPIO_STATE_OFFSET);
 | |
| -
 | |
| -	return (ret & mask) ? 1 : 0;
 | |
| +	return !!(ret & BIT(desc->status_offset + pin));
 | |
|  }
 | |
|  
 | |
| -static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
 | |
| +static int axp_gpio_set_flags(struct udevice *dev, unsigned pin, ulong flags)
 | |
|  {
 | |
| -	u8 reg;
 | |
| +	const struct axp_gpio_desc *desc = dev_get_priv(dev);
 | |
| +	u8 mux;
 | |
|  
 | |
| -	reg = axp_get_gpio_ctrl_reg(pin);
 | |
| -	if (reg == 0)
 | |
| +	if (flags & (GPIOD_MASK_DSTYPE | GPIOD_MASK_PULL))
 | |
|  		return -EINVAL;
 | |
|  
 | |
| -	return pmic_reg_write(dev->parent, reg,
 | |
| -			      val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
 | |
| -				    AXP_GPIO_CTRL_OUTPUT_LOW);
 | |
| +	if (flags & GPIOD_IS_IN)
 | |
| +		mux = desc->input_mux;
 | |
| +	else if (flags & GPIOD_IS_OUT_ACTIVE)
 | |
| +		mux = AXP_GPIO_CTRL_OUTPUT_HIGH;
 | |
| +	else
 | |
| +		mux = AXP_GPIO_CTRL_OUTPUT_LOW;
 | |
| +
 | |
| +	return pmic_clrsetbits(dev->parent, desc->pins[pin],
 | |
| +			       AXP_GPIO_CTRL_MASK, mux);
 | |
|  }
 | |
|  
 | |
|  static const struct dm_gpio_ops axp_gpio_ops = {
 | |
| -	.direction_input	= axp_gpio_direction_input,
 | |
| -	.direction_output	= axp_gpio_direction_output,
 | |
|  	.get_value		= axp_gpio_get_value,
 | |
| -	.set_value		= axp_gpio_set_value,
 | |
| +	.xlate			= gpio_xlate_offs_flags,
 | |
| +	.set_flags		= axp_gpio_set_flags,
 | |
|  };
 | |
|  
 | |
|  static int axp_gpio_probe(struct udevice *dev)
 | |
|  {
 | |
| +	struct axp_gpio_desc *desc = (void *)dev_get_driver_data(dev);
 | |
|  	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 | |
|  
 | |
| +	dev_set_priv(dev, desc);
 | |
| +
 | |
|  	/* Tell the uclass how many GPIOs we have */
 | |
|  	uc_priv->bank_name = AXP_GPIO_PREFIX;
 | |
| -	uc_priv->gpio_count = AXP_GPIO_COUNT;
 | |
| +	uc_priv->gpio_count = desc->npins;
 | |
|  
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| +static const u8 axp152_gpio_pins[] = {
 | |
| +	0x90, 0x91, 0x92, 0x93,
 | |
| +};
 | |
| +
 | |
| +static const struct axp_gpio_desc axp152_gpio_desc = {
 | |
| +	.pins		= axp152_gpio_pins,
 | |
| +	.npins		= ARRAY_SIZE(axp152_gpio_pins),
 | |
| +	.status_reg	= 0x97,
 | |
| +	.status_offset	= 4,
 | |
| +	.input_mux	= 3,
 | |
| +};
 | |
| +
 | |
| +static const u8 axp209_gpio_pins[] = {
 | |
| +	0x90, 0x92, 0x93,
 | |
| +};
 | |
| +
 | |
| +static const struct axp_gpio_desc axp209_gpio_desc = {
 | |
| +	.pins		= axp209_gpio_pins,
 | |
| +	.npins		= ARRAY_SIZE(axp209_gpio_pins),
 | |
| +	.status_reg	= 0x94,
 | |
| +	.status_offset	= 4,
 | |
| +	.input_mux	= 2,
 | |
| +};
 | |
| +
 | |
| +static const u8 axp221_gpio_pins[] = {
 | |
| +	0x90, 0x92,
 | |
| +};
 | |
| +
 | |
| +static const struct axp_gpio_desc axp221_gpio_desc = {
 | |
| +	.pins		= axp221_gpio_pins,
 | |
| +	.npins		= ARRAY_SIZE(axp221_gpio_pins),
 | |
| +	.status_reg	= 0x94,
 | |
| +	.input_mux	= 2,
 | |
| +};
 | |
| +
 | |
|  static const struct udevice_id axp_gpio_ids[] = {
 | |
| -	{ .compatible = "x-powers,axp152-gpio" },
 | |
| -	{ .compatible = "x-powers,axp209-gpio" },
 | |
| -	{ .compatible = "x-powers,axp221-gpio" },
 | |
| -	{ .compatible = "x-powers,axp813-gpio" },
 | |
| +	{ .compatible = "x-powers,axp152-gpio", .data = (ulong)&axp152_gpio_desc },
 | |
| +	{ .compatible = "x-powers,axp209-gpio", .data = (ulong)&axp209_gpio_desc },
 | |
| +	{ .compatible = "x-powers,axp221-gpio", .data = (ulong)&axp221_gpio_desc },
 | |
| +	{ .compatible = "x-powers,axp813-gpio", .data = (ulong)&axp221_gpio_desc },
 | |
|  	{ }
 | |
|  };
 | |
|  
 | |
| --- a/drivers/power/axp209.c
 | |
| +++ b/drivers/power/axp209.c
 | |
| @@ -215,15 +215,15 @@ int axp_init(void)
 | |
|  	 * Turn off LDOIO regulators / tri-state GPIO pins, when rebooting
 | |
|  	 * from android these are sometimes on.
 | |
|  	 */
 | |
| -	rc = pmic_bus_write(AXP_GPIO0_CTRL, AXP_GPIO_CTRL_INPUT);
 | |
| +	rc = pmic_bus_write(AXP209_GPIO0_CTRL, AXP209_GPIO_CTRL_INPUT);
 | |
|  	if (rc)
 | |
|  		return rc;
 | |
|  
 | |
| -	rc = pmic_bus_write(AXP_GPIO1_CTRL, AXP_GPIO_CTRL_INPUT);
 | |
| +	rc = pmic_bus_write(AXP209_GPIO1_CTRL, AXP209_GPIO_CTRL_INPUT);
 | |
|  	if (rc)
 | |
|  		return rc;
 | |
|  
 | |
| -	rc = pmic_bus_write(AXP_GPIO2_CTRL, AXP_GPIO_CTRL_INPUT);
 | |
| +	rc = pmic_bus_write(AXP209_GPIO2_CTRL, AXP209_GPIO_CTRL_INPUT);
 | |
|  	if (rc)
 | |
|  		return rc;
 | |
|  
 | |
| --- a/drivers/power/axp221.c
 | |
| +++ b/drivers/power/axp221.c
 | |
| @@ -226,11 +226,11 @@ int axp_init(void)
 | |
|  	 * Turn off LDOIO regulators / tri-state GPIO pins, when rebooting
 | |
|  	 * from android these are sometimes on.
 | |
|  	 */
 | |
| -	ret = pmic_bus_write(AXP_GPIO0_CTRL, AXP_GPIO_CTRL_INPUT);
 | |
| +	ret = pmic_bus_write(AXP221_GPIO0_CTRL, AXP221_GPIO_CTRL_INPUT);
 | |
|  	if (ret)
 | |
|  		return ret;
 | |
|  
 | |
| -	ret = pmic_bus_write(AXP_GPIO1_CTRL, AXP_GPIO_CTRL_INPUT);
 | |
| +	ret = pmic_bus_write(AXP221_GPIO1_CTRL, AXP221_GPIO_CTRL_INPUT);
 | |
|  	if (ret)
 | |
|  		return ret;
 | |
|  
 | |
| --- a/include/axp152.h
 | |
| +++ b/include/axp152.h
 | |
| @@ -14,17 +14,7 @@ enum axp152_reg {
 | |
|  
 | |
|  #define AXP152_POWEROFF			(1 << 7)
 | |
|  
 | |
| -/* For axp_gpio.c */
 | |
|  #ifdef CONFIG_AXP152_POWER
 | |
|  #define AXP_POWER_STATUS		0x00
 | |
|  #define AXP_POWER_STATUS_ALDO_IN		BIT(0)
 | |
| -#define AXP_GPIO0_CTRL			0x90
 | |
| -#define AXP_GPIO1_CTRL			0x91
 | |
| -#define AXP_GPIO2_CTRL			0x92
 | |
| -#define AXP_GPIO3_CTRL			0x93
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_LOW		0x00 /* Drive pin low */
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_HIGH		0x01 /* Drive pin high */
 | |
| -#define AXP_GPIO_CTRL_INPUT			0x02 /* Input */
 | |
| -#define AXP_GPIO_STATE			0x97
 | |
| -#define AXP_GPIO_STATE_OFFSET			0
 | |
|  #endif
 | |
| --- a/include/axp209.h
 | |
| +++ b/include/axp209.h
 | |
| @@ -21,6 +21,9 @@ enum axp209_reg {
 | |
|  	AXP209_IRQ_ENABLE5 = 0x44,
 | |
|  	AXP209_IRQ_STATUS5 = 0x4c,
 | |
|  	AXP209_SHUTDOWN = 0x32,
 | |
| +	AXP209_GPIO0_CTRL = 0x90,
 | |
| +	AXP209_GPIO1_CTRL = 0x92,
 | |
| +	AXP209_GPIO2_CTRL = 0x93,
 | |
|  };
 | |
|  
 | |
|  #define AXP209_POWER_STATUS_ON_BY_DC	BIT(0)
 | |
| @@ -73,16 +76,11 @@ enum axp209_reg {
 | |
|  
 | |
|  #define AXP209_POWEROFF			BIT(7)
 | |
|  
 | |
| -/* For axp_gpio.c */
 | |
| +#define AXP209_GPIO_CTRL_OUTPUT_LOW	0x00
 | |
| +#define AXP209_GPIO_CTRL_OUTPUT_HIGH	0x01
 | |
| +#define AXP209_GPIO_CTRL_INPUT		0x02
 | |
| +
 | |
|  #ifdef CONFIG_AXP209_POWER
 | |
|  #define AXP_POWER_STATUS		0x00
 | |
|  #define AXP_POWER_STATUS_ALDO_IN		BIT(0)
 | |
| -#define AXP_GPIO0_CTRL			0x90
 | |
| -#define AXP_GPIO1_CTRL			0x92
 | |
| -#define AXP_GPIO2_CTRL			0x93
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_LOW	0x00 /* Drive pin low */
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_HIGH	0x01 /* Drive pin high */
 | |
| -#define AXP_GPIO_CTRL_INPUT		0x02 /* Input */
 | |
| -#define AXP_GPIO_STATE			0x94
 | |
| -#define AXP_GPIO_STATE_OFFSET		4
 | |
|  #endif
 | |
| --- a/include/axp221.h
 | |
| +++ b/include/axp221.h
 | |
| @@ -44,20 +44,17 @@
 | |
|  #define AXP221_ALDO3_CTRL	0x2a
 | |
|  #define AXP221_SHUTDOWN		0x32
 | |
|  #define AXP221_SHUTDOWN_POWEROFF	(1 << 7)
 | |
| +#define AXP221_GPIO0_CTRL	0x90
 | |
| +#define AXP221_GPIO1_CTRL	0x92
 | |
| +#define AXP221_GPIO_CTRL_OUTPUT_LOW	0x00
 | |
| +#define AXP221_GPIO_CTRL_OUTPUT_HIGH	0x01
 | |
| +#define AXP221_GPIO_CTRL_INPUT		0x02
 | |
|  #define AXP221_PAGE		0xff
 | |
|  
 | |
|  /* Page 1 addresses */
 | |
|  #define AXP221_SID		0x20
 | |
|  
 | |
| -/* For axp_gpio.c */
 | |
|  #ifdef CONFIG_AXP221_POWER
 | |
|  #define AXP_POWER_STATUS		0x00
 | |
|  #define AXP_POWER_STATUS_ALDO_IN		BIT(0)
 | |
| -#define AXP_GPIO0_CTRL			0x90
 | |
| -#define AXP_GPIO1_CTRL			0x92
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_LOW		0x00 /* Drive pin low */
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_HIGH		0x01 /* Drive pin high */
 | |
| -#define AXP_GPIO_CTRL_INPUT			0x02 /* Input */
 | |
| -#define AXP_GPIO_STATE			0x94
 | |
| -#define AXP_GPIO_STATE_OFFSET			0
 | |
|  #endif
 | |
| --- a/include/axp809.h
 | |
| +++ b/include/axp809.h
 | |
| @@ -43,15 +43,7 @@
 | |
|  #define AXP809_SHUTDOWN		0x32
 | |
|  #define AXP809_SHUTDOWN_POWEROFF	(1 << 7)
 | |
|  
 | |
| -/* For axp_gpio.c */
 | |
|  #ifdef CONFIG_AXP809_POWER
 | |
|  #define AXP_POWER_STATUS		0x00
 | |
|  #define AXP_POWER_STATUS_ALDO_IN		BIT(0)
 | |
| -#define AXP_GPIO0_CTRL			0x90
 | |
| -#define AXP_GPIO1_CTRL			0x92
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_LOW	0x00 /* Drive pin low */
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_HIGH	0x01 /* Drive pin high */
 | |
| -#define AXP_GPIO_CTRL_INPUT		0x02 /* Input */
 | |
| -#define AXP_GPIO_STATE			0x94
 | |
| -#define AXP_GPIO_STATE_OFFSET		0
 | |
|  #endif
 | |
| --- a/include/axp818.h
 | |
| +++ b/include/axp818.h
 | |
| @@ -57,15 +57,7 @@
 | |
|  #define AXP818_SHUTDOWN		0x32
 | |
|  #define AXP818_SHUTDOWN_POWEROFF	(1 << 7)
 | |
|  
 | |
| -/* For axp_gpio.c */
 | |
|  #ifdef CONFIG_AXP818_POWER
 | |
|  #define AXP_POWER_STATUS		0x00
 | |
|  #define AXP_POWER_STATUS_ALDO_IN		BIT(0)
 | |
| -#define AXP_GPIO0_CTRL			0x90
 | |
| -#define AXP_GPIO1_CTRL			0x92
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_LOW	0x00 /* Drive pin low */
 | |
| -#define AXP_GPIO_CTRL_OUTPUT_HIGH	0x01 /* Drive pin high */
 | |
| -#define AXP_GPIO_CTRL_INPUT		0x02 /* Input */
 | |
| -#define AXP_GPIO_STATE			0x94
 | |
| -#define AXP_GPIO_STATE_OFFSET		0
 | |
|  #endif
 |