diff options
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/pmic_bus.c | 10 | ||||
-rw-r--r-- | board/sunxi/board.c | 20 | ||||
-rw-r--r-- | drivers/power/Kconfig | 69 | ||||
-rw-r--r-- | drivers/power/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/axp809.c | 278 | ||||
-rw-r--r-- | include/axp809.h | 75 | ||||
-rw-r--r-- | include/axp_pmic.h | 4 | ||||
-rw-r--r-- | include/configs/sunxi-common.h | 2 |
9 files changed, 432 insertions, 28 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 0d6335abea..6c341fd2fa 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o obj-$(CONFIG_AXP152_POWER) += pmic_bus.o obj-$(CONFIG_AXP209_POWER) += pmic_bus.o obj-$(CONFIG_AXP221_POWER) += pmic_bus.o +obj-$(CONFIG_AXP809_POWER) += pmic_bus.o obj-$(CONFIG_AXP818_POWER) += pmic_bus.o ifndef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/armv7/sunxi/pmic_bus.c b/arch/arm/cpu/armv7/sunxi/pmic_bus.c index 5b81a8d8e1..d96130b6ed 100644 --- a/arch/arm/cpu/armv7/sunxi/pmic_bus.c +++ b/arch/arm/cpu/armv7/sunxi/pmic_bus.c @@ -4,7 +4,7 @@ * Sunxi PMIC bus access helpers * * The axp152 & axp209 use an i2c bus, the axp221 uses the p2wi bus and the - * axp223 uses the rsb bus, these functions abstract this. + * axp223/axp809 use the rsb bus, these functions abstract this. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -23,7 +23,7 @@ #define AXP221_CTRL_ADDR 0x3e #define AXP221_INIT_DATA 0x3e -/* AXP818 device and runtime addresses are same as AXP223 */ +/* AXP809 and AXP818 device and runtime addresses are same as AXP223 */ #define AXP223_DEVICE_ADDR 0x3a3 #define AXP223_RUNTIME_ADDR 0x2d @@ -36,7 +36,7 @@ int pmic_bus_init(void) if (!needs_init) return 0; -#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || defined CONFIG_AXP809_POWER # ifdef CONFIG_MACH_SUN6I p2wi_init(); ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, @@ -62,7 +62,7 @@ int pmic_bus_read(u8 reg, u8 *data) return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1); #elif defined CONFIG_AXP209_POWER return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1); -#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || defined CONFIG_AXP809_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_read(reg, data); # else @@ -77,7 +77,7 @@ int pmic_bus_write(u8 reg, u8 data) return i2c_write(AXP152_I2C_ADDR, reg, 1, &data, 1); #elif defined CONFIG_AXP209_POWER return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1); -#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || defined CONFIG_AXP809_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_write(reg, data); # else diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 718810bc19..ea0ab736e9 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -458,10 +458,15 @@ void sunxi_board_init(void) #endif #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ - defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER + defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || \ + defined CONFIG_AXP809_POWER power_failed = axp_init(); -#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP809_POWER + power_failed |= axp_set_dc5ldo(CONFIG_AXP_DC5LDO_VOLT); +#endif +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || \ + defined CONFIG_AXP809_POWER power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); #endif power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); @@ -469,11 +474,13 @@ void sunxi_board_init(void) #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER) power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); #endif -#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || \ + defined CONFIG_AXP809_POWER power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT); #endif -#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || \ + defined CONFIG_AXP809_POWER power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); #endif power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); @@ -484,11 +491,14 @@ void sunxi_board_init(void) power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT); #endif -#if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP818_POWER) +#if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP818_POWER) || \ + defined CONFIG_AXP809_POWER power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT); power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT); +#if !defined(CONFIG_AXP809_POWER) power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT); power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT); +#endif power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT); power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index adc64552e7..d17e2bd698 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -10,6 +10,7 @@ choice default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 default AXP818_POWER if MACH_SUN8I_A83T + default AXP809_POWER if MACH_SUN9I default SUNXI_NO_PMIC if MACH_SUN8I_H3 config SUNXI_NO_PMIC @@ -41,6 +42,14 @@ config AXP221_POWER Select this to enable support for the axp221/axp223 pmic found on most A23 and A31 boards. +config AXP809_POWER + boolean "axp809 pmic support" + depends on MACH_SUN9I + select CMD_POWEROFF + ---help--- + Select this to enable support for the axp809 pmic found on most A80 + boards. + config AXP818_POWER boolean "axp818 pmic support" depends on MACH_SUN8I_A83T @@ -59,9 +68,10 @@ endchoice config AXP_DCDC1_VOLT int "axp pmic dcdc1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER default 3300 if AXP818_POWER default 3000 if MACH_SUN6I || MACH_SUN8I + default 3300 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc1 at, set to 0 to disable dcdc1. On A23 / A31 / A33 (axp221) boards dcdc1 is used for @@ -69,14 +79,17 @@ config AXP_DCDC1_VOLT sdcard interfaces, etc. On most boards dcdc1 is undervolted to 3.0V to safe battery. On A31 devices dcdc1 is also used for VCC-IO. On A83T dcdc1 is used for VCC-IO, nand, usb0, sd , etc. + On the A80-Q7, dcdc1 is used for peripherals (e.g. GbE PHY) and IO and + should be set to 3.3V to ensure compliance with the Qseven specification. config AXP_DCDC2_VOLT int "axp pmic dcdc2 voltage" - depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER + depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER || AXP809_POWER default 900 if AXP818_POWER default 1400 if AXP152_POWER || AXP209_POWER default 1200 if MACH_SUN6I default 1100 if MACH_SUN8I + default 0 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc2 at, set to 0 to disable dcdc2. @@ -84,14 +97,17 @@ config AXP_DCDC2_VOLT On A31 boards dcdc2 is used for VDD-GPU and should be 1.2V. On A23/A33 boards dcdc2 is used for VDD-SYS and should be 1.1V. On A83T boards dcdc2 is used for VDD-CPUA(cluster 0) and should be 0.9V. + On A80 boards dcdc2 is used for VDD-GPU and should be 0.9V (we turn it + off in U-Boot, as the kernel can turn it on later on, if necessary). config AXP_DCDC3_VOLT int "axp pmic dcdc3 voltage" - depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER + depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER || AXP809_POWER default 900 if AXP818_POWER default 1500 if AXP152_POWER default 1250 if AXP209_POWER default 1200 if MACH_SUN6I || MACH_SUN8I + default 900 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc3 at, set to 0 to disable dcdc3. @@ -100,13 +116,15 @@ config AXP_DCDC3_VOLT On A10s boards with an axp152 dcdc3 is VCC-DRAM and should be 1.5V. On A23 / A31 / A33 boards dcdc3 is VDD-CPU and should be 1.2V. On A83T boards dcdc3 is used for VDD-CPUB(cluster 1) and should be 0.9V. + On A80 boards dcdc2 is used for VDD-CPUA(Cortex-A7) and should be 0.9V. config AXP_DCDC4_VOLT int "axp pmic dcdc4 voltage" - depends on AXP152_POWER || AXP221_POWER || AXP818_POWER + depends on AXP152_POWER || AXP221_POWER || AXP818_POWER || AXP809_POWER default 1250 if AXP152_POWER default 1200 if MACH_SUN6I default 0 if MACH_SUN8I + default 900 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to disable dcdc4. @@ -114,24 +132,35 @@ config AXP_DCDC4_VOLT On A31 boards dcdc4 is used for VDD-SYS and should be 1.2V. On A23 / A33 boards dcdc4 is unused and should be disabled. On A83T boards dcdc4 is used for VDD-GPU. + On A80 boards dcdc4 is used for VDD-SYS and should be 0.9V. config AXP_DCDC5_VOLT int "axp pmic dcdc5 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER default 1800 if AXP818_POWER - default 1500 if MACH_SUN6I || MACH_SUN8I + default 1500 if MACH_SUN6I || MACH_SUN8I || MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc5 at, set to 0 to disable dcdc5. - On A23 / A31 / A33 / A83T boards dcdc5 is VCC-DRAM and should be 1.5V, - 1.8V for A83T. + On A23 / A31 / A33 / A83T / A80 boards dcdc5 is VCC-DRAM and should + be 1.5V, 1.8V for A83T. + +config AXP_DC5LDO_VOLT + int "axp pmic dc5ldo voltage" + depends on AXP809_POWER + default 900 if MACH_SUN9I + ---help--- + Set the voltage (mV) to program the axp pmic dc5ldo at, set to 0 to + disable dc5ldo. + On A80 boards dc5ldo is VDD-CPUS and should be 0.9V. config AXP_ALDO1_VOLT int "axp pmic (a)ldo1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER default 0 if MACH_SUN6I default 1800 if MACH_SUN8I_A83T default 3000 if MACH_SUN8I + default 3300 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic aldo1 at, set to 0 to disable aldo1. @@ -139,14 +168,16 @@ config AXP_ALDO1_VOLT On A23 / A33 boards aldo1 is used for VCC-IO and should be 3.0V. On A83T / H8 boards aldo1 is used for MIPI CSI, DSI, HDMI, EFUSE, and should be 1.8V. + On A80 boards aldo1 is used for VCC-USBH and should be 3.3V. config AXP_ALDO2_VOLT int "axp pmic (a)ldo2 voltage" - depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER + depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER || AXP809_POWER default 3000 if AXP152_POWER || AXP209_POWER default 0 if MACH_SUN6I default 1800 if MACH_SUN8I_A83T default 2500 if MACH_SUN8I + default 0 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic aldo2 at, set to 0 to disable aldo2. @@ -159,9 +190,10 @@ config AXP_ALDO2_VOLT config AXP_ALDO3_VOLT int "axp pmic (a)ldo3 voltage" - depends on AXP209_POWER || AXP221_POWER || AXP818_POWER + depends on AXP209_POWER || AXP221_POWER || AXP818_POWER || AXP809_POWER default 0 if AXP209_POWER default 3000 if MACH_SUN6I || MACH_SUN8I + default 0 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic aldo3 at, set to 0 to disable aldo3. @@ -181,7 +213,7 @@ config AXP_ALDO4_VOLT config AXP_DLDO1_VOLT int "axp pmic dldo1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic dldo1 at, set to 0 to @@ -191,7 +223,7 @@ config AXP_DLDO1_VOLT config AXP_DLDO2_VOLT int "axp pmic dldo2 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic dldo2 at, set to 0 to @@ -215,7 +247,7 @@ config AXP_DLDO4_VOLT config AXP_ELDO1_VOLT int "axp pmic eldo1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo1 at, set to 0 to @@ -223,7 +255,7 @@ config AXP_ELDO1_VOLT config AXP_ELDO2_VOLT int "axp pmic eldo2 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo2 at, set to 0 to @@ -231,13 +263,16 @@ config AXP_ELDO2_VOLT config AXP_ELDO3_VOLT int "axp pmic eldo3 voltage" - depends on AXP221_POWER || AXP818_POWER - default 0 + depends on AXP221_POWER || AXP818_POWER || AXP809_POWER + default 0 if !MACH_SUN9I + default 1800 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic eldo3 at, set to 0 to disable eldo3. On some A31(s) tablets it might be used to supply 1.2V for the SSD2828 chip (converter of parallel LCD interface into MIPI DSI). + On the A80-Q7 (and other A80 boards) it supplies the CPUS IO pins + and should be 1.8V. config SY8106A_VOUT1_VOLT int "SY8106A pmic VOUT1 voltage" diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 690faa0f5e..b43523e628 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AS3722_POWER) += as3722.o obj-$(CONFIG_AXP152_POWER) += axp152.o obj-$(CONFIG_AXP209_POWER) += axp209.o obj-$(CONFIG_AXP221_POWER) += axp221.o +obj-$(CONFIG_AXP809_POWER) += axp809.o obj-$(CONFIG_AXP818_POWER) += axp818.o obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o diff --git a/drivers/power/axp809.c b/drivers/power/axp809.c new file mode 100644 index 0000000000..48249de411 --- /dev/null +++ b/drivers/power/axp809.c @@ -0,0 +1,278 @@ +/* + * AXP809 driver + * + * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH + * Philipp Tomsich <philipp.tomsich@theobroma-systems.com> + * + * based on AXP221/AXP223 driver (axp221.c): + * + * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com> + * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <errno.h> +#include <asm/arch/pmic_bus.h> +#include <axp_pmic.h> + +static u8 axp809_mvolt_to_cfg(int mvolt, int min, int max, int div) +{ + if (mvolt < min) + mvolt = min; + else if (mvolt > max) + mvolt = max; + + return (mvolt - min) / div; +} + +int axp_set_dc5ldo(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 1400, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DC5LDO_EN); + + ret = pmic_bus_write(AXP809_DC5LDO_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DC5LDO_EN); +} + +int axp_set_dcdc1(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 1600, 3400, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC1_EN); + + ret = pmic_bus_write(AXP809_DCDC1_CTRL, cfg); + if (ret) + return ret; + + ret = pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_DC1SW_EN); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC1_EN); +} + +int axp_set_dcdc2(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC2_EN); + + ret = pmic_bus_write(AXP809_DCDC2_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC2_EN); +} + +int axp_set_dcdc3(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1860, 20); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC3_EN); + + ret = pmic_bus_write(AXP809_DCDC3_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC3_EN); +} + +int axp_set_dcdc4(unsigned int mvolt) +{ + int ret; + u8 cfg; + + /* DCDC4 has two separate ramps: + 20mV steps for 600mV ... 1540mV + 100mV steps for 1800mV ... 2600mV + */ + cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20); + cfg += axp809_mvolt_to_cfg(mvolt, 1800, 2600, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC4_EN); + + ret = pmic_bus_write(AXP809_DCDC4_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC4_EN); +} + +int axp_set_dcdc5(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 1000, 2550, 50); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC5_EN); + + ret = pmic_bus_write(AXP809_DCDC5_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC5_EN); +} + +int axp_set_aldo1(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_ALDO1_EN); + + ret = pmic_bus_write(AXP809_ALDO1_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_ALDO1_EN); +} + +int axp_set_aldo2(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_ALDO2_EN); + + ret = pmic_bus_write(AXP809_ALDO2_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_ALDO2_EN); +} + +int axp_set_aldo3(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_ALDO3_EN); + + ret = pmic_bus_write(AXP809_ALDO3_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_ALDO3_EN); +} + +int axp_set_dldo(int dldo_num, unsigned int mvolt) +{ + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + int ret; + + if (dldo_num < 1 || dldo_num > 2) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); + + ret = pmic_bus_write(AXP809_DLDO1_CTRL + (dldo_num - 1), cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); +} + +int axp_set_eldo(int eldo_num, unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + u8 addr, bits; + + switch (eldo_num) { + case 3: + addr = AXP809_ELDO3_CTRL; + bits = AXP809_OUTPUT_CTRL2_ELDO3_EN; + break; + case 2: + addr = AXP809_ELDO2_CTRL; + bits = AXP809_OUTPUT_CTRL2_ELDO2_EN; + break; + case 1: + addr = AXP809_ELDO1_CTRL; + bits = AXP809_OUTPUT_CTRL2_ELDO1_EN; + break; + default: + return -EINVAL; + } + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2, bits); + + ret = pmic_bus_write(addr, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL2, bits); +} + +int axp_init(void) +{ + u8 axp_chip_id; + int ret; + + ret = pmic_bus_init(); + if (ret) + return ret; + + ret = pmic_bus_read(AXP809_VERSION, &axp_chip_id); + if (ret) + return ret; + + axp_chip_id &= AXP809_VERSION_CHIPID_MASK; + if (!(axp_chip_id == AXP809_VERSION_CHIPID)) + return -ENODEV; + + return 0; +} + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + pmic_bus_write(AXP809_SHUTDOWN, AXP809_SHUTDOWN_POWEROFF); + + /* infinite loop during shutdown */ + while (1) {} + + /* not reached */ + return 0; +} diff --git a/include/axp809.h b/include/axp809.h new file mode 100644 index 0000000000..81b3607d06 --- /dev/null +++ b/include/axp809.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH + * Philipp Tomsich <philipp.tomsich@theobroma-systems.com> + * + * X-Powers AXP809 Power Management IC driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Page 0 addresses */ +#define AXP809_INPUT_POWER_STATUS 0x00 +#define AXP809_POWERMODE 0x01 +#define AXP809_VERSION 0x03 +#define AXP809_VERSION_CHIPID_MASK 0xcf +#define AXP809_VERSION_CHIPID 0x42 +#define AXP809_DATACACHE 0x04 +#define AXP809_OUTPUT_CTRL1 0x10 +#define AXP809_OUTPUT_CTRL1_DC5LDO_EN (1 << 0) +#define AXP809_OUTPUT_CTRL1_DCDC1_EN (1 << 1) +#define AXP809_OUTPUT_CTRL1_DCDC2_EN (1 << 2) +#define AXP809_OUTPUT_CTRL1_DCDC3_EN (1 << 3) +#define AXP809_OUTPUT_CTRL1_DCDC4_EN (1 << 4) +#define AXP809_OUTPUT_CTRL1_DCDC5_EN (1 << 5) +#define AXP809_OUTPUT_CTRL1_ALDO1_EN (1 << 6) +#define AXP809_OUTPUT_CTRL1_ALDO2_EN (1 << 7) +#define AXP809_OUTPUT_CTRL2 0x12 +#define AXP809_OUTPUT_CTRL2_ELDO1_EN (1 << 0) +#define AXP809_OUTPUT_CTRL2_ELDO2_EN (1 << 1) +#define AXP809_OUTPUT_CTRL2_ELDO3_EN (1 << 2) +#define AXP809_OUTPUT_CTRL2_DLDO1_EN (1 << 3) +#define AXP809_OUTPUT_CTRL2_DLDO2_EN (1 << 4) +#define AXP809_OUTPUT_CTRL2_ALDO3_EN (1 << 5) +#define AXP809_OUTPUT_CTRL2_SWOUT_EN (1 << 6) +#define AXP809_OUTPUT_CTRL2_DC1SW_EN (1 << 7) +#define AXP809_DLDO1_CTRL 0x15 +#define AXP809_DLDO2_CTRL 0x16 +#define AXP809_ELDO1_CTRL 0x19 +#define AXP809_ELDO2_CTRL 0x1a +#define AXP809_ELDO3_CTRL 0x1b +#define AXP809_DC5LDO_CTRL 0x1c +#define AXP809_DCDC1_CTRL 0x21 +#define AXP809_DCDC2_CTRL 0x22 +#define AXP809_DCDC3_CTRL 0x23 +#define AXP809_DCDC4_CTRL 0x24 +#define AXP809_DCDC5_CTRL 0x25 +#define AXP809_DCDC23_DVS_CTRL 0x27 +#define AXP809_ALDO1_CTRL 0x28 +#define AXP809_ALDO2_CTRL 0x29 +#define AXP809_ALDO3_CTRL 0x2a +#define AXP809_VBUS_IPSOUT 0x30 +#define AXP809_VBUS_IPSOUT_DRIVEBUS (1 << 2) +#define AXP809_WAKEUP 0x31 +#define AXP809_SHUTDOWN 0x32 +#define AXP809_SHUTDOWN_POWEROFF (1 << 7) +#define AXP809_DCDC_FREQUENCY 0x3b +#define AXP809_DCDC_MODE 0x80 +#define AXP809_ADC_ENABLE 0x82 +#define AXP809_ADC_CTRL 0x84 +#define AXP809_ADC_RAT 0x85 +#define AXP809_TIMER_CTRL 0x8a +#define AXP809_PWREN_CTRL1 0x8c +#define AXP809_PWREN_CTRL2 0x8d +#define AXP809_MISC_CTRL 0x8f +#define AXP809_MISC_CTRL_N_VBUSEN_FUNC (1 << 4) + +/* For axp_gpio.c */ +#define AXP_POWER_STATUS 0x00 +#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) +#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 diff --git a/include/axp_pmic.h b/include/axp_pmic.h index 0f14683509..22f31d1c55 100644 --- a/include/axp_pmic.h +++ b/include/axp_pmic.h @@ -16,6 +16,9 @@ #ifdef CONFIG_AXP221_POWER #include <axp221.h> #endif +#ifdef CONFIG_AXP809_POWER +#include <axp809.h> +#endif #ifdef CONFIG_AXP818_POWER #include <axp818.h> #endif @@ -25,6 +28,7 @@ int axp_set_dcdc2(unsigned int mvolt); int axp_set_dcdc3(unsigned int mvolt); int axp_set_dcdc4(unsigned int mvolt); int axp_set_dcdc5(unsigned int mvolt); +int axp_set_dc5ldo(unsigned int mvolt); int axp_set_aldo1(unsigned int mvolt); int axp_set_aldo2(unsigned int mvolt); int axp_set_aldo3(unsigned int mvolt); diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index d750791c76..7fa9833b4d 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -257,7 +257,7 @@ extern int soft_i2c_gpio_scl; /* PMU */ #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER || \ - defined CONFIG_SY8106A_POWER + defined CONFIG_AXP809_POWER || defined CONFIG_SY8106A_POWER #define CONFIG_SPL_POWER_SUPPORT #endif |