Commit 1c50c3a1 authored by Lothar Felten's avatar Lothar Felten Committed by Carles Cufi
Browse files

drivers: regulator: add support for AXP2101 power management IC



Add initial support for the AXP2101 power management IC from X-powers.
Remark: only DC/DC1 and ALDO have been tested on real hardware.

Co-authored-by: default avatarTOKITA Hiroshi <tokita.hiroshi@gmail.com>
Co-authored-by: default avatarGerard Marull-Paretas <gerard.marull@nordicsemi.no>

Signed-off-by: default avatarLothar Felten <lothar.felten@gmail.com>
parent 648b5838
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ config GPIO_HOGS_INIT_PRIORITY
config MFD_INIT_PRIORITY
	default 70

config REGULATOR_AXP192_INIT_PRIORITY
config REGULATOR_AXP192_AXP2101_INIT_PRIORITY
	default 71

config GPIO_AXP192_INIT_PRIORITY
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ config GPIO_HOGS_INIT_PRIORITY
config MFD_INIT_PRIORITY
	default 70

config REGULATOR_AXP192_INIT_PRIORITY
config REGULATOR_AXP192_AXP2101_INIT_PRIORITY
	default 71

config GPIO_AXP192_INIT_PRIORITY
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_MFD_NCT38XX mfd_nct38xx.c)
zephyr_library_sources_ifdef(CONFIG_MFD_NPM1300 mfd_npm1300.c)
zephyr_library_sources_ifdef(CONFIG_MFD_NPM2100 mfd_npm2100.c)
zephyr_library_sources_ifdef(CONFIG_MFD_NPM6001 mfd_npm6001.c)
zephyr_library_sources_ifdef(CONFIG_MFD_AXP192 mfd_axp192.c)
zephyr_library_sources_ifdef(CONFIG_MFD_AXP192_AXP2101 mfd_axp192.c)
zephyr_library_sources_ifdef(CONFIG_MFD_AD559X mfd_ad559x.c)
zephyr_library_sources_ifdef(CONFIG_MFD_AD559X_BUS_I2C mfd_ad559x_i2c.c)
zephyr_library_sources_ifdef(CONFIG_MFD_AD559X_BUS_SPI mfd_ad559x_spi.c)
+4 −4
Original line number Diff line number Diff line
# Copyright (c) 2023 Martin Kiepfer <mrmarteng@teleschirm.org>
# SPDX-License-Identifier: Apache-2.0

config MFD_AXP192
	bool "AXP192 PMIC multi-function device driver"
config MFD_AXP192_AXP2101
	bool "AXP192/AXP2101 PMIC multi-function device driver"
	default y
	depends on DT_HAS_X_POWERS_AXP192_ENABLED
	depends on DT_HAS_X_POWERS_AXP192_ENABLED || DT_HAS_X_POWERS_AXP2101_ENABLED
	select I2C
	help
	  Enable the X-Powers AXP192 PMIC multi-function device driver
	  Enable the X-Powers AXP192/AXP2101 PMIC multi-function device driver
+59 −25
Original line number Diff line number Diff line
@@ -3,8 +3,6 @@
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT x_powers_axp192

#include <errno.h>
#include <stdbool.h>

@@ -15,6 +13,19 @@

LOG_MODULE_REGISTER(mfd_axp192, CONFIG_MFD_LOG_LEVEL);

struct mfd_axp192_config {
	struct i2c_dt_spec i2c;
#ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED
	bool vbusen_disable;
#endif
	uint8_t reg_chip_id;
	uint8_t vbus_config_reg;
	uint8_t chip_id;
	uint8_t val_vbusen_disable;
};

#ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED

/* Chip ID value */
#define AXP192_CHIP_ID 0x03U

@@ -97,11 +108,6 @@ LOG_MODULE_REGISTER(mfd_axp192, CONFIG_MFD_LOG_LEVEL);
#define AXP192_GPIO5_OUTPUT_VAL   0x04U
#define AXP192_GPIO5_OUTPUT_SHIFT 3U

struct mfd_axp192_config {
	struct i2c_dt_spec i2c;
	bool vbusen_disable;
};

struct mfd_axp192_data {
	const struct device *gpio_mask_used[AXP192_GPIO_MAX_NUM];
	uint8_t gpio_mask_output;
@@ -139,12 +145,27 @@ const struct mfd_axp192_func_reg_desc gpio_reg_desc[AXP192_GPIO_MAX_NUM] = {
		.mask = AXP192_GPIO4_FUNC_MASK,
	},
};
#endif /* CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED */

