hw/xen/hvm: Inline TARGET_PAGE_ALIGN() macro
[qemu/ar7.git] / hw / misc / axp2xx.c
blobaf646878cd2e8ad588739e1ac2185842335ed3bc
1 /*
2 * AXP-2XX PMU Emulation, supported lists:
3 * AXP209
4 * AXP221
6 * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
7 * Copyright (C) 2023 qianfan Zhao <qianfanguijin@163.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
27 * SPDX-License-Identifier: MIT
30 #include "qemu/osdep.h"
31 #include "qemu/log.h"
32 #include "qom/object.h"
33 #include "trace.h"
34 #include "hw/i2c/i2c.h"
35 #include "migration/vmstate.h"
37 #define TYPE_AXP2XX "axp2xx_pmu"
38 #define TYPE_AXP209_PMU "axp209_pmu"
39 #define TYPE_AXP221_PMU "axp221_pmu"
41 OBJECT_DECLARE_TYPE(AXP2xxI2CState, AXP2xxClass, AXP2XX)
43 #define NR_REGS (0xff)
45 /* A simple I2C slave which returns values of ID or CNT register. */
46 typedef struct AXP2xxI2CState {
47 /*< private >*/
48 I2CSlave i2c;
49 /*< public >*/
50 uint8_t regs[NR_REGS]; /* peripheral registers */
51 uint8_t ptr; /* current register index */
52 uint8_t count; /* counter used for tx/rx */
53 } AXP2xxI2CState;
55 typedef struct AXP2xxClass {
56 /*< private >*/
57 I2CSlaveClass parent_class;
58 /*< public >*/
59 void (*reset_enter)(AXP2xxI2CState *s, ResetType type);
60 } AXP2xxClass;
62 #define AXP209_CHIP_VERSION_ID (0x01)
63 #define AXP209_DC_DC2_OUT_V_CTRL_RESET (0x16)
65 /* Reset all counters and load ID register */
66 static void axp209_reset_enter(AXP2xxI2CState *s, ResetType type)
68 memset(s->regs, 0, NR_REGS);
69 s->ptr = 0;
70 s->count = 0;
72 s->regs[0x03] = AXP209_CHIP_VERSION_ID;
73 s->regs[0x23] = AXP209_DC_DC2_OUT_V_CTRL_RESET;
75 s->regs[0x30] = 0x60;
76 s->regs[0x32] = 0x46;
77 s->regs[0x34] = 0x41;
78 s->regs[0x35] = 0x22;
79 s->regs[0x36] = 0x5d;
80 s->regs[0x37] = 0x08;
81 s->regs[0x38] = 0xa5;
82 s->regs[0x39] = 0x1f;
83 s->regs[0x3a] = 0x68;
84 s->regs[0x3b] = 0x5f;
85 s->regs[0x3c] = 0xfc;
86 s->regs[0x3d] = 0x16;
87 s->regs[0x40] = 0xd8;
88 s->regs[0x42] = 0xff;
89 s->regs[0x43] = 0x3b;
90 s->regs[0x80] = 0xe0;
91 s->regs[0x82] = 0x83;
92 s->regs[0x83] = 0x80;
93 s->regs[0x84] = 0x32;
94 s->regs[0x86] = 0xff;
95 s->regs[0x90] = 0x07;
96 s->regs[0x91] = 0xa0;
97 s->regs[0x92] = 0x07;
98 s->regs[0x93] = 0x07;
101 #define AXP221_PWR_STATUS_ACIN_PRESENT BIT(7)
102 #define AXP221_PWR_STATUS_ACIN_AVAIL BIT(6)
103 #define AXP221_PWR_STATUS_VBUS_PRESENT BIT(5)
104 #define AXP221_PWR_STATUS_VBUS_USED BIT(4)
105 #define AXP221_PWR_STATUS_BAT_CHARGING BIT(2)
106 #define AXP221_PWR_STATUS_ACIN_VBUS_POWERED BIT(1)
108 /* Reset all counters and load ID register */
109 static void axp221_reset_enter(AXP2xxI2CState *s, ResetType type)
111 memset(s->regs, 0, NR_REGS);
112 s->ptr = 0;
113 s->count = 0;
115 /* input power status register */
116 s->regs[0x00] = AXP221_PWR_STATUS_ACIN_PRESENT
117 | AXP221_PWR_STATUS_ACIN_AVAIL
118 | AXP221_PWR_STATUS_ACIN_VBUS_POWERED;
120 s->regs[0x01] = 0x00; /* no battery is connected */
123 * CHIPID register, no documented on datasheet, but it is checked in
124 * u-boot spl. I had read it from AXP221s and got 0x06 value.
125 * So leave 06h here.
127 s->regs[0x03] = 0x06;
129 s->regs[0x10] = 0xbf;
130 s->regs[0x13] = 0x01;
131 s->regs[0x30] = 0x60;
132 s->regs[0x31] = 0x03;
133 s->regs[0x32] = 0x43;
134 s->regs[0x33] = 0xc6;
135 s->regs[0x34] = 0x45;
136 s->regs[0x35] = 0x0e;
137 s->regs[0x36] = 0x5d;
138 s->regs[0x37] = 0x08;
139 s->regs[0x38] = 0xa5;
140 s->regs[0x39] = 0x1f;
141 s->regs[0x3c] = 0xfc;
142 s->regs[0x3d] = 0x16;
143 s->regs[0x80] = 0x80;
144 s->regs[0x82] = 0xe0;
145 s->regs[0x84] = 0x32;
146 s->regs[0x8f] = 0x01;
148 s->regs[0x90] = 0x07;
149 s->regs[0x91] = 0x1f;
150 s->regs[0x92] = 0x07;
151 s->regs[0x93] = 0x1f;
153 s->regs[0x40] = 0xd8;
154 s->regs[0x41] = 0xff;
155 s->regs[0x42] = 0x03;
156 s->regs[0x43] = 0x03;
158 s->regs[0xb8] = 0xc0;
159 s->regs[0xb9] = 0x64;
160 s->regs[0xe6] = 0xa0;
163 static void axp2xx_reset_enter(Object *obj, ResetType type)
165 AXP2xxI2CState *s = AXP2XX(obj);
166 AXP2xxClass *sc = AXP2XX_GET_CLASS(s);
168 sc->reset_enter(s, type);
171 /* Handle events from master. */
172 static int axp2xx_event(I2CSlave *i2c, enum i2c_event event)
174 AXP2xxI2CState *s = AXP2XX(i2c);
176 s->count = 0;
178 return 0;
181 /* Called when master requests read */
182 static uint8_t axp2xx_rx(I2CSlave *i2c)
184 AXP2xxI2CState *s = AXP2XX(i2c);
185 uint8_t ret = 0xff;
187 if (s->ptr < NR_REGS) {
188 ret = s->regs[s->ptr++];
191 trace_axp2xx_rx(s->ptr - 1, ret);
193 return ret;
197 * Called when master sends write.
198 * Update ptr with byte 0, then perform write with second byte.
200 static int axp2xx_tx(I2CSlave *i2c, uint8_t data)
202 AXP2xxI2CState *s = AXP2XX(i2c);
204 if (s->count == 0) {
205 /* Store register address */
206 s->ptr = data;
207 s->count++;
208 trace_axp2xx_select(data);
209 } else {
210 trace_axp2xx_tx(s->ptr, data);
211 s->regs[s->ptr++] = data;
214 return 0;
217 static const VMStateDescription vmstate_axp2xx = {
218 .name = TYPE_AXP2XX,
219 .version_id = 1,
220 .fields = (const VMStateField[]) {
221 VMSTATE_UINT8_ARRAY(regs, AXP2xxI2CState, NR_REGS),
222 VMSTATE_UINT8(ptr, AXP2xxI2CState),
223 VMSTATE_UINT8(count, AXP2xxI2CState),
224 VMSTATE_END_OF_LIST()
228 static void axp2xx_class_init(ObjectClass *oc, void *data)
230 DeviceClass *dc = DEVICE_CLASS(oc);
231 I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
232 ResettableClass *rc = RESETTABLE_CLASS(oc);
234 rc->phases.enter = axp2xx_reset_enter;
235 dc->vmsd = &vmstate_axp2xx;
236 isc->event = axp2xx_event;
237 isc->recv = axp2xx_rx;
238 isc->send = axp2xx_tx;
241 static const TypeInfo axp2xx_info = {
242 .name = TYPE_AXP2XX,
243 .parent = TYPE_I2C_SLAVE,
244 .instance_size = sizeof(AXP2xxI2CState),
245 .class_size = sizeof(AXP2xxClass),
246 .class_init = axp2xx_class_init,
247 .abstract = true,
250 static void axp209_class_init(ObjectClass *oc, void *data)
252 AXP2xxClass *sc = AXP2XX_CLASS(oc);
254 sc->reset_enter = axp209_reset_enter;
257 static const TypeInfo axp209_info = {
258 .name = TYPE_AXP209_PMU,
259 .parent = TYPE_AXP2XX,
260 .class_init = axp209_class_init
263 static void axp221_class_init(ObjectClass *oc, void *data)
265 AXP2xxClass *sc = AXP2XX_CLASS(oc);
267 sc->reset_enter = axp221_reset_enter;
270 static const TypeInfo axp221_info = {
271 .name = TYPE_AXP221_PMU,
272 .parent = TYPE_AXP2XX,
273 .class_init = axp221_class_init,
276 static void axp2xx_register_devices(void)
278 type_register_static(&axp2xx_info);
279 type_register_static(&axp209_info);
280 type_register_static(&axp221_info);
283 type_init(axp2xx_register_devices);