On 06/01/2021 23:33, Jaehoon Chung wrote: > On 1/6/21 7:11 PM, André Przywara wrote: >> On 05/01/2021 22:36, Jaehoon Chung wrote: >> >> Hi, >> >> thanks for having a look! >> >>> Hi Jernej >>> >>> On 1/3/21 6:26 PM, Jernej Skrabec wrote: >>>> This PMIC can be found on H616 boards and it's very similar to AXP805 >>>> and AXP806. >>> >>> Is there any plan to cleanup codes? >> >> There is no support for either of these, we use the PMICs only in >> Trusted Firmware or Linux. So nothing to consolidate, yet. This might >> change in the future, and then of course we will use a common code base. >> >>> >>>> >>>> Signed-off-by: Jernej Skrabec <jernej.skra...@siol.net> >>>> --- >>>> arch/arm/mach-sunxi/pmic_bus.c | 6 +++ >>>> board/sunxi/board.c | 10 +++-- >>>> drivers/power/Kconfig | 13 +++++- >>>> drivers/power/Makefile | 1 + >>>> drivers/power/axp305.c | 80 ++++++++++++++++++++++++++++++++++ >>>> include/axp305.h | 17 ++++++++ >>>> include/axp_pmic.h | 3 ++ >>>> 7 files changed, 126 insertions(+), 4 deletions(-) >>>> create mode 100644 drivers/power/axp305.c >>>> create mode 100644 include/axp305.h >>>> >>>> diff --git a/arch/arm/mach-sunxi/pmic_bus.c >>>> b/arch/arm/mach-sunxi/pmic_bus.c >>>> index dea42de833f1..0394ce856448 100644 >>>> --- a/arch/arm/mach-sunxi/pmic_bus.c >>>> +++ b/arch/arm/mach-sunxi/pmic_bus.c >>>> @@ -18,6 +18,8 @@ >>>> >>>> #define AXP209_I2C_ADDR 0x34 >>>> >>>> +#define AXP305_I2C_ADDR 0x36 >>>> + >>>> #define AXP221_CHIP_ADDR 0x68 >>>> #define AXP221_CTRL_ADDR 0x3e >>>> #define AXP221_INIT_DATA 0x3e >>>> @@ -64,6 +66,8 @@ 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_AXP305_POWER >>>> + return i2c_read(AXP305_I2C_ADDR, reg, 1, data, 1); >>>> #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || >>>> defined CONFIG_AXP818_POWER >>>> # ifdef CONFIG_MACH_SUN6I >>>> return p2wi_read(reg, data); >>>> @@ -81,6 +85,8 @@ 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_AXP305_POWER >>>> + return i2c_write(AXP305_I2C_ADDR, reg, 1, &data, 1); >>>> #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || >>>> defined CONFIG_AXP818_POWER >>>> # ifdef CONFIG_MACH_SUN6I >>>> return p2wi_write(reg, data); >>>> diff --git a/board/sunxi/board.c b/board/sunxi/board.c >>>> index 708a27ed78e9..54ff9bc92396 100644 >>>> --- a/board/sunxi/board.c >>>> +++ b/board/sunxi/board.c >>>> @@ -634,16 +634,18 @@ void sunxi_board_init(void) >>>> #endif >>>> >>>> #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ >>>> - defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ >>>> - defined CONFIG_AXP818_POWER >>>> + defined CONFIG_AXP221_POWER || defined CONFIG_AXP305_POWER || \ >>>> + defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER >>>> power_failed = axp_init(); >>>> >>>> #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ >>>> defined CONFIG_AXP818_POWER >>>> power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); >>>> #endif >>>> +#if !defined(CONFIG_AXP305_POWER) >>>> power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); >>>> power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT); >>>> +#endif >>>> #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER) >>>> power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); >>>> #endif >>>> @@ -656,8 +658,10 @@ void sunxi_board_init(void) >>>> defined CONFIG_AXP818_POWER >>>> power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); >>>> #endif >>>> +#if !defined(CONFIG_AXP305_POWER) >>>> power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); >>>> -#if !defined(CONFIG_AXP152_POWER) >>>> +#endif >>>> +#if !defined(CONFIG_AXP152_POWER) && !defined(CONFIG_AXP305_POWER) >>>> power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT); >>>> #endif >>>> #ifdef CONFIG_AXP209_POWER >>>> diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig >>>> index 02050f6f3569..d17cf2d9112a 100644 >>>> --- a/drivers/power/Kconfig >>>> +++ b/drivers/power/Kconfig >>>> @@ -48,6 +48,15 @@ config AXP221_POWER >>>> Select this to enable support for the axp221/axp223 pmic found on most >>>> A23 and A31 boards. >>>> >>>> +config AXP305_POWER >>>> + bool "axp305 pmic support" >>>> + depends on MACH_SUN50I_H616 >>>> + select AXP_PMIC_BUS >>>> + select CMD_POWEROFF >>>> + ---help--- >>>> + Select this to enable support for the axp305 pmic found on most >>>> + H616 boards. >>>> + >>>> config AXP809_POWER >>>> bool "axp809 pmic support" >>>> depends on MACH_SUN9I >>>> @@ -127,11 +136,12 @@ config AXP_DCDC3_VOLT >>>> >>>> config AXP_DCDC4_VOLT >>>> int "axp pmic dcdc4 voltage" >>>> - depends on AXP152_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER >>>> + depends on AXP152_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER >>>> || AXP305_POWER >>>> default 1250 if AXP152_POWER >>>> default 1200 if MACH_SUN6I >>>> default 0 if MACH_SUN8I >>>> default 900 if MACH_SUN9I >>>> + default 1500 if AXP305_POWER >>>> ---help--- >>>> Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to >>>> disable dcdc4. >>>> @@ -140,6 +150,7 @@ config AXP_DCDC4_VOLT >>>> On A23 / A33 boards dcdc4 is unused and should be disabled. >>>> On A80 boards dcdc4 powers VDD-SYS, HDMI, USB OTG and should be 0.9V. >>>> On A83T boards dcdc4 is used for VDD-GPU. >>>> + On H616 boards dcdcd is used for VCC-DRAM. >>>> >>>> config AXP_DCDC5_VOLT >>>> int "axp pmic dcdc5 voltage" >>>> diff --git a/drivers/power/Makefile b/drivers/power/Makefile >>>> index 2dcc7bb99d02..0bef06920a7d 100644 >>>> --- a/drivers/power/Makefile >>>> +++ b/drivers/power/Makefile >>>> @@ -6,6 +6,7 @@ >>>> obj-$(CONFIG_AXP152_POWER) += axp152.o >>>> obj-$(CONFIG_AXP209_POWER) += axp209.o >>>> obj-$(CONFIG_AXP221_POWER) += axp221.o >>>> +obj-$(CONFIG_AXP305_POWER) += axp305.o >>>> obj-$(CONFIG_AXP809_POWER) += axp809.o >>>> obj-$(CONFIG_AXP818_POWER) += axp818.o >>>> obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o >>>> diff --git a/drivers/power/axp305.c b/drivers/power/axp305.c >>>> new file mode 100644 >>>> index 000000000000..f620798bb1d7 >>>> --- /dev/null >>>> +++ b/drivers/power/axp305.c >>>> @@ -0,0 +1,80 @@ >>>> +// SPDX-License-Identifier: GPL-2.0+ >>>> +/* >>>> + * AXP305 driver >>>> + * >>>> + * (C) Copyright 2020 Jernej Skrabec <jernej.skra...@siol.net> >>>> + * >>>> + * Based on axp221.c >>>> + * (C) Copyright 2014 Hans de Goede <hdego...@redhat.com> >>>> + * (C) Copyright 2013 Oliver Schinagl <oli...@schinagl.nl> >>>> + */ >>>> + >>>> +#include <common.h> >>>> +#include <command.h> >>>> +#include <errno.h> >>>> +#include <asm/arch/pmic_bus.h> >>>> +#include <axp_pmic.h> >>>> + >>>> +static u8 axp305_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_dcdc4(unsigned int mvolt) >>>> +{ >>>> + int ret; >>> >>> Initialized ret value to 0. >> >> Why? We set it unconditionally below, so initialising it here would be >> pointless and might actually be warned upon by astute compilers. > > Sorry. It's my misunderstanding. you're right. > >> >>> >>>> + u8 cfg; >>>> + >>>> + if (mvolt >= 1600) >>>> + cfg = 46 + axp305_mvolt_to_cfg(mvolt, 1600, 3300, 100); >>> >>> Could you use macro instead of 46 (magic code)? >>> >>>> + else >>>> + cfg = axp305_mvolt_to_cfg(mvolt, 600, 1500, 20); >>>> + >>>> + if (mvolt == 0) >>>> + return pmic_bus_clrbits(AXP305_OUTPUT_CTRL1, >>>> + AXP305_OUTPUT_CTRL1_DCDCD_EN); >>>> + >>>> + ret = pmic_bus_write(AXP305_DCDCD_VOLTAGE, cfg); >>>> + if (ret) >>>> + return ret; >>>> + >>>> + return pmic_bus_setbits(AXP305_OUTPUT_CTRL1, >>>> + AXP305_OUTPUT_CTRL1_DCDCD_EN); >>>> +} >>>> + >>>> +int axp_init(void) >>>> +{ >>>> + u8 axp_chip_id; >>>> + int ret; >>>> + >>>> + ret = pmic_bus_init(); >>>> + if (ret) >>>> + return ret; >>>> + >>>> + ret = pmic_bus_read(AXP305_CHIP_VERSION, &axp_chip_id); >>>> + if (ret) >>>> + return ret; >>>> + >>>> + if ((axp_chip_id & AXP305_CHIP_VERSION_MASK) != 0x40) >>> >>> Ditto, use macro instead of 0x40. >> >> Not sure a macro is too useful here. I think the statement is pretty >> clear in that this must be the chip version, which is given as this >> value in the manual. > > 0x40 is chip version? When i saw 0x40, i thought it mean some bit values. > Thanks for kindly explanation.
Well, it's both, welcome to Allwinner :-D This is what the manual says: bits 7-6 & 3-0: IC Type NO. 010000: IC is AXP305 Others: Reserved So it's a mess, and that number is not really unique (the AXP805 and AXP806 also use the same bits), but it's just a safety measure to avoid talking to the wrong device. Cheers, Andre >> >> Cheers, >> Andre >> >>>> + return -ENODEV; >>>> + >>>> + return ret; >>>> +} >>>> + >>>> +#ifndef CONFIG_PSCI_RESET >>>> +int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const >>>> argv[]) >>>> +{ >>>> + pmic_bus_write(AXP305_SHUTDOWN, AXP305_POWEROFF); >>>> + >>>> + /* infinite loop during shutdown */ >>>> + while (1) {} >>>> + >>>> + /* not reached */ >>>> + return 0; >>>> +} >>>> +#endif >>>> diff --git a/include/axp305.h b/include/axp305.h >>>> new file mode 100644 >>>> index 000000000000..225c5040a322 >>>> --- /dev/null >>>> +++ b/include/axp305.h >>>> @@ -0,0 +1,17 @@ >>>> +/* SPDX-License-Identifier: GPL-2.0+ */ >>>> +/* >>>> + * (C) Copyright 2020 Jernej Skrabec <jernej.skra...@siol.net> >>>> + */ >>>> + >>>> +enum axp305_reg { >>>> + AXP305_CHIP_VERSION = 0x3, >>>> + AXP305_OUTPUT_CTRL1 = 0x10, >>>> + AXP305_DCDCD_VOLTAGE = 0x15, >>>> + AXP305_SHUTDOWN = 0x32, >>>> +}; >>>> + >>>> +#define AXP305_CHIP_VERSION_MASK 0xcf >>>> + >>>> +#define AXP305_OUTPUT_CTRL1_DCDCD_EN (1 << 3) >>>> + >>>> +#define AXP305_POWEROFF (1 << 7) >>>> diff --git a/include/axp_pmic.h b/include/axp_pmic.h >>>> index 10091d0bb278..405044c3a32f 100644 >>>> --- a/include/axp_pmic.h >>>> +++ b/include/axp_pmic.h >>>> @@ -15,6 +15,9 @@ >>>> #ifdef CONFIG_AXP221_POWER >>>> #include <axp221.h> >>>> #endif >>>> +#ifdef CONFIG_AXP305_POWER >>>> +#include <axp305.h> >>>> +#endif >>>> #ifdef CONFIG_AXP809_POWER >>>> #include <axp809.h> >>>> #endif >>>> >>> >> >> >