1 /* $OpenBSD: axppmic.c,v 1.20 2023/08/02 11:52:18 uaa 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 struct cfdriver axppmic_rsb_cd = { 518 NULL, "axppmic", DV_DULL 519 }; 520 521 uint8_t axppmic_rsb_read(struct axppmic_softc *, uint8_t); 522 void axppmic_rsb_write(struct axppmic_softc *, uint8_t, uint8_t); 523 524 int 525 axppmic_rsb_match(struct device *parent, void *match, void *aux) 526 { 527 struct rsb_attach_args *ra = aux; 528 529 if (axppmic_lookup(ra->ra_name)) 530 return 1; 531 return 0; 532 } 533 534 void 535 axppmic_rsb_attach(struct device *parent, struct device *self, void *aux) 536 { 537 struct axppmic_softc *sc = (struct axppmic_softc *)self; 538 struct rsb_attach_args *ra = aux; 539 540 sc->sc_cookie = ra->ra_cookie; 541 sc->sc_addr = ra->ra_rta; 542 sc->sc_read = axppmic_rsb_read; 543 sc->sc_write = axppmic_rsb_write; 544 545 axppmic_attach_common(sc, ra->ra_name, ra->ra_node); 546 } 547 548 uint8_t 549 axppmic_rsb_read(struct axppmic_softc *sc, uint8_t reg) 550 { 551 return rsb_read_1(sc->sc_cookie, sc->sc_addr, reg); 552 } 553 554 void 555 axppmic_rsb_write(struct axppmic_softc *sc, uint8_t reg, uint8_t value) 556 { 557 rsb_write_1(sc->sc_cookie, sc->sc_addr, reg, value); 558 } 559 560 #endif 561 562 /* Common code */ 563 564 void axppmic_attach_node(struct axppmic_softc *, int); 565 void axppmic_attach_regulators(struct axppmic_softc *, int); 566 void axppmic_attach_sensors(struct axppmic_softc *); 567 568 struct axppmic_softc *axppmic_sc; 569 void axp209_powerdown(void); 570 571 void 572 axppmic_attach_common(struct axppmic_softc *sc, const char *name, int node) 573 { 574 const struct axppmic_device *device; 575 int child; 576 577 device = axppmic_lookup(name); 578 printf(": %s\n", device->chip); 579 580 sc->sc_name = device->name; 581 sc->sc_regdata = device->regdata; 582 sc->sc_sensdata = device->sensdata; 583 584 /* Switch AXP806 into master or slave mode. */ 585 if (strcmp(name, "x-powers,axp305") == 0 || 586 strcmp(name, "x-powers,axp805") == 0 || 587 strcmp(name, "x-powers,axp806") == 0) { 588 if (OF_getproplen(node, "x-powers,master-mode") == 0 || 589 OF_getproplen(node, "x-powers,self-working-mode") == 0) { 590 axppmic_write_reg(sc, AXP806_REG_ADDR_EXT, 591 AXP806_REG_ADDR_EXT_MASTER_MODE); 592 } else { 593 axppmic_write_reg(sc, AXP806_REG_ADDR_EXT, 594 AXP806_REG_ADDR_EXT_SLAVE_MODE); 595 } 596 } 597 598 /* Enable data collection on AXP209. */ 599 if (strcmp(name, "x-powers,axp209") == 0) { 600 uint8_t reg; 601 602 /* Turn on sampling of ACIN and VBUS voltage and current. */ 603 reg = axppmic_read_reg(sc, AXP209_ADC_EN1); 604 reg |= AXP209_ADC_EN1_ACIN; 605 reg |= AXP209_ADC_EN1_VBUS; 606 axppmic_write_reg(sc, AXP209_ADC_EN1, reg); 607 } 608 609 /* Read battery warning levels on AXP803. */ 610 if (strcmp(name, "x-powers,axp803") == 0) { 611 uint8_t value; 612 613 value = axppmic_read_reg(sc, AXP803_BAT_CAP_WARN); 614 sc->sc_warn = ((value & AXP803_BAT_CAP_WARN_LV1) >> 4); 615 sc->sc_warn += AXP803_BAT_CAP_WARN_LV1BASE; 616 sc->sc_crit = (value & AXP803_BAT_CAP_WARN_LV2); 617 } 618 619 for (child = OF_child(node); child; child = OF_peer(child)) 620 axppmic_attach_node(sc, child); 621 622 if (sc->sc_regdata) 623 axppmic_attach_regulators(sc, node); 624 625 if (sc->sc_sensdata) 626 axppmic_attach_sensors(sc); 627 628 /* Disable all interrupts on AXP803. */ 629 if (strcmp(name, "x-powers,axp803") == 0) { 630 axppmic_write_reg(sc, AXP803_IRQ1_EN, 0); 631 axppmic_write_reg(sc, AXP803_IRQ2_EN, 0); 632 axppmic_write_reg(sc, AXP803_IRQ3_EN, 0); 633 axppmic_write_reg(sc, AXP803_IRQ4_EN, 0); 634 axppmic_write_reg(sc, AXP803_IRQ5_EN, 0); 635 axppmic_write_reg(sc, AXP803_IRQ6_EN, 0); 636 } 637 638 #ifdef __armv7__ 639 if (strcmp(name, "x-powers,axp152") == 0 || 640 strcmp(name, "x-powers,axp209") == 0) { 641 axppmic_sc = sc; 642 powerdownfn = axp209_powerdown; 643 } 644 #endif 645 646 #ifdef SUSPEND 647 /* AXP803 can wake us up. */ 648 if (strcmp(name, "x-powers,axp803") == 0) 649 device_register_wakeup(&sc->sc_dev); 650 #endif 651 } 652 653 void 654 axppmic_attach_node(struct axppmic_softc *sc, int node) 655 { 656 char status[32]; 657 658 if (OF_getprop(node, "status", status, sizeof(status)) > 0 && 659 strcmp(status, "disabled") == 0) 660 return; 661 662 if (OF_is_compatible(node, "x-powers,axp803-battery-power-supply")) 663 sc->sc_sensdata = axp803_battery_sensdata; 664 } 665 666 int 667 axppmic_activate(struct device *self, int act) 668 { 669 struct axppmic_softc *sc = (struct axppmic_softc *)self; 670 671 switch (act) { 672 case DVACT_SUSPEND: 673 if (strcmp(sc->sc_name, "x-powers,axp803") == 0) { 674 /* Enable interrupt for short power button press. */ 675 axppmic_write_reg(sc, AXP803_IRQ5_STAT, 676 AXP803_IRQ5_STAT_PEK_SHORT); 677 axppmic_write_reg(sc, AXP803_IRQ5_EN, 678 AXP803_IRQ5_EN_PEK_SHORT); 679 } 680 break; 681 case DVACT_RESUME: 682 if (strcmp(sc->sc_name, "x-powers,axp803") == 0) { 683 /* Disable interrupt for short power button press. */ 684 axppmic_write_reg(sc, AXP803_IRQ5_EN, 0); 685 } 686 break; 687 } 688 689 return 0; 690 } 691 692 /* Regulators */ 693 694 struct axppmic_regulator { 695 struct axppmic_softc *ar_sc; 696 697 uint8_t ar_ereg, ar_emask; 698 uint8_t ar_eval, ar_dval; 699 700 uint8_t ar_vreg, ar_vmask; 701 uint32_t ar_base, ar_delta, ar_nsteps; 702 uint32_t ar_base2, ar_delta2, ar_nsteps2; 703 704 struct regulator_device ar_rd; 705 }; 706 707 void axppmic_attach_regulator(struct axppmic_softc *, int); 708 uint32_t axppmic_get_voltage(void *); 709 int axppmic_set_voltage(void *, uint32_t); 710 int axppmic_enable(void *, int); 711 712 void 713 axppmic_attach_regulators(struct axppmic_softc *sc, int node) 714 { 715 node = OF_getnodebyname(node, "regulators"); 716 if (node == 0) 717 return; 718 719 for (node = OF_child(node); node; node = OF_peer(node)) 720 axppmic_attach_regulator(sc, node); 721 } 722 723 void 724 axppmic_attach_regulator(struct axppmic_softc *sc, int node) 725 { 726 struct axppmic_regulator *ar; 727 char name[32]; 728 int i; 729 730 name[0] = 0; 731 OF_getprop(node, "name", name, sizeof(name)); 732 name[sizeof(name) - 1] = 0; 733 for (i = 0; sc->sc_regdata[i].name; i++) { 734 if (strcmp(sc->sc_regdata[i].name, name) == 0) 735 break; 736 } 737 if (sc->sc_regdata[i].name == NULL) 738 return; 739 740 ar = malloc(sizeof(*ar), M_DEVBUF, M_WAITOK | M_ZERO); 741 ar->ar_sc = sc; 742 743 ar->ar_ereg = sc->sc_regdata[i].ereg; 744 ar->ar_emask = sc->sc_regdata[i].emask; 745 ar->ar_eval = sc->sc_regdata[i].eval; 746 ar->ar_dval = sc->sc_regdata[i].dval; 747 ar->ar_vreg = sc->sc_regdata[i].vreg; 748 ar->ar_vmask = sc->sc_regdata[i].vmask; 749 ar->ar_base = sc->sc_regdata[i].base; 750 ar->ar_delta = sc->sc_regdata[i].delta; 751 ar->ar_nsteps = sc->sc_regdata[i].nsteps; 752 ar->ar_base2 = sc->sc_regdata[i].base2; 753 ar->ar_delta2 = sc->sc_regdata[i].delta2; 754 ar->ar_nsteps2 = sc->sc_regdata[i].nsteps2; 755 756 ar->ar_rd.rd_node = node; 757 ar->ar_rd.rd_cookie = ar; 758 ar->ar_rd.rd_get_voltage = axppmic_get_voltage; 759 ar->ar_rd.rd_set_voltage = axppmic_set_voltage; 760 ar->ar_rd.rd_enable = axppmic_enable; 761 regulator_register(&ar->ar_rd); 762 } 763 764 uint32_t 765 axppmic_get_voltage(void *cookie) 766 { 767 struct axppmic_regulator *ar = cookie; 768 uint32_t voltage; 769 uint8_t value; 770 771 value = axppmic_read_reg(ar->ar_sc, ar->ar_vreg); 772 value &= ar->ar_vmask; 773 if (ar->ar_base2 > 0 && value >= ar->ar_nsteps) { 774 voltage = 775 ar->ar_base2 + (value - ar->ar_nsteps) * ar->ar_delta2; 776 } else { 777 voltage = ar->ar_base + value * ar->ar_delta; 778 } 779 return voltage; 780 } 781 782 int 783 axppmic_set_voltage(void *cookie, uint32_t voltage) 784 { 785 struct axppmic_regulator *ar = cookie; 786 uint32_t value, reg; 787 788 if (voltage < ar->ar_base) 789 return EINVAL; 790 if (ar->ar_base2 > 0 && voltage >= ar->ar_base2) { 791 value = (voltage - ar->ar_base2) / ar->ar_delta2; 792 if (value >= ar->ar_nsteps2) 793 return EINVAL; 794 value += ar->ar_nsteps; 795 } else { 796 value = (voltage - ar->ar_base) / ar->ar_delta; 797 if (value >= ar->ar_nsteps) 798 return EINVAL; 799 } 800 if (value > ar->ar_vmask) 801 return EINVAL; 802 803 reg = axppmic_read_reg(ar->ar_sc, ar->ar_vreg); 804 axppmic_write_reg(ar->ar_sc, ar->ar_vreg, 805 (reg & ~ar->ar_vmask) | (value & ar->ar_vmask)); 806 return 0; 807 } 808 809 int 810 axppmic_enable(void *cookie, int on) 811 { 812 struct axppmic_regulator *ar = cookie; 813 uint8_t reg; 814 815 reg = axppmic_read_reg(ar->ar_sc, ar->ar_ereg); 816 reg &= ~ar->ar_emask; 817 if (on) 818 reg |= ar->ar_eval; 819 else 820 reg |= ar->ar_dval; 821 axppmic_write_reg(ar->ar_sc, ar->ar_ereg, reg); 822 return 0; 823 } 824 825 /* Sensors */ 826 827 void axppmic_update_sensors(void *); 828 void axppmic_update_indicator(struct axppmic_softc *, int); 829 void axppmic_update_percent(struct axppmic_softc *, int); 830 void axppmic_update_amphour(struct axppmic_softc *, int); 831 void axppmic_update_sensor(struct axppmic_softc *, int); 832 833 void 834 axppmic_attach_sensors(struct axppmic_softc *sc) 835 { 836 int i; 837 838 for (i = 0; sc->sc_sensdata[i].name; i++) { 839 KASSERT(i < AXPPMIC_NSENSORS); 840 841 sc->sc_sensor[i].type = sc->sc_sensdata[i].type; 842 strlcpy(sc->sc_sensor[i].desc, sc->sc_sensdata[i].name, 843 sizeof(sc->sc_sensor[i].desc)); 844 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); 845 } 846 847 axppmic_update_sensors(sc); 848 if (sensor_task_register(sc, axppmic_update_sensors, 5) == NULL) { 849 printf(", unable to register update task\n"); 850 return; 851 } 852 853 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 854 sizeof(sc->sc_sensordev.xname)); 855 sensordev_install(&sc->sc_sensordev); 856 } 857 858 void 859 axppmic_update_sensors(void *arg) 860 { 861 struct axppmic_softc *sc = arg; 862 int i; 863 864 for (i = 0; sc->sc_sensdata[i].name; i++) { 865 switch (sc->sc_sensdata[i].type) { 866 case SENSOR_INDICATOR: 867 axppmic_update_indicator(sc, i); 868 break; 869 case SENSOR_PERCENT: 870 axppmic_update_percent(sc, i); 871 break; 872 case SENSOR_AMPHOUR: 873 axppmic_update_amphour(sc, i); 874 break; 875 default: 876 axppmic_update_sensor(sc, i); 877 break; 878 } 879 } 880 } 881 882 void 883 axppmic_update_indicator(struct axppmic_softc *sc, int i) 884 { 885 uint8_t reg = sc->sc_sensdata[i].reg; 886 uint8_t mask = sc->sc_sensdata[i].base; 887 uint8_t mask_ok = sc->sc_sensdata[i].delta; 888 uint8_t value; 889 890 value = axppmic_read_reg(sc, reg); 891 sc->sc_sensor[i].value = (value & mask) ? 1 : 0; 892 if (value & mask) { 893 sc->sc_sensor[i].status = 894 (value & mask_ok) ? SENSOR_S_OK : SENSOR_S_WARN; 895 } else { 896 sc->sc_sensor[i].status = SENSOR_S_UNSPEC; 897 } 898 } 899 900 void 901 axppmic_update_percent(struct axppmic_softc *sc, int i) 902 { 903 uint8_t reg = sc->sc_sensdata[i].reg; 904 uint8_t mask = sc->sc_sensdata[i].base; 905 uint8_t mask_ok = sc->sc_sensdata[i].delta; 906 uint8_t value; 907 908 value = axppmic_read_reg(sc, reg); 909 sc->sc_sensor[i].value = (value & mask) * 1000; 910 911 if (value & mask_ok) { 912 if ((value & mask) <= sc->sc_crit) 913 sc->sc_sensor[i].status = SENSOR_S_CRIT; 914 else if ((value & mask) <= sc->sc_warn) 915 sc->sc_sensor[i].status = SENSOR_S_WARN; 916 else 917 sc->sc_sensor[i].status = SENSOR_S_OK; 918 } else { 919 sc->sc_sensor[i].status = SENSOR_S_UNSPEC; 920 } 921 } 922 923 void 924 axppmic_update_amphour(struct axppmic_softc *sc, int i) 925 { 926 uint8_t reg = sc->sc_sensdata[i].reg; 927 uint64_t base = sc->sc_sensdata[i].base; 928 uint64_t delta = sc->sc_sensdata[i].delta; 929 uint16_t value; 930 931 value = axppmic_read_reg(sc, reg); 932 sc->sc_sensor[i].status = (value & 0x80) ? SENSOR_S_OK : SENSOR_S_WARN; 933 value = ((value & 0x7f) << 8) | axppmic_read_reg(sc, reg + 1); 934 sc->sc_sensor[i].value = base + value * delta; 935 } 936 937 void 938 axppmic_update_sensor(struct axppmic_softc *sc, int i) 939 { 940 uint8_t reg = sc->sc_sensdata[i].reg; 941 uint64_t base = sc->sc_sensdata[i].base; 942 uint64_t delta = sc->sc_sensdata[i].delta; 943 uint16_t value; 944 945 value = axppmic_read_reg(sc, reg); 946 value = (value << 4) | axppmic_read_reg(sc, reg + 1); 947 sc->sc_sensor[i].value = base + value * delta; 948 } 949 950 void 951 axp209_powerdown(void) 952 { 953 axppmic_write_reg(axppmic_sc, AXP209_SDR, AXP209_SDR_SHUTDOWN); 954 } 955