• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
axp_read(uint8_t reg)29 int axp_read(uint8_t reg)
30 {
31 	uint8_t val;
32 	int ret;
33 
34 	ret = i2c_write(AXP805_ADDR, 0, 0, &reg, 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 
axp_write(uint8_t reg,uint8_t val)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 
axp805_probe(void)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 
sunxi_pmic_setup(uint16_t socid,const void * fdt)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 
sunxi_power_down(void)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