mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	The generic AXP SPL driver implementation can cover all regulators we need for the AXP305. Add the descriptions for four of the six DC/DC regulators of the AXP305, and enable that when CONFIG_AXP305_POWER is enabled. We won't need DCDC2 and DCDC3, but by using the position in the array for the index we keep the code cleaner. Also remove the old driver, and switch the Makefile to include the new, generic driver. Signed-off-by: Andre Przywara <andre.przywara@arm.com>
		
			
				
	
	
		
			174 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0+
 | 
						|
/*
 | 
						|
 * AXP PMIC SPL driver
 | 
						|
 * (C) Copyright 2024 Arm Ltd.
 | 
						|
 */
 | 
						|
 | 
						|
#include <errno.h>
 | 
						|
#include <linux/types.h>
 | 
						|
#include <asm/arch/pmic_bus.h>
 | 
						|
#include <axp_pmic.h>
 | 
						|
 | 
						|
struct axp_reg_desc_spl {
 | 
						|
	u8	enable_reg;
 | 
						|
	u8	enable_mask;
 | 
						|
	u8	volt_reg;
 | 
						|
	u8	volt_mask;
 | 
						|
	u16	min_mV;
 | 
						|
	u16	max_mV;
 | 
						|
	u8	step_mV;
 | 
						|
	u8	split;
 | 
						|
};
 | 
						|
 | 
						|
#define NA 0xff
 | 
						|
 | 
						|
#if defined(CONFIG_AXP717_POWER)				/* AXP717 */
 | 
						|
 | 
						|
static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
 | 
						|
	{ 0x80, BIT(0), 0x83, 0x7f,  500, 1540,  10, 70 },
 | 
						|
	{ 0x80, BIT(1), 0x84, 0x7f,  500, 1540,  10, 70 },
 | 
						|
	{ 0x80, BIT(2), 0x85, 0x7f,  500, 1840,  10, 70 },
 | 
						|
};
 | 
						|
 | 
						|
#define AXP_CHIP_VERSION	0x0
 | 
						|
#define AXP_CHIP_VERSION_MASK	0x0
 | 
						|
#define AXP_CHIP_ID		0x0
 | 
						|
#define AXP_SHUTDOWN_REG	0x27
 | 
						|
#define AXP_SHUTDOWN_MASK	BIT(0)
 | 
						|
 | 
						|
#elif defined(CONFIG_AXP313_POWER)				/* AXP313 */
 | 
						|
 | 
						|
static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
 | 
						|
	{ 0x10, BIT(0), 0x13, 0x7f,  500, 1540,  10, 70 },
 | 
						|
	{ 0x10, BIT(1), 0x14, 0x7f,  500, 1540,  10, 70 },
 | 
						|
	{ 0x10, BIT(2), 0x15, 0x7f,  500, 1840,  10, 70 },
 | 
						|
};
 | 
						|
 | 
						|
#define AXP_CHIP_VERSION	0x3
 | 
						|
#define AXP_CHIP_VERSION_MASK	0xc8
 | 
						|
#define AXP_CHIP_ID		0x48
 | 
						|
#define AXP_SHUTDOWN_REG	0x1a
 | 
						|
#define AXP_SHUTDOWN_MASK	BIT(7)
 | 
						|
 | 
						|
#elif defined(CONFIG_AXP305_POWER)				/* AXP305 */
 | 
						|
 | 
						|
static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
 | 
						|
	{ 0x10, BIT(0), 0x12, 0x7f,  600, 1520,  10, 50 },
 | 
						|
	{ 0x10, BIT(1), 0x13, 0x1f, 1000, 2550,  50, NA },
 | 
						|
	{ 0x10, BIT(2), 0x14, 0x7f,  600, 1520,  10, 50 },
 | 
						|
	{ 0x10, BIT(3), 0x15, 0x3f,  600, 1500,  20, NA },
 | 
						|
	{ 0x10, BIT(4), 0x16, 0x1f, 1100, 3400, 100, NA },
 | 
						|
};
 | 
						|
 | 
						|
#define AXP_CHIP_VERSION	0x3
 | 
						|
#define AXP_CHIP_VERSION_MASK	0xcf
 | 
						|
#define AXP_CHIP_ID		0x40
 | 
						|
#define AXP_SHUTDOWN_REG	0x32
 | 
						|
