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