1 /* 2 * AXP-2XX PMU Emulation, supported lists: 3 * AXP209 4 * AXP221 5 * 6 * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com> 7 * Copyright (C) 2023 qianfan Zhao <qianfanguijin@163.com> 8 * 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: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 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. 26 * 27 * SPDX-License-Identifier: MIT 28 */ 29 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" 36 37 #define TYPE_AXP2XX "axp2xx_pmu" 38 #define TYPE_AXP209_PMU "axp209_pmu" 39 #define TYPE_AXP221_PMU "axp221_pmu" 40 41 OBJECT_DECLARE_TYPE(AXP2xxI2CState, AXP2xxClass, AXP2XX) 42 43 #define NR_REGS (0xff) 44 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; 54 55 typedef struct AXP2xxClass { 56 /*< private >*/ 57 I2CSlaveClass parent_class; 58 /*< public >*/ 59 void (*reset_enter)(AXP2xxI2CState *s, ResetType type); 60 } AXP2xxClass; 61 62 #define AXP209_CHIP_VERSION_ID (0x01) 63 #define AXP209_DC_DC2_OUT_V_CTRL_RESET (0x16) 64 65 /* Reset all counters and load ID register */ 66 static void axp209_reset_enter(AXP2xxI2CState *s, ResetType type) 67 { 68 memset(s->regs, 0, NR_REGS); 69 s->ptr = 0; 70 s->count = 0; 71 72 s->regs[0x03] = AXP209_CHIP_VERSION_ID; 73 s->regs[0x23] = AXP209_DC_DC2_OUT_V_CTRL_RESET; 74 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; 99 } 100 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) 107 108 /* Reset all counters and load ID register */ 109 static void axp221_reset_enter(AXP2xxI2CState *s, ResetType type) 110 { 111 memset(s->regs, 0, NR_REGS); 112 s->ptr = 0; 113 s->count = 0; 114 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; 119 120 s->regs[0x01] = 0x00; /* no battery is connected */ 121 122 /* 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. 126 */ 127 s->regs[0x03] = 0x06; 128 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; 147 148 s->regs[0x90] = 0x07; 149 s->regs[0x91] = 0x1f; 150 s->regs[0x92] = 0x07; 151 s->regs[0x93] = 0x1f; 152 153 s->regs[0x40] = 0xd8; 154 s->regs[0x41] = 0xff; 155 s->regs[0x42] = 0x03; 156 s->regs[0x43] = 0x03; 157 158 s->regs[0xb8] = 0xc0; 159 s->regs[0xb9] = 0x64; 160 s->regs[0xe6] = 0xa0; 161 } 162 163 static void axp2xx_reset_enter(Object *obj, ResetType type) 164 { 165 AXP2xxI2CState *s = AXP2XX(obj); 166 AXP2xxClass *sc = AXP2XX_GET_CLASS(s); 167 168 sc->reset_enter(s, type); 169 } 170 171 /* Handle events from master. */ 172 static int axp2xx_event(I2CSlave *i2c, enum i2c_event event) 173 { 174 AXP2xxI2CState *s = AXP2XX(i2c); 175 176 s->count = 0; 177 178 return 0; 179 } 180 181 /* Called when master requests read */ 182 static uint8_t axp2xx_rx(I2CSlave *i2c) 183 { 184 AXP2xxI2CState *s = AXP2XX(i2c); 185 uint8_t ret = 0xff; 186 187 if (s->ptr < NR_REGS) { 188 ret = s->regs[s->ptr++]; 189 } 190 191 trace_axp2xx_rx(s->ptr - 1, ret); 192 193 return ret; 194 } 195 196 /* 197 * Called when master sends write. 198 * Update ptr with byte 0, then perform write with second byte. 199 */ 200 static int axp2xx_tx(I2CSlave *i2c, uint8_t data) 201 { 202 AXP2xxI2CState *s = AXP2XX(i2c); 203 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; 212 } 213 214 return 0; 215 } 216 217 static const VMStateDescription vmstate_axp2xx = { 218 .name = TYPE_AXP2XX, 219 .version_id = 1, 220 .fields = (VMStateField[]) { 221 VMSTATE_UINT8_ARRAY(regs, AXP2xxI2CState, NR_REGS), 222 VMSTATE_UINT8(ptr, AXP2xxI2CState), 223 VMSTATE_UINT8(count, AXP2xxI2CState), 224 VMSTATE_END_OF_LIST() 225 } 226 }; 227 228 static void axp2xx_class_init(ObjectClass *oc, void *data) 229 { 230 DeviceClass *dc = DEVICE_CLASS(oc); 231 I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc); 232 ResettableClass *rc = RESETTABLE_CLASS(oc); 233 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; 239 } 240 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, 248 }; 249 250 static void axp209_class_init(ObjectClass *oc, void *data) 251 { 252 AXP2xxClass *sc = AXP2XX_CLASS(oc); 253 254 sc->reset_enter = axp209_reset_enter; 255 } 256 257 static const TypeInfo axp209_info = { 258 .name = TYPE_AXP209_PMU, 259 .parent = TYPE_AXP2XX, 260 .class_init = axp209_class_init 261 }; 262 263 static void axp221_class_init(ObjectClass *oc, void *data) 264 { 265 AXP2xxClass *sc = AXP2XX_CLASS(oc); 266 267 sc->reset_enter = axp221_reset_enter; 268 } 269 270 static const TypeInfo axp221_info = { 271 .name = TYPE_AXP221_PMU, 272 .parent = TYPE_AXP2XX, 273 .class_init = axp221_class_init, 274 }; 275 276 static void axp2xx_register_devices(void) 277 { 278 type_register_static(&axp2xx_info); 279 type_register_static(&axp209_info); 280 type_register_static(&axp221_info); 281 } 282 283 type_init(axp2xx_register_devices); 284