#define AXP_SHUTDOWN_MASK	BIT(7)
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
	#error "Please define the regulator registers in axp_spl_regulators[]."
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
static u8 axp_mvolt_to_cfg(int mvolt, const struct axp_reg_desc_spl *reg)
 | 
						|
{
 | 
						|
	if (mvolt < reg->min_mV)
 | 
						|
		mvolt = reg->min_mV;
 | 
						|
	else if (mvolt > reg->max_mV)
 | 
						|
		mvolt = reg->max_mV;
 | 
						|
 | 
						|
	mvolt -= reg->min_mV;
 | 
						|
 | 
						|
	/* voltage in the first range ? */
 | 
						|
	if (mvolt <= reg->split * reg->step_mV)
 | 
						|
		return mvolt / reg->step_mV;
 | 
						|
 | 
						|
	mvolt -= reg->split * reg->step_mV;
 | 
						|
 | 
						|
	return reg->split + mvolt / (reg->step_mV * 2);
 | 
						|
}
 | 
						|
 | 
						|
static int axp_set_dcdc(int dcdc_num, unsigned int mvolt)
 | 
						|
{
 | 
						|
	const struct axp_reg_desc_spl *reg;
 | 
						|
	int ret;
 | 
						|
 | 
						|
	if (dcdc_num < 1 || dcdc_num > ARRAY_SIZE(axp_spl_dcdc_regulators))
 | 
						|
		return -EINVAL;
 | 
						|
 | 
						|
	reg = &axp_spl_dcdc_regulators[dcdc_num - 1];
 | 
						|
 | 
						|
	if (mvolt == 0)
 | 
						|
		return pmic_bus_clrbits(reg->enable_reg, reg->enable_mask);
 | 
						|
 | 
						|
	ret = pmic_bus_write(reg->volt_reg, axp_mvolt_to_cfg(mvolt, reg));
 | 
						|
	if (ret)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	return pmic_bus_setbits(reg->enable_reg, reg->enable_mask);
 | 
						|
}
 | 
						|
 | 
						|
int axp_set_dcdc1(unsigned int mvolt)
 | 
						|
{
 | 
						|
	return axp_set_dcdc(1, mvolt);
 | 
						|
}
 | 
						|
 | 
						|
int axp_set_dcdc2(unsigned int mvolt)
 | 
						|
{
 | 
						|
	return axp_set_dcdc(2, mvolt);
 | 
						|
}
 | 
						|
 | 
						|
int axp_set_dcdc3(unsigned int mvolt)
 | 
						|
{
 | 
						|
	return axp_set_dcdc(3, mvolt);
 | 
						|
}
 | 
						|
 | 
						|
int axp_set_dcdc4(unsigned int mvolt)
 | 
						|
{
 | 
						|
	return axp_set_dcdc(4, mvolt);
 | 
						|
}
 | 
						|
 | 
						|
int axp_set_dcdc5(unsigned int mvolt)
 | 
						|
{
 | 
						|
	return axp_set_dcdc(5, mvolt);
 | 
						|
}
 | 
						|
 | 
						|
int axp_init(void)
 | 
						|
{
 | 
						|
	int ret = pmic_bus_init();
 | 
						|
 | 
						|
	if (ret)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	if (AXP_CHIP_VERSION_MASK) {
 | 
						|
		u8 axp_chip_id;
 | 
						|
 | 
						|
		ret = pmic_bus_read(AXP_CHIP_VERSION, &axp_chip_id);
 | 
						|
		if (ret)
 | 
						|
			return ret;
 | 
						|
 | 
						|
		if ((axp_chip_id & AXP_CHIP_VERSION_MASK) != AXP_CHIP_ID) {
 | 
						|
			debug("unknown PMIC: 0x%x\n", axp_chip_id);
 | 
						|
			return -EINVAL;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
#if !CONFIG_IS_ENABLED(ARM_PSCI_FW) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
 | 
						|
int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 | 
						|
{
 | 
						|
	pmic_bus_setbits(AXP_SHUTDOWN_REG, AXP_SHUTDOWN_MASK);
 | 
						|
 | 
						|
	/* infinite loop during shutdown */
 | 
						|
	while (1)
 | 
						|
		;
 | 
						|
 | 
						|
	/* not reached */
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
#endif
 |