1 /* 2 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io> 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <errno.h> 9 10 #include <common/debug.h> 11 #include <drivers/allwinner/axp.h> 12 #include <drivers/allwinner/sunxi_rsb.h> 13 14 #include <sunxi_def.h> 15 #include <sunxi_mmap.h> 16 #include <sunxi_private.h> 17 18 #define AXP805_HW_ADDR 0x745 19 #define AXP805_RT_ADDR 0x3a 20 21 static enum pmic_type { 22 UNKNOWN, 23 AXP805, 24 } pmic; 25 26 int axp_read(uint8_t reg) 27 { 28 return rsb_read(AXP805_RT_ADDR, reg); 29 } 30 31 int axp_write(uint8_t reg, uint8_t val) 32 { 33 return rsb_write(AXP805_RT_ADDR, reg, val); 34 } 35 36 static int rsb_init(void) 37 { 38 int ret; 39 40 ret = rsb_init_controller(); 41 if (ret) 42 return ret; 43 44 /* Switch to the recommended 3 MHz bus clock. */ 45 ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000); 46 if (ret) 47 return ret; 48 49 /* Initiate an I2C transaction to switch the PMIC to RSB mode. */ 50 ret = rsb_set_device_mode(AXP20X_MODE_RSB << 16 | AXP20X_MODE_REG << 8); 51 if (ret) 52 return ret; 53 54 /* Associate the 8-bit runtime address with the 12-bit bus address. */ 55 ret = rsb_assign_runtime_address(AXP805_HW_ADDR, AXP805_RT_ADDR); 56 if (ret) 57 return ret; 58 59 return axp_check_id(); 60 } 61 62 int sunxi_pmic_setup(uint16_t socid, const void *fdt) 63 { 64 int ret; 65 66 INFO("PMIC: Probing AXP805 on RSB\n"); 67 68 ret = sunxi_init_platform_r_twi(socid, true); 69 if (ret) 70 return ret; 71 72 ret = rsb_init(); 73 if (ret) 74 return ret; 75 76 /* Switch the AXP805 to master/single-PMIC mode. */ 77 ret = axp_write(0xff, 0x0); 78 if (ret) 79 return ret; 80 81 pmic = AXP805; 82 axp_setup_regulators(fdt); 83 84 /* Switch the PMIC back to I2C mode. */ 85 ret = axp_write(AXP20X_MODE_REG, AXP20X_MODE_I2C); 86 if (ret) 87 return ret; 88 89 return 0; 90 } 91 92 void sunxi_power_down(void) 93 { 94 switch (pmic) { 95 case AXP805: 96 /* (Re-)init RSB in case the rich OS has disabled it. */ 97 sunxi_init_platform_r_twi(SUNXI_SOC_H6, true); 98 rsb_init(); 99 axp_power_off(); 100 break; 101 default: 102 break; 103 } 104 } 105