#ifdef CONFIG_DT_HAS_X_POWERS_AXP2101_ENABLED

/* Chip ID value */
#define AXP2101_CHIP_ID		0x4AU

/* Registers definitions */
#define AXP2101_REG_CHIP_ID	0x03U

/* AXP210 GPIO register addresses */
#define AXP2101_VBUS_CFG_REG	0x00U

/* VBUS control reg values */
#define AXP2101_VBUS_CFG_VAL_VBUSEN_DISABLE	0x00U
#endif /* CONFIG_DT_HAS_X_POWERS_AXP2101_ENABLED */

static int mfd_axp192_init(const struct device *dev)
{
	const struct mfd_axp192_config *config = dev->config;
	uint8_t chip_id;
	uint8_t vbus_val;
	int ret;

	LOG_DBG("Initializing instance");
@@ -155,29 +176,29 @@ static int mfd_axp192_init(const struct device *dev)
	}

	/* Check if axp192 chip is available */
	ret = i2c_reg_read_byte_dt(&config->i2c, AXP192_REG_CHIP_ID, &chip_id);
	ret = i2c_reg_read_byte_dt(&config->i2c, config->reg_chip_id, &chip_id);
	if (ret < 0) {
		return ret;
	}
	if (chip_id != AXP192_CHIP_ID) {
	if (chip_id != config->chip_id) {
		LOG_ERR("Invalid Chip detected (%d)", chip_id);
		return -EINVAL;
	}

#ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED
	/* Disable N_VBUSEN */
	vbus_val = 0;
	if (config->vbusen_disable) {
		vbus_val = AXP192_VBUS_CFG_VAL_VBUSEN_DISABLE;
	}
	ret = i2c_reg_update_byte_dt(&config->i2c, AXP192_VBUS_CFG_REG,
				     AXP192_VBUS_CFG_VAL_VBUSEN_DISABLE, vbus_val);
	ret = i2c_reg_update_byte_dt(
		&config->i2c, config->vbus_config_reg, config->val_vbusen_disable,
		config->vbusen_disable ? config->val_vbusen_disable : 0);
	if (ret < 0) {
		return ret;
	}
#endif

	return 0;
}

#ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED
int mfd_axp192_gpio_func_get(const struct device *dev, uint8_t gpio, enum axp192_gpio_func *func)
{
	const struct mfd_axp192_config *config = dev->config;
@@ -605,16 +626,29 @@ int mfd_axp192_gpio_write_port(const struct device *dev, uint8_t value, uint8_t

	return 0;
}
#endif

#define MFD_AXP192_CONST_CONFIG(model)                                                             \
	.reg_chip_id = AXP##model##_REG_CHIP_ID,                                                   \
	.vbus_config_reg = AXP##model##_VBUS_CFG_REG,                                              \
	.chip_id = AXP##model##_CHIP_ID,                                                           \
	.val_vbusen_disable = AXP##model##_CHIP_ID,

#define MFD_AXP192_DEFINE(inst)                                                                    \
	static const struct mfd_axp192_config config##inst = {                                     \
		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
		.vbusen_disable = DT_INST_PROP_OR(inst, vbusen_disable, false),                    \
#define MFD_AXP192_AXP2101_DEFINE(node, model)                                                     \
	static const struct mfd_axp192_config config##node = {                                     \
		.i2c = I2C_DT_SPEC_GET(node),                                                      \
		IF_ENABLED(CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED,                                  \
		(.vbusen_disable = DT_PROP_OR(node, vbusen_disable, false),))                      \
		MFD_AXP192_CONST_CONFIG(model)                                                     \
	};                                                                                         \
                                                                                                   \
	static struct mfd_axp192_data data##inst;                                                  \
	IF_ENABLED(CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED,                                          \
		   (static struct mfd_axp192_data data##node;))                                    \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(inst, mfd_axp192_init, NULL, &data##inst, &config##inst,             \
			      POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL);
	DEVICE_DT_DEFINE(node, mfd_axp192_init, NULL,                                              \
			 COND_CODE_1(CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED,                        \
				     (&data##node), (NULL)),                                       \
			 &config##node, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL);

DT_INST_FOREACH_STATUS_OKAY(MFD_AXP192_DEFINE);
DT_FOREACH_STATUS_OKAY_VARGS(x_powers_axp192, MFD_AXP192_AXP2101_DEFINE, 192);
DT_FOREACH_STATUS_OKAY_VARGS(x_powers_axp2101, MFD_AXP192_AXP2101_DEFINE, 2101);
Loading