1 /* $OpenBSD: axppmic.c,v 1.9 2020/01/23 10:01:41 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_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,axp806", "AXP806", axp806_regdata }, 297 { "x-powers,axp809", "AXP809", axp809_regdata, axp221_sensdata } 298 }; 299 300 const struct axppmic_device * 301 axppmic_lookup(const char *name) 302 { 303 int i; 304 305 for (i = 0; i < nitems(axppmic_devices); i++) { 306 if (strcmp(name, axppmic_devices[i].name) == 0) 307 return &axppmic_devices[i]; 308 } 309 310 return NULL; 311 } 312 313 struct axppmic_softc { 314 struct device sc_dev; 315 void *sc_cookie; 316 uint16_t sc_addr; 317 318 uint8_t (*sc_read)(struct axppmic_softc *, uint8_t); 319 void (*sc_write)(struct axppmic_softc *, uint8_t, uint8_t); 320 struct axppmic_regdata *sc_regdata; 321 struct axppmic_sensdata *sc_sensdata; 322 323 struct ksensor sc_sensor[AXPPMIC_NSENSORS]; 324 struct ksensordev sc_sensordev; 325 326 uint8_t sc_warn; 327 uint8_t sc_crit; 328 }; 329 330 inline uint8_t 331 axppmic_read_reg(struct axppmic_softc *sc, uint8_t reg) 332 { 333 return sc->sc_read(sc, reg); 334 } 335 336 inline void 337 axppmic_write_reg(struct axppmic_softc *sc, uint8_t reg, uint8_t value) 338 { 339 sc->sc_write(sc, reg, value); 340 } 341 342 void axppmic_attach_common(struct axppmic_softc *, const char *, int); 343 344 /* I2C interface */ 345 346 int axppmic_i2c_match(struct device *, void *, void *); 347 void axppmic_i2c_attach(struct device *, struct device *, void *); 348 349 struct cfattach axppmic_ca = { 350 sizeof(struct axppmic_softc), axppmic_i2c_match, axppmic_i2c_attach 351 }; 352 353 struct cfdriver axppmic_cd = { 354 NULL, "axppmic", DV_DULL 355 }; 356 357 uint8_t axppmic_i2c_read(struct axppmic_softc *, uint8_t); 358 void axppmic_i2c_write(struct axppmic_softc *, uint8_t, uint8_t); 359 360 int 361 axppmic_i2c_match(struct device *parent, void *match, void *aux) 362 { 363 struct i2c_attach_args *ia = aux; 364 365 if (axppmic_lookup(ia->ia_name)) 366 return 1; 367 return 0; 368 } 369 370 void 371 axppmic_i2c_attach(struct device *parent, struct device *self, void *aux) 372 { 373 struct axppmic_softc *sc = (struct axppmic_softc *)self; 374 struct i2c_attach_args *ia = aux; 375 int node = *(int *)ia->ia_cookie; 376 377 sc->sc_cookie = ia->ia_tag; 378 sc->sc_addr = ia->ia_addr; 379 sc->sc_read = axppmic_i2c_read; 380 sc->sc_write = axppmic_i2c_write; 381 382 axppmic_attach_common(sc, ia->ia_name, node); 383 } 384 385 uint8_t 386 axppmic_i2c_read(struct axppmic_softc *sc, uint8_t reg) 387 { 388 i2c_tag_t tag = sc->sc_cookie; 389 int flags = cold ? I2C_F_POLL : 0; 390 int error; 391 uint8_t value; 392 393 iic_acquire_bus(tag, flags); 394 error = iic_smbus_read_byte(tag, sc->sc_addr, reg, &value, flags); 395 iic_release_bus(tag, flags); 396 if (error) { 397 printf("%s: SMBus read byte from 0x%02x failed\n", 398 sc->sc_dev.dv_xname, reg); 399 return 0xff; 400 } 401 402 return value; 403 } 404 405 void 406 axppmic_i2c_write(struct axppmic_softc *sc, uint8_t reg, uint8_t value) 407 { 408 i2c_tag_t tag = sc->sc_cookie; 409 int flags = cold ? I2C_F_POLL : 0; 410 int error; 411 412 iic_acquire_bus(tag, flags); 413 error = iic_smbus_write_byte(tag, sc->sc_addr, reg, value, flags); 414 iic_release_bus(tag, flags); 415 if (error) 416 printf("%s: SMBus write byte to 0x%02x failed\n", 417 sc->sc_dev.dv_xname, reg); 418 } 419 420 /* RSB interface */ 421 422 int axppmic_rsb_match(struct device *, void *, void *); 423 void axppmic_rsb_attach(struct device *, struct device *, void *); 424 425 struct cfattach axppmic_rsb_ca = { 426 sizeof(struct axppmic_softc), axppmic_rsb_match, axppmic_rsb_attach 427 }; 428 429 struct cfdriver axppmic_rsb_cd = { 430 NULL, "axppmic", DV_DULL 431 }; 432 433 uint8_t axppmic_rsb_read(struct axppmic_softc *, uint8_t); 434 void axppmic_rsb_write(struct axppmic_softc *, uint8_t, uint8_t); 435 436 int 437 axppmic_rsb_match(struct device *parent, void *match, void *aux) 438 { 439 struct rsb_attach_args *ra = aux; 440 441 if (axppmic_lookup(ra->ra_name)) 442 return 1; 443 return 0; 444 } 445 446 void 447 axppmic_rsb_attach(struct device *parent, struct device *self, void *aux) 448 { 449 struct axppmic_softc *sc = (struct axppmic_softc *)self; 450 struct rsb_attach_args *ra = aux; 451 452 sc->sc_cookie = ra->ra_cookie; 453 sc->sc_addr = ra->ra_rta; 454 sc->sc_read = axppmic_rsb_read; 455 sc->sc_write = axppmic_rsb_write; 456 457 axppmic_attach_common(sc, ra->ra_name, ra->ra_node); 458 } 459 460 uint8_t 461 axppmic_rsb_read(struct axppmic_softc *sc, uint8_t reg) 462 { 463 return rsb_read_1(sc->sc_cookie, sc->sc_addr, reg); 464 } 465 466 void 467 axppmic_rsb_write(struct axppmic_softc *sc, uint8_t reg, uint8_t value) 468 { 469 rsb_write_1(sc->sc_cookie, sc->sc_addr, reg, value); 470 } 471 472 /* Common code */ 473 474 void axppmic_attach_node(struct axppmic_softc *, int); 475 void axppmic_attach_regulators(struct axppmic_softc *, int); 476 void axppmic_attach_sensors(struct axppmic_softc *); 477 478 struct axppmic_softc *axppmic_sc; 479 void axp209_powerdown(void); 480 481 void 482 axppmic_attach_common(struct axppmic_softc *sc, const char *name, int node) 483 { 484 const struct axppmic_device *device; 485 int child; 486 487 device = axppmic_lookup(name); 488 printf(": %s\n", device->chip); 489 490 sc->sc_regdata = device->regdata; 491 sc->sc_sensdata = device->sensdata; 492 493 /* Switch AXP806 into master or slave mode. */ 494 if (strcmp(name, "x-powers,axp806") == 0) { 495 if (OF_getproplen(node, "x-powers,master-mode") == 0) { 496 axppmic_write_reg(sc, AXP806_REG_ADDR_EXT, 497 AXP806_REG_ADDR_EXT_MASTER_MODE); 498 } else { 499 axppmic_write_reg(sc, AXP806_REG_ADDR_EXT, 500 AXP806_REG_ADDR_EXT_SLAVE_MODE); 501 } 502 } 503 504 /* Enable data collecton on AXP209. */ 505 if (strcmp(name, "x-powers,axp209") == 0) { 506 uint8_t reg; 507 508 /* Turn on sampling of ACIN and VBUS voltage and current. */ 509 reg = axppmic_read_reg(sc, AXP209_ADC_EN1); 510 reg |= AXP209_ADC_EN1_ACIN; 511 reg |= AXP209_ADC_EN1_VBUS; 512 axppmic_write_reg(sc, AXP209_ADC_EN1, reg); 513 } 514 515 /* Read battery warning levels on AXP803. */ 516 if (strcmp(name, "x-powers,axp803") == 0) { 517 uint8_t value; 518 519 value = axppmic_read_reg(sc, AXP803_BAT_CAP_WARN); 520 sc->sc_warn = ((value & AXP803_BAT_CAP_WARN_LV1) >> 4); 521 sc->sc_warn += AXP803_BAT_CAP_WARN_LV1BASE; 522 sc->sc_crit = (value & AXP803_BAT_CAP_WARN_LV2); 523 } 524 525 for (child = OF_child(node); child; child = OF_peer(child)) 526 axppmic_attach_node(sc, child); 527 528 if (sc->sc_regdata) 529 axppmic_attach_regulators(sc, node); 530 531 if (sc->sc_sensdata) 532 axppmic_attach_sensors(sc); 533 534 #ifdef __armv7__ 535 if (strcmp(name, "x-powers,axp152") == 0 || 536 strcmp(name, "x-powers,axp209") == 0) { 537 axppmic_sc = sc; 538 powerdownfn = axp209_powerdown; 539 } 540 #endif 541 } 542 543 void 544 axppmic_attach_node(struct axppmic_softc *sc, int node) 545 { 546 char status[32]; 547 548 if (OF_getprop(node, "status", status, sizeof(status)) > 0 && 549 strcmp(status, "disabled") == 0) 550 return; 551 552 if (OF_is_compatible(node, "x-powers,axp803-battery-power-supply")) 553 sc->sc_sensdata = axp803_battery_sensdata; 554 } 555 556 /* Regulators */ 557 558 struct axppmic_regulator { 559 struct axppmic_softc *ar_sc; 560 561 uint8_t ar_ereg, ar_emask; 562 uint8_t ar_eval, ar_dval; 563 564 uint8_t ar_vreg, ar_vmask; 565 uint32_t ar_base, ar_delta; 566 uint32_t ar_base2, ar_delta2; 567 568 struct regulator_device ar_rd; 569 }; 570 571 void axppmic_attach_regulator(struct axppmic_softc *, int); 572 uint32_t axppmic_get_voltage(void *); 573 int axppmic_set_voltage(void *, uint32_t); 574 int axppmic_enable(void *, int); 575 576 void 577 axppmic_attach_regulators(struct axppmic_softc *sc, int node) 578 { 579 node = OF_getnodebyname(node, "regulators"); 580 if (node == 0) 581 return; 582 583 for (node = OF_child(node); node; node = OF_peer(node)) 584 axppmic_attach_regulator(sc, node); 585 } 586 587 void 588 axppmic_attach_regulator(struct axppmic_softc *sc, int node) 589 { 590 struct axppmic_regulator *ar; 591 char name[32]; 592 int i; 593 594 name[0] = 0; 595 OF_getprop(node, "name", name, sizeof(name)); 596 name[sizeof(name) - 1] = 0; 597 for (i = 0; sc->sc_regdata[i].name; i++) { 598 if (strcmp(sc->sc_regdata[i].name, name) == 0) 599 break; 600 } 601 if (sc->sc_regdata[i].name == NULL) 602 return; 603 604 ar = malloc(sizeof(*ar), M_DEVBUF, M_WAITOK | M_ZERO); 605 ar->ar_sc = sc; 606 607 ar->ar_ereg = sc->sc_regdata[i].ereg; 608 ar->ar_emask = sc->sc_regdata[i].emask; 609 ar->ar_eval = sc->sc_regdata[i].eval; 610 ar->ar_dval = sc->sc_regdata[i].dval; 611 ar->ar_vreg = sc->sc_regdata[i].vreg; 612 ar->ar_vmask = sc->sc_regdata[i].vmask; 613 ar->ar_base = sc->sc_regdata[i].base; 614 ar->ar_delta = sc->sc_regdata[i].delta; 615 616 ar->ar_rd.rd_node = node; 617 ar->ar_rd.rd_cookie = ar; 618 ar->ar_rd.rd_get_voltage = axppmic_get_voltage; 619 ar->ar_rd.rd_set_voltage = axppmic_set_voltage; 620 ar->ar_rd.rd_enable = axppmic_enable; 621 regulator_register(&ar->ar_rd); 622 } 623 624 uint32_t 625 axppmic_get_voltage(void *cookie) 626 { 627 struct axppmic_regulator *ar = cookie; 628 uint32_t voltage; 629 uint8_t value; 630 631 value = axppmic_read_reg(ar->ar_sc, ar->ar_vreg); 632 value &= ar->ar_vmask; 633 voltage = ar->ar_base + value * ar->ar_delta; 634 if (ar->ar_base2 > 0 && voltage > ar->ar_base2) { 635 value -= (ar->ar_base2 - ar->ar_base) / ar->ar_delta; 636 voltage = ar->ar_base2 + value * ar->ar_delta2; 637 } 638 return voltage; 639 } 640 641 int 642 axppmic_set_voltage(void *cookie, uint32_t voltage) 643 { 644 struct axppmic_regulator *ar = cookie; 645 uint32_t value, reg; 646 647 if (voltage < ar->ar_base) 648 return EINVAL; 649 value = (voltage - ar->ar_base) / ar->ar_delta; 650 if (ar->ar_base2 > 0 && voltage > ar->ar_base2) { 651 value = (ar->ar_base2 - ar->ar_base) / ar->ar_delta; 652 value += (voltage - ar->ar_base2) / ar->ar_delta2; 653 } 654 if (value > ar->ar_vmask) 655 return EINVAL; 656 657 reg = axppmic_read_reg(ar->ar_sc, ar->ar_vreg); 658 reg &= ~ar->ar_vmask; 659 axppmic_write_reg(ar->ar_sc, ar->ar_vreg, reg | value); 660 return 0; 661 } 662 663 int 664 axppmic_enable(void *cookie, int on) 665 { 666 struct axppmic_regulator *ar = cookie; 667 uint8_t reg; 668 669 reg = axppmic_read_reg(ar->ar_sc, ar->ar_ereg); 670 reg &= ~ar->ar_emask; 671 if (on) 672 reg |= ar->ar_eval; 673 else 674 reg |= ar->ar_dval; 675 axppmic_write_reg(ar->ar_sc, ar->ar_ereg, reg); 676 return 0; 677 } 678 679 /* Sensors */ 680 681 void axppmic_update_sensors(void *); 682 void axppmic_update_indicator(struct axppmic_softc *, int); 683 void axppmic_update_percent(struct axppmic_softc *, int); 684 void axppmic_update_amphour(struct axppmic_softc *, int); 685 void axppmic_update_sensor(struct axppmic_softc *, int); 686 687 void 688 axppmic_attach_sensors(struct axppmic_softc *sc) 689 { 690 int i; 691 692 for (i = 0; sc->sc_sensdata[i].name; i++) { 693 KASSERT(i < AXPPMIC_NSENSORS); 694 695 sc->sc_sensor[i].type = sc->sc_sensdata[i].type; 696 strlcpy(sc->sc_sensor[i].desc, sc->sc_sensdata[i].name, 697 sizeof(sc->sc_sensor[i].desc)); 698 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); 699 } 700 701 axppmic_update_sensors(sc); 702 if (sensor_task_register(sc, axppmic_update_sensors, 5) == NULL) { 703 printf(", unable to register update task\n"); 704 return; 705 } 706 707 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 708 sizeof(sc->sc_sensordev.xname)); 709 sensordev_install(&sc->sc_sensordev); 710 } 711 712 void 713 axppmic_update_sensors(void *arg) 714 { 715 struct axppmic_softc *sc = arg; 716 int i; 717 718 for (i = 0; sc->sc_sensdata[i].name; i++) { 719 switch (sc->sc_sensdata[i].type) { 720 case SENSOR_INDICATOR: 721 axppmic_update_indicator(sc, i); 722 break; 723 case SENSOR_PERCENT: 724 axppmic_update_percent(sc, i); 725 break; 726 case SENSOR_AMPHOUR: 727 axppmic_update_amphour(sc, i); 728 break; 729 default: 730 axppmic_update_sensor(sc, i); 731 break; 732 } 733 } 734 } 735 736 void 737 axppmic_update_indicator(struct axppmic_softc *sc, int i) 738 { 739 uint8_t reg = sc->sc_sensdata[i].reg; 740 uint8_t mask = sc->sc_sensdata[i].base; 741 uint8_t mask_ok = sc->sc_sensdata[i].delta; 742 uint8_t value; 743 744 value = axppmic_read_reg(sc, reg); 745 sc->sc_sensor[i].value = (value & mask) ? 1 : 0; 746 if (value & mask) { 747 sc->sc_sensor[i].status = 748 (value & mask_ok) ? SENSOR_S_OK : SENSOR_S_WARN; 749 } else { 750 sc->sc_sensor[i].status = SENSOR_S_UNSPEC; 751 } 752 } 753 754 void 755 axppmic_update_percent(struct axppmic_softc *sc, int i) 756 { 757 uint8_t reg = sc->sc_sensdata[i].reg; 758 uint8_t mask = sc->sc_sensdata[i].base; 759 uint8_t mask_ok = sc->sc_sensdata[i].delta; 760 uint8_t value; 761 762 value = axppmic_read_reg(sc, reg); 763 sc->sc_sensor[i].value = (value & mask) * 1000; 764 765 if (value & mask_ok) { 766 if ((value & mask) <= sc->sc_crit) 767 sc->sc_sensor[i].status = SENSOR_S_CRIT; 768 else if ((value & mask) <= sc->sc_warn) 769 sc->sc_sensor[i].status = SENSOR_S_WARN; 770 else 771 sc->sc_sensor[i].status = SENSOR_S_OK; 772 } else { 773 sc->sc_sensor[i].status = SENSOR_S_UNSPEC; 774 } 775 } 776 777 void 778 axppmic_update_amphour(struct axppmic_softc *sc, int i) 779 { 780 uint8_t reg = sc->sc_sensdata[i].reg; 781 uint64_t base = sc->sc_sensdata[i].base; 782 uint64_t delta = sc->sc_sensdata[i].delta; 783 uint16_t value; 784 785 value = axppmic_read_reg(sc, reg); 786 sc->sc_sensor[i].status = (value & 0x80) ? SENSOR_S_OK : SENSOR_S_WARN; 787 value = ((value & 0x7f) << 8) | axppmic_read_reg(sc, reg + 1); 788 sc->sc_sensor[i].value = base + value * delta; 789 } 790 791 void 792 axppmic_update_sensor(struct axppmic_softc *sc, int i) 793 { 794 uint8_t reg = sc->sc_sensdata[i].reg; 795 uint64_t base = sc->sc_sensdata[i].base; 796 uint64_t delta = sc->sc_sensdata[i].delta; 797 uint16_t value; 798 799 value = axppmic_read_reg(sc, reg); 800 value = (value << 4) | axppmic_read_reg(sc, reg + 1); 801 sc->sc_sensor[i].value = base + value * delta; 802 } 803 804 void 805 axp209_powerdown(void) 806 { 807 axppmic_write_reg(axppmic_sc, AXP209_SDR, AXP209_SDR_SHUTDOWN); 808 } 809