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 #include <string.h> 10 11 #include <arch_helpers.h> 12 #include <common/debug.h> 13 #include <drivers/allwinner/axp.h> 14 #include <drivers/delay_timer.h> 15 #include <drivers/mentor/mi2cv.h> 16 #include <lib/mmio.h> 17 18 #include <sunxi_def.h> 19 #include <sunxi_mmap.h> 20 #include <sunxi_private.h> 21 22 #define AXP805_ADDR 0x36 23 24 static enum pmic_type { 25 UNKNOWN, 26 AXP805, 27 } pmic; 28 29 int axp_read(uint8_t reg) 30 { 31 uint8_t val; 32 int ret; 33 34 ret = i2c_write(AXP805_ADDR, 0, 0, ®, 1); 35 if (ret == 0) 36 ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1); 37 if (ret) { 38 ERROR("PMIC: Cannot read AXP805 register %02x\n", reg); 39 return ret; 40 } 41 42 return val; 43 } 44 45 int axp_write(uint8_t reg, uint8_t val) 46 { 47 int ret; 48 49 ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1); 50 if (ret) 51 ERROR("PMIC: Cannot write AXP805 register %02x\n", reg); 52 53 return ret; 54 } 55 56 static int axp805_probe(void) 57 { 58 int ret; 59 60 /* Switch the AXP805 to master/single-PMIC mode. */ 61 ret = axp_write(0xff, 0x0); 62 if (ret) 63 return ret; 64 65 ret = axp_check_id(); 66 if (ret) 67 return ret; 68 69 return 0; 70 } 71 72 int sunxi_pmic_setup(uint16_t socid, const void *fdt) 73 { 74 int ret; 75 76 INFO("PMIC: Probing AXP805 on I2C\n"); 77 78 ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false); 79 if (ret) 80 return ret; 81 82 /* initialise mi2cv driver */ 83 i2c_init((void *)SUNXI_R_I2C_BASE); 84 85 ret = axp805_probe(); 86 if (ret) 87 return ret; 88 89 pmic = AXP805; 90 axp_setup_regulators(fdt); 91 92 return 0; 93 } 94 95 void sunxi_power_down(void) 96 { 97 switch (pmic) { 98 case AXP805: 99 /* Re-initialise after rich OS might have used it. */ 100 sunxi_init_platform_r_twi(SUNXI_SOC_H6, false); 101 /* initialise mi2cv driver */ 102 i2c_init((void *)SUNXI_R_I2C_BASE); 103 axp_power_off(); 104 break; 105 default: 106 break; 107 } 108 } 109