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