blob: 7c51a9b3dfb77a6afc3a0dc5abd11b9a18b3afba [file] [log] [blame]
Andre Przywara660dc912024-05-13 22:55:07 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * AXP PMIC SPL driver
4 * (C) Copyright 2024 Arm Ltd.
5 */
6
7#include <errno.h>
8#include <linux/types.h>
9#include <asm/arch/pmic_bus.h>
10#include <axp_pmic.h>
11
12struct axp_reg_desc_spl {
13 u8 enable_reg;
14 u8 enable_mask;
15 u8 volt_reg;
16 u8 volt_mask;
17 u16 min_mV;
18 u16 max_mV;
19 u8 step_mV;
20 u8 split;
21};
22
23#define NA 0xff
24
25#if defined(CONFIG_AXP717_POWER) /* AXP717 */
26
27static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
28 { 0x80, BIT(0), 0x83, 0x7f, 500, 1540, 10, 70 },
29 { 0x80, BIT(1), 0x84, 0x7f, 500, 1540, 10, 70 },
30 { 0x80, BIT(2), 0x85, 0x7f, 500, 1840, 10, 70 },
31};
32
33#define AXP_CHIP_VERSION 0x0
34#define AXP_CHIP_VERSION_MASK 0x0
35#define AXP_CHIP_ID 0x0
36#define AXP_SHUTDOWN_REG 0x27
37#define AXP_SHUTDOWN_MASK BIT(0)
38
Andre Przywara3febb0a2024-10-20 17:36:19 +010039#elif defined(CONFIG_AXP803_POWER) /* AXP803 */
40
41static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
42 { 0x10, BIT(0), 0x20, 0x1f, 1600, 3400, 100, NA },
43 { 0x10, BIT(1), 0x21, 0x7f, 500, 1300, 10, 70 },
44 { 0x10, BIT(2), 0x22, 0x7f, 500, 1300, 10, 70 },
45 { 0x10, BIT(3), 0x23, 0x7f, 500, 1300, 10, 70 },
46 { 0x10, BIT(4), 0x24, 0x7f, 800, 1840, 10, 32 },
47 { 0x10, BIT(5), 0x25, 0x7f, 600, 1520, 10, 50 },
48};
49
50#define AXP_CHIP_VERSION 0x3
51#define AXP_CHIP_VERSION_MASK 0xcf
52#define AXP_CHIP_ID 0x41
53#define AXP_SHUTDOWN_REG 0x32
54#define AXP_SHUTDOWN_MASK BIT(7)
55
Andre Przywara4842cd02024-05-14 00:46:59 +010056#elif defined(CONFIG_AXP313_POWER) /* AXP313 */
57
58static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
59 { 0x10, BIT(0), 0x13, 0x7f, 500, 1540, 10, 70 },
60 { 0x10, BIT(1), 0x14, 0x7f, 500, 1540, 10, 70 },
61 { 0x10, BIT(2), 0x15, 0x7f, 500, 1840, 10, 70 },
62};
63
64#define AXP_CHIP_VERSION 0x3
65#define AXP_CHIP_VERSION_MASK 0xc8
66#define AXP_CHIP_ID 0x48
67#define AXP_SHUTDOWN_REG 0x1a
68#define AXP_SHUTDOWN_MASK BIT(7)
69
Andre Przywaraea9efe82024-05-14 00:47:09 +010070#elif defined(CONFIG_AXP305_POWER) /* AXP305 */
71
72static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
73 { 0x10, BIT(0), 0x12, 0x7f, 600, 1520, 10, 50 },
74 { 0x10, BIT(1), 0x13, 0x1f, 1000, 2550, 50, NA },
75 { 0x10, BIT(2), 0x14, 0x7f, 600, 1520, 10, 50 },
76 { 0x10, BIT(3), 0x15, 0x3f, 600, 1500, 20, NA },
77 { 0x10, BIT(4), 0x16, 0x1f, 1100, 3400, 100, NA },
78};
79
80#define AXP_CHIP_VERSION 0x3
81#define AXP_CHIP_VERSION_MASK 0xcf
82#define AXP_CHIP_ID 0x40
83#define AXP_SHUTDOWN_REG 0x32
84#define AXP_SHUTDOWN_MASK BIT(7)
85
Andre Przywara660dc912024-05-13 22:55:07 +010086#else
87
88 #error "Please define the regulator registers in axp_spl_regulators[]."
89
90#endif
91
92static u8 axp_mvolt_to_cfg(int mvolt, const struct axp_reg_desc_spl *reg)
93{
94 if (mvolt < reg->min_mV)
95 mvolt = reg->min_mV;
96 else if (mvolt > reg->max_mV)
97 mvolt = reg->max_mV;
98
99 mvolt -= reg->min_mV;
100
101 /* voltage in the first range ? */
102 if (mvolt <= reg->split * reg->step_mV)
103 return mvolt / reg->step_mV;
104
105 mvolt -= reg->split * reg->step_mV;
106
107 return reg->split + mvolt / (reg->step_mV * 2);
108}
109
110static int axp_set_dcdc(int dcdc_num, unsigned int mvolt)
111{
112 const struct axp_reg_desc_spl *reg;
113 int ret;
114
115 if (dcdc_num < 1 || dcdc_num > ARRAY_SIZE(axp_spl_dcdc_regulators))
116 return -EINVAL;
117
118 reg = &axp_spl_dcdc_regulators[dcdc_num - 1];
119
120 if (mvolt == 0)
121 return pmic_bus_clrbits(reg->enable_reg, reg->enable_mask);
122
123 ret = pmic_bus_write(reg->volt_reg, axp_mvolt_to_cfg(mvolt, reg));
124 if (ret)
125 return ret;
126
127 return pmic_bus_setbits(reg->enable_reg, reg->enable_mask);
128}
129
130int axp_set_dcdc1(unsigned int mvolt)
131{
132 return axp_set_dcdc(1, mvolt);
133}
134
135int axp_set_dcdc2(unsigned int mvolt)
136{
137 return axp_set_dcdc(2, mvolt);
138}
139
140int axp_set_dcdc3(unsigned int mvolt)
141{
142 return axp_set_dcdc(3, mvolt);
143}
144
145int axp_set_dcdc4(unsigned int mvolt)
146{
147 return axp_set_dcdc(4, mvolt);
148}
149
150int axp_set_dcdc5(unsigned int mvolt)
151{
152 return axp_set_dcdc(5, mvolt);
153}
154
155int axp_init(void)
156{
157 int ret = pmic_bus_init();
158
159 if (ret)
160 return ret;
161
162 if (AXP_CHIP_VERSION_MASK) {
163 u8 axp_chip_id;
164
165 ret = pmic_bus_read(AXP_CHIP_VERSION, &axp_chip_id);
166 if (ret)
167 return ret;
168
169 if ((axp_chip_id & AXP_CHIP_VERSION_MASK) != AXP_CHIP_ID) {
170 debug("unknown PMIC: 0x%x\n", axp_chip_id);
171 return -EINVAL;
172 }
173 }
174
175 return 0;
176}
177
178#if !CONFIG_IS_ENABLED(ARM_PSCI_FW) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
179int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
180{
181 pmic_bus_setbits(AXP_SHUTDOWN_REG, AXP_SHUTDOWN_MASK);
182
183 /* infinite loop during shutdown */
184 while (1)
185 ;
186
187 /* not reached */
188 return 0;
189}
190#endif