1 /* $OpenBSD: axppmic.c,v 1.15 2022/07/16 11:26:13 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/device.h> 21 #include <sys/malloc.h> 22 #include <sys/sensors.h> 23 24 #include <dev/i2c/i2cvar.h> 25 #include <dev/fdt/rsbvar.h> 26 27 #include <dev/ofw/openfirm.h> 28 #include <dev/ofw/ofw_regulator.h> 29 #include <dev/ofw/fdt.h> 30 31 extern void (*powerdownfn)(void); 32 33 #define AXP209_SDR 0x32 34 #define AXP209_SDR_SHUTDOWN (1 << 7) 35 #define AXP209_ADC_EN1 0x82 36 #define AXP209_ADC_EN1_ACIN (3 << 4) 37 #define AXP209_ADC_EN1_VBUS (3 << 2) 38 39 #define AXP803_IRQ1_EN 0x40 40 #define AXP803_IRQ2_EN 0x41 41 #define AXP803_IRQ3_EN 0x42 42 #define AXP803_IRQ4_EN 0x43 43 #define AXP803_IRQ5_EN 0x44 44 #define AXP803_IRQ5_EN_PEK_SHORT (1 << 4) 45 #define AXP803_IRQ6_EN 0x45 46 #define AXP803_IRQ1_STAT 0x48 47 #define AXP803_IRQ2_STAT 0x49 48 #define AXP803_IRQ3_STAT 0x4a 49 #define AXP803_IRQ4_STAT 0x4b 50 #define AXP803_IRQ5_STAT 0x4c 51 #define AXP803_IRQ5_STAT_PEK_SHORT (1 << 4) 52 #define AXP803_IRQ6_STAT 0x4d 53 #define AXP803_BAT_CAP_WARN 0xe6 54 #define AXP803_BAT_CAP_WARN_LV1 0xf0 55 #define AXP803_BAT_CAP_WARN_LV1BASE 5 56 #define AXP803_BAT_CAP_WARN_LV2 0x0f 57 58 #define AXP806_REG_ADDR_EXT 0xff 59 #define AXP806_REG_ADDR_EXT_MASTER_MODE (0 << 4) 60 #define AXP806_REG_ADDR_EXT_SLAVE_MODE (1 << 4) 61 62 /* Regulators for AXP209, AXP221, AXP806 and AXP809. */ 63 64 struct axppmic_regdata { 65 const char *name; 66 uint8_t ereg, emask, eval, dval; 67 uint8_t vreg, vmask; 68 uint32_t base, delta; 69 uint32_t base2, delta2; 70 }; 71 72 const struct axppmic_regdata axp209_regdata[] = { 73 { "dcdc2", 0x12, (1 << 4), (1 << 4), (0 << 4), 74 0x23, 0x3f, 700000, 25000 }, 75 { "dcdc3", 0x12, (1 << 1), (1 << 1), (0 << 1), 76 0x27, 0x3f, 700000, 25000 }, 77 /* LDO1 can't be controlled */ 78 { "ldo2", 0x12, (1 << 2), (1 << 2), (0 << 2), 79 0x28, 0xf0, 1800000, (100000 >> 4) }, 80 { "ldo3", 0x12, (1 << 6), (1 << 6), (0 << 6), 81 0x29, 0x7f, 700000, 25000 }, 82 /* LDO4 voltage levels are complicated */ 83 { "ldo5", 0x90, 0x07, 0x03, 0x07, 84 0x91, 0xf0, 1800000, (100000 >> 4) }, 85 { NULL } 86 }; 87 88 const struct axppmic_regdata axp221_regdata[] = { 89 { "dcdc1", 0x10, (1 << 1), (1 << 1), (0 << 1), 90 0x21, 0x1f, 1600000, 100000 }, 91 { "dcdc2", 0x10, (1 << 2), (1 << 2), (0 << 2), 92 0x22, 0x3f, 600000, 20000 }, 93 { "dcdc3", 0x10, (1 << 3), (1 << 3), (0 << 3), 94 0x23, 0x3f, 600000, 20000 }, 95 { "dcdc4", 0x10, (1 << 4), (1 << 4), (0 << 4), 96 0x24, 0x3f, 600000, 20000 }, 97 { "dcdc5", 0x10, (1 << 5), (1 << 5), (0 << 5), 98 0x25, 0x1f, 1000000, 50000 }, 99 { "dc1sw", 0x12, (1 << 7), (1 << 7), (0 << 7) }, 100 { "dc5ldo", 0x10, (1 << 0), (1 << 0), (0 << 0), 101 0x1c, 0x07, 700000, 100000 }, 102 { "aldo1", 0x10, (1 << 6), (1 << 6), (0 << 6), 103 0x28, 0x1f, 700000, 100000 }, 104 { "aldo2", 0x10, (1 << 7), (1 << 7), (0 << 7), 105 0x29, 0x1f, 700000, 100000 }, 106 { "aldo3", 0x13, (1 << 7), (1 << 7), (0 << 7), 107 0x2a, 0x1f, 700000, 100000 }, 108 { "dldo1", 0x12, (1 << 3), (1 << 3), (0 << 3), 109 0x15, 0x1f, 700000, 100000 }, 110 { "dldo2", 0x12, (1 << 4), (1 << 4), (0 << 4), 111 0x16, 0x1f, 700000, 100000 }, 112 { "dldo3", 0x12, (1 << 5), (1 << 5), (0 << 5), 113 0x17, 0x1f, 700000, 100000 }, 114 { "dldo4", 0x12, (1 << 6), (1 << 6), (0 << 6), 115 0x18, 0x1f, 700000, 100000 }, 116 { "eldo1", 0x12, (1 << 0), (1 << 0), (0 << 0), 117 0x19, 0x1f, 700000, 100000 }, 118 { "eldo2", 0x12, (1 << 1), (1 << 1), (0 << 1), 119 0x1a, 0x1f, 700000, 100000 }, 120 { "eldo3", 0x12, (1 << 2), (1 << 2), (0 << 2), 121 0x1b, 0x1f, 700000, 100000 }, 122 { "ldo_io0", 0x90, 0x07, 0x03, 0x04, 123 0x91, 0x1f, 700000, 100000 }, 124 { "ldo_io1", 0x92, 0x07, 0x03, 0x04, 125 0x93, 0x1f, 700000, 100000 }, 126 { NULL } 127 }; 128 129 const struct axppmic_regdata axp803_regdata[] = { 130 { "dcdc1", 0x10, (1 << 0), (1 << 0), (0 << 0), 131 0x20, 0x1f, 1600000, 100000 }, 132 { "dcdc2", 0x10, (1 << 1), (1 << 1), (0 << 1), 133 0x21, 0x7f, 500000, 10000, 1220000, 20000 }, 134 { "dcdc3", 0x10, (1 << 2), (1 << 2), (0 << 2), 135 0x22, 0x7f, 500000, 10000, 1220000, 20000 }, 136 { "dcdc4", 0x10, (1 << 3), (1 << 3), (0 << 3), 137 0x23, 0x7f, 500000, 10000, 1220000, 20000 }, 138 { "dcdc5", 0x10, (1 << 4), (1 << 4), (0 << 4), 139 0x24, 0x7f, 800000, 10000, 1140000, 20000 }, 140 { "dcdc6", 0x10, (1 << 5), (1 << 5), (0 << 5), 141 0x25, 0x7f, 600000, 10000, 1120000, 20000 }, 142 { "dc1sw", 0x12, (1 << 7), (1 << 7), (0 << 7) }, 143 { "aldo1", 0x13, (1 << 5), (1 << 5), (0 << 5), 144 0x28, 0x1f, 700000, 100000 }, 145 { "aldo2", 0x13, (1 << 6), (1 << 6), (0 << 6), 146 0x29, 0x1f, 700000, 100000 }, 147 { "aldo3", 0x13, (1 << 7), (1 << 7), (0 << 7), 148 0x2a, 0x1f, 700000, 100000 }, 149 { "dldo1", 0x12, (1 << 3), (1 << 3), (0 << 3), 150 0x15, 0x1f, 700000, 100000 }, 151 { "dldo2", 0x12, (1 << 4), (1 << 4), (0 << 4), 152 0x16, 0x1f, 700000, 100000, 3400000, 200000 }, 153 { "dldo3", 0x12, (1 << 5), (1 << 5), (0 << 5), 154 0x17, 0x1f, 700000, 100000 }, 155 { "dldo4", 0x12, (1 << 6), (1 << 6), (0 << 6), 156 0x18, 0x1f, 700000, 100000 }, 157 { "eldo1", 0x12, (1 << 0), (1 << 0), (0 << 0), 158 0x19, 0x1f, 700000, 50000 }, 159 { "eldo2", 0x12, (1 << 1), (1 << 1), (0 << 1), 160 0x1a, 0x1f, 700000, 50000 }, 161 { "eldo3", 0x12, (1 << 2), (1 << 2), (0 << 2), 162 0x1b, 0x1f, 700000, 50000 }, 163 { "fldo1", 0x13, (1 << 2), (1 << 2), (0 << 2), 164 0x1c, 0x0f, 700000, 50000 }, 165 { "fldo2", 0x13, (1 << 3), (1 << 3), (0 << 3), 166 0x1d, 0x0f, 700000, 50000 }, 167 { "ldo-io0", 0x90, 0x07, 0x03, 0x04, 168 0x91, 0x1f, 700000, 100000 }, 169 { "ldo-io1", 0x92, 0x07, 0x03, 0x04, 170 0x93, 0x1f, 700000, 100000 }, 171 { NULL } 172 }; 173 174 const struct axppmic_regdata axp806_regdata[] = { 175 { "dcdca", 0x10, (1 << 0), (1 << 0), (0 << 0), 176 0x12, 0x7f, 600000, 10000, 1120000, 20000 }, 177 { "dcdcb", 0x10, (1 << 1), (1 << 1), (0 << 1), 178 0x13, 0x1f, 1000000, 50000 }, 179 { "dcdcc", 0x10, (1 << 2), (1 << 2), (0 << 2), 180 0x14, 0x7f, 600000, 10000, 1120000, 20000 }, 181 { "dcdcd", 0x10, (1 << 3), (1 << 3), (0 << 3), 182 0x15, 0x3f, 600000, 20000, 1600000, 100000 }, 183 { "dcdce", 0x10, (1 << 4), (1 << 4), (0 << 4), 184 0x16, 0x1f, 1100000, 100000 }, 185 { "aldo1", 0x10, (1 << 5), (1 << 5), (0 << 5), 186 0x17, 0x1f, 700000, 100000 }, 187 { "aldo2", 0x10, (1 << 6), (1 << 6), (0 << 6), 188 0x18, 0x1f, 700000, 100000 }, 189 { "aldo3", 0x10, (1 << 7), (1 << 7), (0 << 7), 190 0x19, 0x1f, 700000, 100000 }, 191 { "bldo1", 0x11, (1 << 0), (1 << 0), (0 << 0), 192 0x20, 0x0f, 700000, 100000 }, 193 { "bldo2", 0x11, (1 << 1), (1 << 1), (0 << 1), 194 0x21, 0x0f, 700000, 100000 }, 195 { "bldo3", 0x11, (1 << 2), (1 << 2), (0 << 2), 196 0x22, 0x0f, 700000, 100000 }, 197 { "bldo4", 0x11, (1 << 3), (1 << 3), (0 << 3), 198 0x23, 0x0f, 700000, 100000 }, 199 { "cldo1", 0x11, (1 << 4), (1 << 4), (0 << 4), 200 0x24, 0x1f, 700000, 100000 }, 201 { "cldo2", 0x11, (1 << 5), (1 << 5), (0 << 5), 202 0x25, 0x1f, 700000, 100000, 3600000, 200000 }, 203 { "cldo3", 0x11, (1 << 6), (1 << 6), (0 << 6), 204 0x26, 0x1f, 700000, 100000 }, 205 { "sw", 0x11, (1 << 7), (1 << 7), (0 << 7) }, 206 { NULL } 207 }; 208 209 const struct axppmic_regdata axp809_regdata[] = { 210 { "dcdc1", 0x10, (1 << 1), (1 << 1), (0 << 1), 211 0x21, 0x1f, 1600000, 100000 }, 212 { "dcdc2", 0x10, (1 << 2), (1 << 2), (0 << 2), 213 0x22, 0x3f, 600000, 20000 }, 214 { "dcdc3", 0x10, (1 << 3), (1 << 3), (0 << 3), 215 0x23, 0x3f, 600000, 20000 }, 216 { "dcdc4", 0x10, (1 << 4), (1 << 4), (0 << 4), 217 0x24, 0x3f, 600000, 20000, 1800000, 100000 }, 218 { "dcdc5", 0x10, (1 << 5), (1 << 5), (0 << 5), 219 0x25, 0x1f, 1000000, 50000 }, 220 { "dc5ldo", 0x10, (1 << 0), (1 << 0), (0 << 0), 221 0x1c, 0x07, 700000, 100000 }, 222 { "aldo1", 0x10, (1 << 6), (1 << 6), (0 << 6), 223 0x28, 0x1f, 700000, 100000 }, 224 { "aldo2", 0x10, (1 << 7), (1 << 7), (0 << 7), 225 0x29, 0x1f, 700000, 100000 }, 226 { "aldo3", 0x12, (1 << 5), (1 << 5), (0 << 5), 227 0x2a, 0x1f, 700000, 100000 }, 228 { "dldo1", 0x12, (1 << 3), (1 << 3), (0 << 3), 229 0x15, 0x1f, 700000, 100000 }, 230 { "dldo2", 0x12, (1 << 4), (1 << 4), (0 << 4), 231 0x16, 0x1f, 700000, 100000 }, 232 { "eldo1", 0x12, (1 << 0), (1 << 0), (0 << 0), 233 0x19, 0x1f, 700000, 100000 }, 234 { "eldo2", 0x12, (1 << 1), (1 << 1), (0 << 1), 235 0x1a, 0x1f, 700000, 100000 }, 236 { "eldo3", 0x12, (1 << 2), (1 << 2), (0 << 2), 237 0x1b, 0x1f, 700000, 100000 }, 238 { "ldo_io0", 0x90, 0x07, 0x03, 0x04, 239 0x91, 0x1f, 700000, 100000 }, 240 { "ldo_io1", 0x92, 0x07, 0x03, 0x04, 241 0x93, 0x1f, 700000, 100000 }, 242 { NULL } 243 }; 244 245 /* Sensors for AXP209 and AXP221/AXP809. */ 246 247 #define AXPPMIC_NSENSORS 12 248 249 struct axppmic_sensdata { 250 const char *name; 251 enum sensor_type type; 252 uint8_t reg; 253 uint64_t base, delta; 254 }; 255 256 const struct axppmic_sensdata axp209_sensdata[] = { 257 { "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) }, 258 { "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) }, 259 { "ACIN", SENSOR_VOLTS_DC, 0x56, 0, 1700 }, 260 { "ACIN", SENSOR_AMPS, 0x58, 0, 625 }, 261 { "VBUS", SENSOR_VOLTS_DC, 0x5a, 0, 1700 }, 262 { "VBUS", SENSOR_AMPS, 0x5c, 0, 375 }, 263 { "", SENSOR_TEMP, 0x5e, 128450000, 100000 }, 264 { "APS", SENSOR_VOLTS_DC, 0x7e, 0, 1400 }, 265 { NULL } 266 }; 267 268 const struct axppmic_sensdata axp221_sensdata[] = { 269 { "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) }, 270 { "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) }, 271 { "", SENSOR_TEMP, 0x56, 5450000, 105861 }, 272 { NULL } 273 }; 274 275 const struct axppmic_sensdata axp803_sensdata[] = { 276 { "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) }, 277 { "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) }, 278 { "", SENSOR_TEMP, 0x56, 5450000, 106250 }, 279 { NULL } 280 }; 281 282 const struct axppmic_sensdata axp803_battery_sensdata[] = { 283 { "ACIN", SENSOR_INDICATOR, 0x00, (1 << 7), (1 << 6) }, 284 { "VBUS", SENSOR_INDICATOR, 0x00, (1 << 5), (1 << 4) }, 285 { "", SENSOR_TEMP, 0x56, 5450000, 106250 }, 286 { "battery present", SENSOR_INDICATOR, 0x01, (1 << 5), (1 << 4) }, 287 { "battery charging", SENSOR_INDICATOR, 0x01, (1 << 6), (1 << 6) }, 288 { "battery percent", SENSOR_PERCENT, 0xb9, 0x7f, (1 << 7) }, 289 { "battery voltage", SENSOR_VOLTS_DC, 0x78, 0x00, 1100 }, 290 { "battery charging current", SENSOR_AMPS, 0x7a, 0x00, 1000 }, 291 { "battery discharging current", SENSOR_AMPS, 0x7c, 0x00, 1000 }, 292 { "battery maximum capacity", SENSOR_AMPHOUR, 0xe0, 0x00, 1456 }, 293 { "battery current capacity", SENSOR_AMPHOUR, 0xe2, 0x00, 1456 }, 294 { NULL } 295 }; 296 297 struct axppmic_device { 298 const char *name; 299 const char *chip; 300 const struct axppmic_regdata *regdata; 301 const struct axppmic_sensdata *sensdata; 302 }; 303 304 const struct axppmic_device axppmic_devices[] = { 305 { "x-powers,axp152", "AXP152" }, 306 { "x-powers,axp209", "AXP209", axp209_regdata, axp209_sensdata }, 307 { "x-powers,axp221", "AXP221", axp221_regdata, axp221_sensdata }, 308 { "x-powers,axp223", "AXP223", axp221_regdata, axp221_sensdata }, 309 { "x-powers,axp803", "AXP803", axp803_regdata, axp803_sensdata }, 310 { "x-powers,axp805", "AXP805", axp806_regdata }, 311 { "x-powers,axp806", "AXP806", axp806_regdata }, 312 { "x-powers,axp809", "AXP809", axp809_regdata, axp221_sensdata } 313 }; 314 315 const struct axppmic_device * 316 axppmic_lookup(const char *name) 317 { 318 int i; 319 320 for (i = 0; i < nitems(axppmic_devices); i++) { 321 if (strcmp(name, axppmic_devices[i].name) == 0) 322 return &axppmic_devices[i]; 323 } 324 325 return NULL; 326 } 327 328 struct axppmic_softc { 329 struct device sc_dev; 330 void *sc_cookie; 331 uint16_t sc_addr; 332 const char *sc_name; 333 334 uint8_t (*sc_read)(struct axppmic_softc *, uint8_t); 335 void (*sc_write)(struct axppmic_softc *, uint8_t, uint8_t); 336 const struct axppmic_regdata *sc_regdata; 337 const struct axppmic_sensdata *sc_sensdata; 338 339 struct ksensor sc_sensor[AXPPMIC_NSENSORS]; 340 struct ksensordev sc_sensordev; 341 342 uint8_t sc_warn; 343 uint8_t sc_crit; 344 }; 345 346 static inline uint8_t 347 axppmic_read_reg(struct axppmic_softc *sc, uint8_t reg) 348 { 349 return sc->sc_read(sc, reg); 350 } 351 352 static inline void 353 axppmic_write_reg(struct axppmic_softc *sc, uint8_t reg, uint8_t value) 354 { 355 sc->sc_write(sc, reg, value); 356 } 357 358 void axppmic_attach_common(struct axppmic_softc *, const char *, int); 359 int axppmic_activate(struct device *, int); 360 361 /* I2C interface */ 362 363 int axppmic_i2c_match(struct device *, void *, void *); 364 void axppmic_i2c_attach(struct device *, struct device *, void *); 365 366 const struct cfattach axppmic_ca = { 367 sizeof(struct axppmic_softc), axppmic_i2c_match, axppmic_i2c_attach, 368 NULL, axppmic_activate 369 }; 370 371 struct cfdriver axppmic_cd = { 372 NULL, "axppmic", DV_DULL 373 }; 374 375 uint8_t axppmic_i2c_read(struct axppmic_softc *, uint8_t); 376 void axppmic_i2c_write(struct axppmic_softc *, uint8_t, uint8_t); 377 378 int 379 axppmic_i2c_match(struct device *parent, void *match, void *aux) 380 { 381 struct i2c_attach_args *ia = aux; 382 383 if (axppmic_lookup(ia->ia_name)) 384 return 1; 385 return 0; 386 } 387 388 void 389 axppmic_i2c_attach(struct device *parent, struct device *self, void *aux) 390 { 391 struct axppmic_softc *sc = (struct axppmic_softc *)self; 392 struct i2c_attach_args *ia = aux; 393 int node = *(int *)ia->ia_cookie; 394 395 sc->sc_cookie = ia->ia_tag; 396 sc->sc_addr = ia->ia_addr; 397 sc->sc_read = axppmic_i2c_read; 398 sc->sc_write = axppmic_i2c_write; 399 400 axppmic_attach_common(sc, ia->ia_name, node); 401 } 402 403 uint8_t 404 axppmic_i2c_read(struct axppmic_softc *sc, uint8_t reg) 405 { 406 i2c_tag_t tag = sc->sc_cookie; 407 int flags = cold ? I2C_F_POLL : 0; 408 int error; 409 uint8_t value; 410 411 iic_acquire_bus(tag, flags); 412 error = iic_smbus_read_byte(tag, sc->sc_addr, reg, &value, flags); 413 iic_release_bus(tag, flags); 414 if (error) { 415 printf("%s: SMBus read byte from 0x%02x failed\n", 416 sc->sc_dev.dv_xname, reg); 417 return 0xff; 418 } 419 420 return value; 421 } 422 423 void 424 axppmic_i2c_write(struct axppmic_softc *sc, uint8_t reg, uint8_t value) 425 { 426 i2c_tag_t tag = sc->sc_cookie; 427 int flags = cold ? I2C_F_POLL : 0; 428 int error; 429 430 iic_acquire_bus(tag, flags); 431 error = iic_smbus_write_byte(tag, sc->sc_addr, reg, value, flags); 432 iic_release_bus(tag, flags); 433 if (error) 434 printf("%s: SMBus write byte to 0x%02x failed\n", 435 sc->sc_dev.dv_xname, reg); 436 } 437 438 /* RSB interface */ 439 440 int axppmic_rsb_match(struct device *, void *, void *); 441 void axppmic_rsb_attach(struct device *, struct device *, void *); 442 443 const struct cfattach axppmic_rsb_ca = { 444 sizeof(struct axppmic_softc), axppmic_rsb_match, axppmic_rsb_attach, 445 NULL, axppmic_activate 446 }; 447 448 struct cfdriver axppmic_rsb_cd = { 449 NULL, "axppmic", DV_DULL 450 }; 451 452 uint8_t axppmic_rsb_read(struct axppmic_softc *, uint8_t); 453 void axppmic_rsb_write(struct axppmic_softc *, uint8_t, uint8_t); 454 455 int 456 axppmic_rsb_match(struct device *parent, void *match, void *aux) 457 { 458 struct rsb_attach_args *ra = aux; 459 460 if (axppmic_lookup(ra->ra_name)) 461 return 1; 462 return 0; 463 } 464 465 void 466 axppmic_rsb_attach(struct device *parent, struct device *self, void *aux) 467 { 468 struct axppmic_softc *sc = (struct axppmic_softc *)self; 469 struct rsb_attach_args *ra = aux; 470 471 sc->sc_cookie = ra->ra_cookie; 472 sc->sc_addr = ra->ra_rta; 473 sc->sc_read = axppmic_rsb_read; 474 sc->sc_write = axppmic_rsb_write; 475 476 axppmic_attach_common(sc, ra->ra_name, ra->ra_node); 477 } 478 479 uint8_t 480 axppmic_rsb_read(struct axppmic_softc *sc, uint8_t reg) 481 { 482 return rsb_read_1(sc->sc_cookie, sc->sc_addr, reg); 483 } 484 485 void 486 axppmic_rsb_write(struct axppmic_softc *sc, uint8_t reg, uint8_t value) 487 { 488 rsb_write_1(sc->sc_cookie, sc->sc_addr, reg, value); 489 } 490 491 /* Common code */ 492 493 void axppmic_attach_node(struct axppmic_softc *, int); 494 void axppmic_attach_regulators(struct axppmic_softc *, int); 495 void axppmic_attach_sensors(struct axppmic_softc *); 496 497 struct axppmic_softc *axppmic_sc; 498 void axp209_powerdown(void); 499 500 void 501 axppmic_attach_common(struct axppmic_softc *sc, const char *name, int node) 502 { 503 const struct axppmic_device *device; 504 int child; 505 506 device = axppmic_lookup(name); 507 printf(": %s\n", device->chip); 508 509 sc->sc_name = device->name; 510 sc->sc_regdata = device->regdata; 511 sc->sc_sensdata = device->sensdata; 512 513 /* Switch AXP806 into master or slave mode. */ 514 if (strcmp(name, "x-powers,axp805") == 0 || 515 strcmp(name, "x-powers,axp806") == 0) { 516 if (OF_getproplen(node, "x-powers,master-mode") == 0 || 517 OF_getproplen(node, "x-powers,self-working-mode") == 0) { 518 axppmic_write_reg(sc, AXP806_REG_ADDR_EXT, 519 AXP806_REG_ADDR_EXT_MASTER_MODE); 520 } else { 521 axppmic_write_reg(sc, AXP806_REG_ADDR_EXT, 522 AXP806_REG_ADDR_EXT_SLAVE_MODE); 523 } 524 } 525 526 /* Enable data collection on AXP209. */ 527 if (strcmp(name, "x-powers,axp209") == 0) { 528 uint8_t reg; 529 530 /* Turn on sampling of ACIN and VBUS voltage and current. */ 531 reg = axppmic_read_reg(sc, AXP209_ADC_EN1); 532 reg |= AXP209_ADC_EN1_ACIN; 533 reg |= AXP209_ADC_EN1_VBUS; 534 axppmic_write_reg(sc, AXP209_ADC_EN1, reg); 535 } 536 537 /* Read battery warning levels on AXP803. */ 538 if (strcmp(name, "x-powers,axp803") == 0) { 539 uint8_t value; 540 541 value = axppmic_read_reg(sc, AXP803_BAT_CAP_WARN); 542 sc->sc_warn = ((value & AXP803_BAT_CAP_WARN_LV1) >> 4); 543 sc->sc_warn += AXP803_BAT_CAP_WARN_LV1BASE; 544 sc->sc_crit = (value & AXP803_BAT_CAP_WARN_LV2); 545 } 546 547 for (child = OF_child(node); child; child = OF_peer(child)) 548 axppmic_attach_node(sc, child); 549 550 if (sc->sc_regdata) 551 axppmic_attach_regulators(sc, node); 552 553 if (sc->sc_sensdata) 554 axppmic_attach_sensors(sc); 555 556 /* Disable all interrupts on AXP803. */ 557 if (strcmp(name, "x-powers,axp803") == 0) { 558 axppmic_write_reg(sc, AXP803_IRQ1_EN, 0); 559 axppmic_write_reg(sc, AXP803_IRQ2_EN, 0); 560 axppmic_write_reg(sc, AXP803_IRQ3_EN, 0); 561 axppmic_write_reg(sc, AXP803_IRQ4_EN, 0); 562 axppmic_write_reg(sc, AXP803_IRQ5_EN, 0); 563 axppmic_write_reg(sc, AXP803_IRQ6_EN, 0); 564 } 565 566 #ifdef __armv7__ 567 if (strcmp(name, "x-powers,axp152") == 0 || 568 strcmp(name, "x-powers,axp209") == 0) { 569 axppmic_sc = sc; 570 powerdownfn = axp209_powerdown; 571 } 572 #endif 573 } 574 575 void 576 axppmic_attach_node(struct axppmic_softc *sc, int node) 577 { 578 char status[32]; 579 580 if (OF_getprop(node, "status", status, sizeof(status)) > 0 && 581 strcmp(status, "disabled") == 0) 582 return; 583 584 if (OF_is_compatible(node, "x-powers,axp803-battery-power-supply")) 585 sc->sc_sensdata = axp803_battery_sensdata; 586 } 587 588 int 589 axppmic_activate(struct device *self, int act) 590 { 591 struct axppmic_softc *sc = (struct axppmic_softc *)self; 592 593 switch (act) { 594 case DVACT_SUSPEND: 595 if (strcmp(sc->sc_name, "x-powers,axp803") == 0) { 596 /* Enable interrupt for short power button press. */ 597 axppmic_write_reg(sc, AXP803_IRQ5_STAT, 598 AXP803_IRQ5_STAT_PEK_SHORT); 599 axppmic_write_reg(sc, AXP803_IRQ5_EN, 600 AXP803_IRQ5_EN_PEK_SHORT); 601 } 602 break; 603 case DVACT_RESUME: 604 if (strcmp(sc->sc_name, "x-powers,axp803") == 0) { 605 /* Disable interrupt for short power button press. */ 606 axppmic_write_reg(sc, AXP803_IRQ5_EN, 0); 607 } 608 break; 609 } 610 611 return 0; 612 } 613 614 /* Regulators */ 615 616 struct axppmic_regulator { 617 struct axppmic_softc *ar_sc; 618 619 uint8_t ar_ereg, ar_emask; 620 uint8_t ar_eval, ar_dval; 621 622 uint8_t ar_vreg, ar_vmask; 623 uint32_t ar_base, ar_delta; 624 uint32_t ar_base2, ar_delta2; 625 626 struct regulator_device ar_rd; 627 }; 628 629 void axppmic_attach_regulator(struct axppmic_softc *, int); 630 uint32_t axppmic_get_voltage(void *); 631 int axppmic_set_voltage(void *, uint32_t); 632 int axppmic_enable(void *, int); 633 634 void 635 axppmic_attach_regulators(struct axppmic_softc *sc, int node) 636 { 637 node = OF_getnodebyname(node, "regulators"); 638 if (node == 0) 639 return; 640 641 for (node = OF_child(node); node; node = OF_peer(node)) 642 axppmic_attach_regulator(sc, node); 643 } 644 645 void 646 axppmic_attach_regulator(struct axppmic_softc *sc, int node) 647 { 648 struct axppmic_regulator *ar; 649 char name[32]; 650 int i; 651 652 name[0] = 0; 653 OF_getprop(node, "name", name, sizeof(name)); 654 name[sizeof(name) - 1] = 0; 655 for (i = 0; sc->sc_regdata[i].name; i++) { 656 if (strcmp(sc->sc_regdata[i].name, name) == 0) 657 break; 658 } 659 if (sc->sc_regdata[i].name == NULL) 660 return; 661 662 ar = malloc(sizeof(*ar), M_DEVBUF, M_WAITOK | M_ZERO); 663 ar->ar_sc = sc; 664 665 ar->ar_ereg = sc->sc_regdata[i].ereg; 666 ar->ar_emask = sc->sc_regdata[i].emask; 667 ar->ar_eval = sc->sc_regdata[i].eval; 668 ar->ar_dval = sc->sc_regdata[i].dval; 669 ar->ar_vreg = sc->sc_regdata[i].vreg; 670 ar->ar_vmask = sc->sc_regdata[i].vmask; 671 ar->ar_base = sc->sc_regdata[i].base; 672 ar->ar_delta = sc->sc_regdata[i].delta; 673 674 ar->ar_rd.rd_node = node; 675 ar->ar_rd.rd_cookie = ar; 676 ar->ar_rd.rd_get_voltage = axppmic_get_voltage; 677 ar->ar_rd.rd_set_voltage = axppmic_set_voltage; 678 ar->ar_rd.rd_enable = axppmic_enable; 679 regulator_register(&ar->ar_rd); 680 } 681 682 uint32_t 683 axppmic_get_voltage(void *cookie) 684 { 685 struct axppmic_regulator *ar = cookie; 686 uint32_t voltage; 687 uint8_t value; 688 689 value = axppmic_read_reg(ar->ar_sc, ar->ar_vreg); 690 value &= ar->ar_vmask; 691 voltage = ar->ar_base + value * ar->ar_delta; 692 if (ar->ar_base2 > 0 && voltage > ar->ar_base2) { 693 value -= (ar->ar_base2 - ar->ar_base) / ar->ar_delta; 694 voltage = ar->ar_base2 + value * ar->ar_delta2; 695 } 696 return voltage; 697 } 698 699 int 700 axppmic_set_voltage(void *cookie, uint32_t voltage) 701 { 702 struct axppmic_regulator *ar = cookie; 703 uint32_t value, reg; 704 705 if (voltage < ar->ar_base) 706 return EINVAL; 707 value = (voltage - ar->ar_base) / ar->ar_delta; 708 if (ar->ar_base2 > 0 && voltage > ar->ar_base2) { 709 value = (ar->ar_base2 - ar->ar_base) / ar->ar_delta; 710 value += (voltage - ar->ar_base2) / ar->ar_delta2; 711 } 712 if (value > ar->ar_vmask) 713 return EINVAL; 714 715 reg = axppmic_read_reg(ar->ar_sc, ar->ar_vreg); 716 reg &= ~ar->ar_vmask; 717 axppmic_write_reg(ar->ar_sc, ar->ar_vreg, reg | value); 718 return 0; 719 } 720 721 int 722 axppmic_enable(void *cookie, int on) 723 { 724 struct axppmic_regulator *ar = cookie; 725 uint8_t reg; 726 727 reg = axppmic_read_reg(ar->ar_sc, ar->ar_ereg); 728 reg &= ~ar->ar_emask; 729 if (on) 730 reg |= ar->ar_eval; 731 else 732 reg |= ar->ar_dval; 733 axppmic_write_reg(ar->ar_sc, ar->ar_ereg, reg); 734 return 0; 735 } 736 737 /* Sensors */ 738 739 void axppmic_update_sensors(void *); 740 void axppmic_update_indicator(struct axppmic_softc *, int); 741 void axppmic_update_percent(struct axppmic_softc *, int); 742 void axppmic_update_amphour(struct axppmic_softc *, int); 743 void axppmic_update_sensor(struct axppmic_softc *, int); 744 745 void 746 axppmic_attach_sensors(struct axppmic_softc *sc) 747 { 748 int i; 749 750 for (i = 0; sc->sc_sensdata[i].name; i++) { 751 KASSERT(i < AXPPMIC_NSENSORS); 752 753 sc->sc_sensor[i].type = sc->sc_sensdata[i].type; 754 strlcpy(sc->sc_sensor[i].desc, sc->sc_sensdata[i].name, 755 sizeof(sc->sc_sensor[i].desc)); 756 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); 757 } 758 759 axppmic_update_sensors(sc); 760 if (sensor_task_register(sc, axppmic_update_sensors, 5) == NULL) { 761 printf(", unable to register update task\n"); 762 return; 763 } 764 765 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 766 sizeof(sc->sc_sensordev.xname)); 767 sensordev_install(&sc->sc_sensordev); 768 } 769 770 void 771 axppmic_update_sensors(void *arg) 772 { 773 struct axppmic_softc *sc = arg; 774 int i; 775 776 for (i = 0; sc->sc_sensdata[i].name; i++) { 777 switch (sc->sc_sensdata[i].type) { 778 case SENSOR_INDICATOR: 779 axppmic_update_indicator(sc, i); 780 break; 781 case SENSOR_PERCENT: 782 axppmic_update_percent(sc, i); 783 break; 784 case SENSOR_AMPHOUR: 785 axppmic_update_amphour(sc, i); 786 break; 787 default: 788 axppmic_update_sensor(sc, i); 789 break; 790 } 791 } 792 } 793 794 void 795 axppmic_update_indicator(struct axppmic_softc *sc, int i) 796 { 797 uint8_t reg = sc->sc_sensdata[i].reg; 798 uint8_t mask = sc->sc_sensdata[i].base; 799 uint8_t mask_ok = sc->sc_sensdata[i].delta; 800 uint8_t value; 801 802 value = axppmic_read_reg(sc, reg); 803 sc->sc_sensor[i].value = (value & mask) ? 1 : 0; 804 if (value & mask) { 805 sc->sc_sensor[i].status = 806 (value & mask_ok) ? SENSOR_S_OK : SENSOR_S_WARN; 807 } else { 808 sc->sc_sensor[i].status = SENSOR_S_UNSPEC; 809 } 810 } 811 812 void 813 axppmic_update_percent(struct axppmic_softc *sc, int i) 814 { 815 uint8_t reg = sc->sc_sensdata[i].reg; 816 uint8_t mask = sc->sc_sensdata[i].base; 817 uint8_t mask_ok = sc->sc_sensdata[i].delta; 818 uint8_t value; 819 820 value = axppmic_read_reg(sc, reg); 821 sc->sc_sensor[i].value = (value & mask) * 1000; 822 823 if (value & mask_ok) { 824 if ((value & mask) <= sc->sc_crit) 825 sc->sc_sensor[i].status = SENSOR_S_CRIT; 826 else if ((value & mask) <= sc->sc_warn) 827 sc->sc_sensor[i].status = SENSOR_S_WARN; 828 else 829 sc->sc_sensor[i].status = SENSOR_S_OK; 830 } else { 831 sc->sc_sensor[i].status = SENSOR_S_UNSPEC; 832 } 833 } 834 835 void 836 axppmic_update_amphour(struct axppmic_softc *sc, int i) 837 { 838 uint8_t reg = sc->sc_sensdata[i].reg; 839 uint64_t base = sc->sc_sensdata[i].base; 840 uint64_t delta = sc->sc_sensdata[i].delta; 841 uint16_t value; 842 843 value = axppmic_read_reg(sc, reg); 844 sc->sc_sensor[i].status = (value & 0x80) ? SENSOR_S_OK : SENSOR_S_WARN; 845 value = ((value & 0x7f) << 8) | axppmic_read_reg(sc, reg + 1); 846 sc->sc_sensor[i].value = base + value * delta; 847 } 848 849 void 850 axppmic_update_sensor(struct axppmic_softc *sc, int i) 851 { 852 uint8_t reg = sc->sc_sensdata[i].reg; 853 uint64_t base = sc->sc_sensdata[i].base; 854 uint64_t delta = sc->sc_sensdata[i].delta; 855 uint16_t value; 856 857 value = axppmic_read_reg(sc, reg); 858 value = (value << 4) | axppmic_read_reg(sc, reg + 1); 859 sc->sc_sensor[i].value = base + value * delta; 860 } 861 862 void 863 axp209_powerdown(void) 864 { 865 axppmic_write_reg(axppmic_sc, AXP209_SDR, AXP209_SDR_SHUTDOWN); 866 } 867