1 /* $OpenBSD: rkpmic.c,v 1.18 2024/11/23 21:24:03 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/proc.h> 23 #include <sys/signalvar.h> 24 25 #include <machine/fdt.h> 26 27 #include <dev/ofw/openfirm.h> 28 #include <dev/ofw/ofw_regulator.h> 29 #include <dev/ofw/fdt.h> 30 31 #include <dev/i2c/i2cvar.h> 32 #include <dev/spi/spivar.h> 33 34 #include <dev/clock_subr.h> 35 36 extern void (*powerdownfn)(void); 37 38 #define RK80X_SECONDS 0x00 39 #define RK80X_MINUTES 0x01 40 #define RK80X_HOURS 0x02 41 #define RK80X_DAYS 0x03 42 #define RK80X_MONTHS 0x04 43 #define RK80X_YEARS 0x05 44 #define RK80X_WEEKS 0x06 45 #define RK80X_NRTC_REGS 7 46 47 #define RK805_RTC_CTRL 0x10 48 #define RK808_RTC_CTRL 0x10 49 #define RK809_RTC_CTRL 0x0d 50 #define RK80X_RTC_CTRL_STOP_RTC 0x01 51 52 #define RK805_RTC_STATUS 0x11 53 #define RK808_RTC_STATUS 0x11 54 #define RK809_RTC_STATUS 0x0e 55 #define RK80X_RTC_STATUS_POWER_UP 0x80 56 57 #define RK805_DEV_CTRL 0x4b 58 #define RK805_DEV_CTRL_DEV_OFF 0x01 59 60 #define RK806_SYS_CFG3 0x72 61 #define RK806_SYS_CFG3_DEV_OFF 0x01 62 63 #define RK808_DEVCTRL 0x4b 64 #define RK808_DEVCTRL_DEV_OFF_RST 0x08 65 66 #define RK809_PMIC_SYS_CFG3 0xf4 67 #define RK809_PMIC_SYS_CFG3_SLP_FUN_MASK 0x18 68 #define RK809_PMIC_SYS_CFG3_SLP_FUN_NONE 0x00 69 #define RK809_PMIC_SYS_CFG3_SLP_FUN_SLEEP 0x08 70 #define RK809_PMIC_SYS_CFG3_DEV_OFF 0x01 71 #define RK809_PMIC_INT_STS0 0xf8 72 #define RK809_PMIC_INT_MSK0 0xf9 73 #define RK809_PMIC_INT_MSK0_PWRON_FALL_INT_IM 0x01 74 #define RK809_PMIC_INT_STS1 0xfa 75 #define RK809_PMIC_INT_MSK1 0xfb 76 #define RK809_PMIC_INT_STS2 0xfc 77 #define RK809_PMIC_INT_MSK2 0xfd 78 #define RK809_PMIC_GPIO_INT_CONFIG 0xfe 79 #define RK809_PMIC_GPIO_INT_CONFIG_INT_POL 0x02 80 81 #define RKSPI_CMD_READ (0 << 7) 82 #define RKSPI_CMD_WRITE (1 << 7) 83 84 struct rkpmic_vsel_range { 85 uint32_t base, delta; 86 uint8_t vsel_min, vsel_max; 87 }; 88 89 struct rkpmic_regdata { 90 const char *name; 91 uint8_t vreg, vmask; 92 uint8_t sreg, smask; 93 const struct rkpmic_vsel_range *vsel_range; 94 }; 95 96 /* 97 * Used by RK805 for BUCK1, BUCK2 98 * 0-59: 0.7125V-1.45V, step=12.5mV 99 * 60-62: 1.8V-2.2V, step=200mV 100 * 63: 2.3V 101 */ 102 const struct rkpmic_vsel_range rk805_vsel_range1[] = { 103 { 712500, 12500, 0, 59 }, 104 { 1800000, 200000, 60, 62 }, 105 { 2300000, 0, 63, 63 }, 106 {} 107 }; 108 109 /* 110 * Used by RK805 for BUCK4 111 * 0-27: 0.8V-3.5V, step=100mV 112 */ 113 const struct rkpmic_vsel_range rk805_vsel_range2[] = { 114 { 800000, 100000, 0, 27 }, 115 {} 116 }; 117 118 /* 119 * Used by RK805 for LDO1-3 120 * 0-26: 0.8V-3.4V, step=100mV 121 */ 122 const struct rkpmic_vsel_range rk805_vsel_range3[] = { 123 { 800000, 100000, 0, 26 }, 124 {} 125 }; 126 127 const struct rkpmic_regdata rk805_regdata[] = { 128 { "DCDC_REG1", 0x2f, 0x3f, 0, 0, rk805_vsel_range1 }, 129 { "DCDC_REG2", 0x33, 0x3f, 0, 0, rk805_vsel_range1 }, 130 { "DCDC_REG4", 0x38, 0x1f, 0, 0, rk805_vsel_range2 }, 131 { "LDO_REG1", 0x3b, 0x1f, 0, 0, rk805_vsel_range3 }, 132 { "LDO_REG2", 0x3d, 0x1f, 0, 0, rk805_vsel_range3 }, 133 { "LDO_REG3", 0x3f, 0x1f, 0, 0, rk805_vsel_range3 }, 134 { } 135 }; 136 137 /* 138 * Used by RK806 for BUCK 139 * 0-159: 0.5V-1.5V, step=6.25mV 140 * 160-236: 1.5V-3.4V, step=25mV 141 * 237-255: 3.4V-3.4V, step=0mV 142 */ 143 const struct rkpmic_vsel_range rk806_vsel_range1[] = { 144 { 500000, 6250, 0, 159 }, 145 { 1500000, 25000, 160, 236 }, 146 { 3400000, 0, 237, 255 }, 147 {} 148 }; 149 150 /* 151 * Used by RK806 for LDO 152 * 0-232: 0.5V-3.4V, step=12.5mV 153 * 233-255: 3.4V-3.4V, step=0mV 154 */ 155 const struct rkpmic_vsel_range rk806_vsel_range2[] = { 156 { 500000, 12500, 0, 232 }, 157 { 3400000, 0, 233, 255 }, 158 {} 159 }; 160 161 const struct rkpmic_regdata rk806_regdata[] = { 162 { "dcdc-reg1", 0x1a, 0xff, 0, 0, rk806_vsel_range1 }, 163 { "dcdc-reg2", 0x1b, 0xff, 0, 0, rk806_vsel_range1 }, 164 { "dcdc-reg3", 0x1c, 0xff, 0, 0, rk806_vsel_range1 }, 165 { "dcdc-reg4", 0x1d, 0xff, 0, 0, rk806_vsel_range1 }, 166 { "dcdc-reg5", 0x1e, 0xff, 0, 0, rk806_vsel_range1 }, 167 { "dcdc-reg6", 0x1f, 0xff, 0, 0, rk806_vsel_range1 }, 168 { "dcdc-reg7", 0x20, 0xff, 0, 0, rk806_vsel_range1 }, 169 { "dcdc-reg8", 0x21, 0xff, 0, 0, rk806_vsel_range1 }, 170 { "dcdc-reg9", 0x22, 0xff, 0, 0, rk806_vsel_range1 }, 171 { "dcdc-reg10", 0x23, 0xff, 0, 0, rk806_vsel_range1 }, 172 { "nldo-reg1", 0x43, 0xff, 0, 0, rk806_vsel_range2 }, 173 { "nldo-reg2", 0x44, 0xff, 0, 0, rk806_vsel_range2 }, 174 { "nldo-reg3", 0x45, 0xff, 0, 0, rk806_vsel_range2 }, 175 { "nldo-reg4", 0x46, 0xff, 0, 0, rk806_vsel_range2 }, 176 { "nldo-reg5", 0x47, 0xff, 0, 0, rk806_vsel_range2 }, 177 { "pldo-reg1", 0x4e, 0xff, 0, 0, rk806_vsel_range2 }, 178 { "pldo-reg2", 0x4f, 0xff, 0, 0, rk806_vsel_range2 }, 179 { "pldo-reg3", 0x50, 0xff, 0, 0, rk806_vsel_range2 }, 180 { "pldo-reg4", 0x51, 0xff, 0, 0, rk806_vsel_range2 }, 181 { "pldo-reg5", 0x52, 0xff, 0, 0, rk806_vsel_range2 }, 182 { "pldo-reg6", 0x53, 0xff, 0, 0, rk806_vsel_range2 }, 183 { } 184 }; 185 186 /* 187 * Used by RK808 for BUCK1 & BUCK2 188 * 0-63: 0.7125V-1.5V, step=12.5mV 189 */ 190 const struct rkpmic_vsel_range rk808_vsel_range1[] = { 191 { 712500, 12500, 0, 63 }, 192 {} 193 }; 194 195 /* 196 * Used by RK808 for BUCK4 197 * 0-15: 1.8V-3.3V,step=100mV 198 */ 199 const struct rkpmic_vsel_range rk808_vsel_range2[] = { 200 { 1800000, 100000, 0, 15 }, 201 {} 202 }; 203 204 /* 205 * Used by RK808 for LDO1-2, 4-5, 8 206 * 0-16: 1.8V-3.4V, step=100mV 207 */ 208 const struct rkpmic_vsel_range rk808_vsel_range3[] = { 209 { 1800000, 100000, 0, 16 }, 210 {} 211 }; 212 213 /* 214 * Used by RK808 for LDO3 215 * 0-12: 0.8V~2.0V, step=100mV 216 * 13: 2.2V 217 * 15: 2.5V 218 */ 219 const struct rkpmic_vsel_range rk808_vsel_range4[] = { 220 { 800000, 100000, 0, 12 }, 221 { 2200000, 0, 13, 13 }, 222 { 2500000, 0, 15, 15 }, 223 {} 224 }; 225 226 /* 227 * Used by RK808 for LDO6-7 228 * 0-17: 0.8V-2.5V,step=100mV 229 */ 230 const struct rkpmic_vsel_range rk808_vsel_range5[] = { 231 { 800000, 100000, 0, 17 }, 232 {} 233 }; 234 235 const struct rkpmic_regdata rk808_regdata[] = { 236 { "DCDC_REG1", 0x2f, 0x3f, 0, 0, rk808_vsel_range1 }, 237 { "DCDC_REG2", 0x33, 0x3f, 0, 0, rk808_vsel_range1 }, 238 { "DCDC_REG4", 0x38, 0x0f, 0, 0, rk808_vsel_range2 }, 239 { "LDO_REG1", 0x3b, 0x1f, 0, 0, rk808_vsel_range3 }, 240 { "LDO_REG2", 0x3d, 0x1f, 0, 0, rk808_vsel_range3 }, 241 { "LDO_REG3", 0x3f, 0x0f, 0, 0, rk808_vsel_range4 }, 242 { "LDO_REG4", 0x41, 0x1f, 0, 0, rk808_vsel_range3 }, 243 { "LDO_REG5", 0x43, 0x1f, 0, 0, rk808_vsel_range3 }, 244 { "LDO_REG6", 0x45, 0x1f, 0, 0, rk808_vsel_range5 }, 245 { "LDO_REG7", 0x47, 0x1f, 0, 0, rk808_vsel_range5 }, 246 { "LDO_REG8", 0x49, 0x1f, 0, 0, rk808_vsel_range3 }, 247 { } 248 }; 249 250 /* 251 * Used by RK809 for BUCK1-3 252 * 0-80: 0.5V-1.5V,step=12.5mV 253 * 81-89: 1.6V-2.4V,step=100mV 254 */ 255 const struct rkpmic_vsel_range rk809_vsel_range1[] = { 256 { 500000, 12500, 0, 80 }, 257 { 1600000, 100000, 81, 89 }, 258 {} 259 }; 260 261 /* 262 * Used by RK809 for BUCK4 263 * 0-80: 0.5V-1.5V,step=12.5mV 264 * 81-99: 1.6V-3.4V,step=100mV 265 */ 266 const struct rkpmic_vsel_range rk809_vsel_range2[] = { 267 { 500000, 12500, 0, 80 }, 268 { 1600000, 100000, 81, 99 }, 269 {} 270 }; 271 272 /* 273 * Used by RK809 for BUCK5 274 * 0: 1.5V 275 * 1-3: 1.8V-2.2V,step=200mV 276 * 4-5: 2.8V-3.0V,step=200mV 277 * 6-7: 3.3V-3.6V,step=300mV 278 */ 279 const struct rkpmic_vsel_range rk809_vsel_range3[] = { 280 { 1500000, 0, 0, 0 }, 281 { 1800000, 200000, 1, 3 }, 282 { 2800000, 200000, 4, 5 }, 283 { 3300000, 300000, 6, 7 }, 284 {} 285 }; 286 287 /* 288 * Used by RK809 for LDO1-7 289 * 0-112: 0.6V-3.4V,step=25mV 290 */ 291 const struct rkpmic_vsel_range rk809_vsel_range4[] = { 292 { 600000, 25000, 0, 112 }, 293 {} 294 }; 295 296 const struct rkpmic_regdata rk809_regdata[] = { 297 { "DCDC_REG1", 0xbb, 0x7f, 0xb5, 0x01, rk809_vsel_range1 }, 298 { "DCDC_REG2", 0xbe, 0x7f, 0xb5, 0x02, rk809_vsel_range1 }, 299 { "DCDC_REG3", 0xc1, 0x7f, 0xb5, 0x04, rk809_vsel_range1 }, 300 { "DCDC_REG4", 0xc4, 0x7f, 0xb5, 0x08, rk809_vsel_range2 }, 301 { "DCDC_REG5", 0xde, 0x0f, 0xb5, 0x20, rk809_vsel_range3 }, 302 { "LDO_REG1", 0xcc, 0x7f, 0xb6, 0x01, rk809_vsel_range4 }, 303 { "LDO_REG2", 0xce, 0x7f, 0xb6, 0x02, rk809_vsel_range4 }, 304 { "LDO_REG3", 0xd0, 0x7f, 0xb6, 0x04, rk809_vsel_range4 }, 305 { "LDO_REG4", 0xd2, 0x7f, 0xb6, 0x08, rk809_vsel_range4 }, 306 { "LDO_REG5", 0xd4, 0x7f, 0xb6, 0x10, rk809_vsel_range4 }, 307 { "LDO_REG6", 0xd6, 0x7f, 0xb6, 0x20, rk809_vsel_range4 }, 308 { "LDO_REG7", 0xd8, 0x7f, 0xb6, 0x40, rk809_vsel_range4 }, 309 { "LDO_REG8", 0xda, 0x7f, 0xb6, 0x80, rk809_vsel_range4 }, 310 { "LDO_REG9", 0xdc, 0x7f, 0xb5, 0x10, rk809_vsel_range4 }, 311 { "SWITCH_REG1", 0, 0, 0xb5, 0x40, NULL }, 312 { "SWITCH_REG2", 0, 0, 0xb5, 0x80, NULL }, 313 { } 314 }; 315 316 /* 317 * Used by RK817 for BOOST 318 * 0-7: 4.7V-5.4V,step=100mV 319 */ 320 const struct rkpmic_vsel_range rk817_boost_range[] = { 321 { 4700000, 100000, 0, 7 }, 322 {} 323 }; 324 325 const struct rkpmic_regdata rk817_regdata[] = { 326 { "DCDC_REG1", 0xbb, 0x7f, 0, 0, rk809_vsel_range1 }, 327 { "DCDC_REG2", 0xbe, 0x7f, 0, 0, rk809_vsel_range1 }, 328 { "DCDC_REG3", 0xc1, 0x7f, 0, 0, rk809_vsel_range1 }, 329 { "DCDC_REG4", 0xc4, 0x7f, 0, 0, rk809_vsel_range2 }, 330 { "LDO_REG1", 0xcc, 0x7f, 0, 0, rk809_vsel_range4 }, 331 { "LDO_REG2", 0xce, 0x7f, 0, 0, rk809_vsel_range4 }, 332 { "LDO_REG3", 0xd0, 0x7f, 0, 0, rk809_vsel_range4 }, 333 { "LDO_REG4", 0xd2, 0x7f, 0, 0, rk809_vsel_range4 }, 334 { "LDO_REG5", 0xd4, 0x7f, 0, 0, rk809_vsel_range4 }, 335 { "LDO_REG6", 0xd6, 0x7f, 0, 0, rk809_vsel_range4 }, 336 { "LDO_REG7", 0xd8, 0x7f, 0, 0, rk809_vsel_range4 }, 337 { "LDO_REG8", 0xda, 0x7f, 0, 0, rk809_vsel_range4 }, 338 { "LDO_REG9", 0xdc, 0x7f, 0, 0, rk809_vsel_range4 }, 339 { "BOOST", 0xde, 0x07, 0, 0, rk817_boost_range }, 340 { } 341 }; 342 343 struct rkpmic_softc { 344 struct device sc_dev; 345 int sc_node; 346 347 i2c_tag_t sc_i2c_tag; 348 i2c_addr_t sc_i2c_addr; 349 spi_tag_t sc_spi_tag; 350 struct spi_config sc_spi_conf; 351 352 int sc_rtc_ctrl_reg, sc_rtc_status_reg; 353 uint8_t sc_dev_ctrl_reg, sc_dev_off_val; 354 355 struct todr_chip_handle sc_todr; 356 const struct rkpmic_regdata *sc_regdata; 357 358 int (*sc_read)(struct rkpmic_softc *, uint8_t, void *, size_t); 359 int (*sc_write)(struct rkpmic_softc *, uint8_t, void *, size_t); 360 361 void *sc_ih; 362 }; 363 364 int rkpmic_i2c_match(struct device *, void *, void *); 365 void rkpmic_i2c_attach(struct device *, struct device *, void *); 366 int rkpmic_i2c_read(struct rkpmic_softc *, uint8_t, void *, size_t); 367 int rkpmic_i2c_write(struct rkpmic_softc *, uint8_t, void *, size_t); 368 369 int rkpmic_spi_match(struct device *, void *, void *); 370 void rkpmic_spi_attach(struct device *, struct device *, void *); 371 int rkpmic_spi_read(struct rkpmic_softc *, uint8_t, void *, size_t); 372 int rkpmic_spi_write(struct rkpmic_softc *, uint8_t, void *, size_t); 373 374 void rkpmic_attach(struct device *, struct device *, void *); 375 int rkpmic_activate(struct device *, int); 376 377 const struct cfattach rkpmic_i2c_ca = { 378 sizeof(struct rkpmic_softc), rkpmic_i2c_match, rkpmic_i2c_attach, 379 NULL, rkpmic_activate 380 }; 381 382 const struct cfattach rkpmic_spi_ca = { 383 sizeof(struct rkpmic_softc), rkpmic_spi_match, rkpmic_spi_attach 384 }; 385 386 struct cfdriver rkpmic_cd = { 387 NULL, "rkpmic", DV_DULL 388 }; 389 390 int rkpmic_intr(void *); 391 void rkpmic_attach_regulator(struct rkpmic_softc *, int); 392 uint8_t rkpmic_reg_read(struct rkpmic_softc *, int); 393 void rkpmic_reg_write(struct rkpmic_softc *, int, uint8_t); 394 int rkpmic_clock_read(struct rkpmic_softc *, struct clock_ymdhms *); 395 int rkpmic_clock_write(struct rkpmic_softc *, struct clock_ymdhms *); 396 int rkpmic_gettime(struct todr_chip_handle *, struct timeval *); 397 int rkpmic_settime(struct todr_chip_handle *, struct timeval *); 398 399 struct rkpmic_softc *rkpmic_sc; 400 void rkpmic_powerdown(void); 401 402 int 403 rkpmic_i2c_match(struct device *parent, void *match, void *aux) 404 { 405 struct i2c_attach_args *ia = aux; 406 407 return (strcmp(ia->ia_name, "rockchip,rk805") == 0 || 408 strcmp(ia->ia_name, "rockchip,rk808") == 0 || 409 strcmp(ia->ia_name, "rockchip,rk809") == 0 || 410 strcmp(ia->ia_name, "rockchip,rk817") == 0); 411 } 412 413 void 414 rkpmic_i2c_attach(struct device *parent, struct device *self, void *aux) 415 { 416 struct rkpmic_softc *sc = (struct rkpmic_softc *)self; 417 struct i2c_attach_args *ia = aux; 418 419 sc->sc_i2c_tag = ia->ia_tag; 420 sc->sc_i2c_addr = ia->ia_addr; 421 sc->sc_node = *(int *)ia->ia_cookie; 422 sc->sc_read = rkpmic_i2c_read; 423 sc->sc_write = rkpmic_i2c_write; 424 425 rkpmic_attach(parent, self, aux); 426 } 427 428 int 429 rkpmic_spi_match(struct device *parent, void *match, void *aux) 430 { 431 struct spi_attach_args *sa = aux; 432 433 return (strcmp(sa->sa_name, "rockchip,rk806") == 0); 434 } 435 436 void 437 rkpmic_spi_attach(struct device *parent, struct device *self, void *aux) 438 { 439 struct rkpmic_softc *sc = (struct rkpmic_softc *)self; 440 struct spi_attach_args *sa = aux; 441 442 sc->sc_spi_tag = sa->sa_tag; 443 sc->sc_node = *(int *)sa->sa_cookie; 444 sc->sc_read = rkpmic_spi_read; 445 sc->sc_write = rkpmic_spi_write; 446 447 sc->sc_spi_conf.sc_bpw = 8; 448 sc->sc_spi_conf.sc_freq = 449 OF_getpropint(sc->sc_node, "spi-max-frequency", 1000000); 450 sc->sc_spi_conf.sc_cs = OF_getpropint(sc->sc_node, "reg", 0); 451 452 rkpmic_attach(parent, self, aux); 453 } 454 455 void 456 rkpmic_attach(struct device *parent, struct device *self, void *aux) 457 { 458 struct rkpmic_softc *sc = (struct rkpmic_softc *)self; 459 const char *chip; 460 uint8_t val; 461 int node; 462 463 if (OF_is_compatible(sc->sc_node, "rockchip,rk805")) { 464 chip = "RK805"; 465 sc->sc_rtc_ctrl_reg = RK805_RTC_CTRL; 466 sc->sc_rtc_status_reg = RK805_RTC_STATUS; 467 sc->sc_dev_ctrl_reg = RK805_DEV_CTRL; 468 sc->sc_dev_off_val = RK805_DEV_CTRL_DEV_OFF; 469 sc->sc_regdata = rk805_regdata; 470 } else if (OF_is_compatible(sc->sc_node, "rockchip,rk806")) { 471 chip = "RK806"; 472 sc->sc_dev_ctrl_reg = RK806_SYS_CFG3; 473 sc->sc_dev_off_val = RK806_SYS_CFG3_DEV_OFF; 474 sc->sc_regdata = rk806_regdata; 475 } else if (OF_is_compatible(sc->sc_node, "rockchip,rk808")) { 476 chip = "RK808"; 477 sc->sc_rtc_ctrl_reg = RK808_RTC_CTRL; 478 sc->sc_rtc_status_reg = RK808_RTC_STATUS; 479 sc->sc_dev_ctrl_reg = RK808_DEVCTRL; 480 sc->sc_dev_off_val = RK808_DEVCTRL_DEV_OFF_RST; 481 sc->sc_regdata = rk808_regdata; 482 } else if (OF_is_compatible(sc->sc_node, "rockchip,rk809")) { 483 chip = "RK809"; 484 sc->sc_rtc_ctrl_reg = RK809_RTC_CTRL; 485 sc->sc_rtc_status_reg = RK809_RTC_STATUS; 486 sc->sc_dev_ctrl_reg = RK809_PMIC_SYS_CFG3; 487 sc->sc_dev_off_val = RK809_PMIC_SYS_CFG3_DEV_OFF; 488 sc->sc_regdata = rk809_regdata; 489 } else { 490 chip = "RK817"; 491 sc->sc_rtc_ctrl_reg = RK809_RTC_CTRL; 492 sc->sc_rtc_status_reg = RK809_RTC_STATUS; 493 sc->sc_dev_ctrl_reg = RK809_PMIC_SYS_CFG3; 494 sc->sc_dev_off_val = RK809_PMIC_SYS_CFG3_DEV_OFF; 495 sc->sc_regdata = rk817_regdata; 496 } 497 printf(": %s\n", chip); 498 499 if (sc->sc_rtc_ctrl_reg) { 500 sc->sc_todr.cookie = sc; 501 sc->sc_todr.todr_gettime = rkpmic_gettime; 502 sc->sc_todr.todr_settime = rkpmic_settime; 503 sc->sc_todr.todr_quality = 0; 504 todr_attach(&sc->sc_todr); 505 } 506 507 node = OF_getnodebyname(sc->sc_node, "regulators"); 508 if (node == 0) 509 return; 510 for (node = OF_child(node); node; node = OF_peer(node)) 511 rkpmic_attach_regulator(sc, node); 512 513 if (OF_is_compatible(sc->sc_node, "rockchip,rk809")) { 514 /* Mask all interrupts. */ 515 rkpmic_reg_write(sc, RK809_PMIC_INT_MSK0, 0xff); 516 rkpmic_reg_write(sc, RK809_PMIC_INT_MSK1, 0xff); 517 rkpmic_reg_write(sc, RK809_PMIC_INT_MSK2, 0xff); 518 519 /* Ack all interrupts. */ 520 rkpmic_reg_write(sc, RK809_PMIC_INT_STS0, 0xff); 521 rkpmic_reg_write(sc, RK809_PMIC_INT_STS1, 0xff); 522 rkpmic_reg_write(sc, RK809_PMIC_INT_STS2, 0xff); 523 524 /* Set interrupt pin to active-low. */ 525 val = rkpmic_reg_read(sc, RK809_PMIC_GPIO_INT_CONFIG); 526 rkpmic_reg_write(sc, RK809_PMIC_GPIO_INT_CONFIG, 527 val & ~RK809_PMIC_GPIO_INT_CONFIG_INT_POL); 528 529 sc->sc_ih = fdt_intr_establish(sc->sc_node, IPL_TTY, 530 rkpmic_intr, sc, sc->sc_dev.dv_xname); 531 532 /* Unmask power button interrupt. */ 533 rkpmic_reg_write(sc, RK809_PMIC_INT_MSK0, 534 ~RK809_PMIC_INT_MSK0_PWRON_FALL_INT_IM); 535 536 #ifdef SUSPEND 537 if (OF_getpropbool(sc->sc_node, "wakeup-source")) 538 device_register_wakeup(&sc->sc_dev); 539 #endif 540 } 541 542 if (OF_getpropbool(sc->sc_node, "system-power-controller") || 543 OF_getpropbool(sc->sc_node, "rockchip,system-power-controller")) { 544 rkpmic_sc = sc; 545 powerdownfn = rkpmic_powerdown; 546 } 547 } 548 549 int 550 rkpmic_activate(struct device *self, int act) 551 { 552 struct rkpmic_softc *sc = (struct rkpmic_softc *)self; 553 uint8_t val; 554 555 switch (act) { 556 case DVACT_SUSPEND: 557 if (OF_is_compatible(sc->sc_node, "rockchip,rk809")) { 558 val = rkpmic_reg_read(sc, RK809_PMIC_SYS_CFG3); 559 val &= ~RK809_PMIC_SYS_CFG3_SLP_FUN_MASK; 560 val |= RK809_PMIC_SYS_CFG3_SLP_FUN_SLEEP; 561 rkpmic_reg_write(sc, RK809_PMIC_SYS_CFG3, val); 562 } 563 break; 564 case DVACT_RESUME: 565 if (OF_is_compatible(sc->sc_node, "rockchip,rk809")) { 566 val = rkpmic_reg_read(sc, RK809_PMIC_SYS_CFG3); 567 val &= ~RK809_PMIC_SYS_CFG3_SLP_FUN_MASK; 568 val |= RK809_PMIC_SYS_CFG3_SLP_FUN_NONE; 569 rkpmic_reg_write(sc, RK809_PMIC_SYS_CFG3, val); 570 rkpmic_reg_write(sc, RK809_PMIC_INT_STS0, 0xff); 571 } 572 break; 573 } 574 575 return 0; 576 } 577 578 int 579 rkpmic_intr(void *arg) 580 { 581 extern int allowpowerdown; 582 struct rkpmic_softc *sc = arg; 583 584 if (allowpowerdown) { 585 allowpowerdown = 0; 586 prsignal(initprocess, SIGUSR2); 587 } 588 589 rkpmic_reg_write(sc, RK809_PMIC_INT_STS0, 0xff); 590 return 1; 591 } 592 593 void 594 rkpmic_powerdown(void) 595 { 596 struct rkpmic_softc *sc = rkpmic_sc; 597 rkpmic_reg_write(sc, sc->sc_dev_ctrl_reg, 598 rkpmic_reg_read(sc, sc->sc_dev_ctrl_reg) | sc->sc_dev_off_val); 599 } 600 601 struct rkpmic_regulator { 602 struct rkpmic_softc *rr_sc; 603 604 uint8_t rr_vreg, rr_vmask; 605 const struct rkpmic_vsel_range *rr_vsel_range; 606 607 struct regulator_device rr_rd; 608 }; 609 610 uint32_t rkpmic_get_voltage(void *); 611 int rkpmic_set_voltage(void *, uint32_t); 612 int rkpmic_do_set_voltage(struct rkpmic_regulator *, uint32_t, int); 613 614 void 615 rkpmic_attach_regulator(struct rkpmic_softc *sc, int node) 616 { 617 struct rkpmic_regulator *rr; 618 char name[32]; 619 uint32_t voltage; 620 int i, snode; 621 uint8_t val; 622 623 name[0] = 0; 624 OF_getprop(node, "name", name, sizeof(name)); 625 name[sizeof(name) - 1] = 0; 626 for (i = 0; sc->sc_regdata[i].name; i++) { 627 if (strcmp(sc->sc_regdata[i].name, name) == 0) 628 break; 629 } 630 if (sc->sc_regdata[i].name == NULL) 631 return; 632 633 rr = malloc(sizeof(*rr), M_DEVBUF, M_WAITOK | M_ZERO); 634 rr->rr_sc = sc; 635 636 rr->rr_vreg = sc->sc_regdata[i].vreg; 637 rr->rr_vmask = sc->sc_regdata[i].vmask; 638 rr->rr_vsel_range = sc->sc_regdata[i].vsel_range; 639 640 rr->rr_rd.rd_node = node; 641 rr->rr_rd.rd_cookie = rr; 642 rr->rr_rd.rd_get_voltage = rkpmic_get_voltage; 643 rr->rr_rd.rd_set_voltage = rkpmic_set_voltage; 644 regulator_register(&rr->rr_rd); 645 646 if (sc->sc_regdata[i].smask) { 647 snode = OF_getnodebyname(node, "regulator-state-mem"); 648 if (snode) { 649 val = rkpmic_reg_read(sc, sc->sc_regdata[i].sreg); 650 if (OF_getpropbool(snode, "regulator-on-in-suspend")) 651 val |= sc->sc_regdata[i].smask; 652 if (OF_getpropbool(snode, "regulator-off-in-suspend")) 653 val &= ~sc->sc_regdata[i].smask; 654 rkpmic_reg_write(sc, sc->sc_regdata[i].sreg, val); 655 656 voltage = OF_getpropint(snode, 657 "regulator-suspend-min-microvolt", 0); 658 voltage = OF_getpropint(snode, 659 "regulator-suspend-microvolt", voltage); 660 if (voltage > 0) 661 rkpmic_do_set_voltage(rr, voltage, 1); 662 } 663 } 664 } 665 666 uint32_t 667 rkpmic_get_voltage(void *cookie) 668 { 669 struct rkpmic_regulator *rr = cookie; 670 const struct rkpmic_vsel_range *vsel_range = rr->rr_vsel_range; 671 uint8_t vsel; 672 uint32_t ret = 0; 673 674 if (vsel_range == NULL) 675 return 0; 676 677 vsel = rkpmic_reg_read(rr->rr_sc, rr->rr_vreg) & rr->rr_vmask; 678 679 while (vsel_range->base) { 680 ret = vsel_range->base; 681 if (vsel >= vsel_range->vsel_min && 682 vsel <= vsel_range->vsel_max) { 683 ret += (vsel - vsel_range->vsel_min) * 684 vsel_range->delta; 685 break; 686 } else 687 ret += (vsel_range->vsel_max - vsel_range->vsel_min) * 688 vsel_range->delta; 689 vsel_range++; 690 691 } 692 693 return ret; 694 } 695 696 int 697 rkpmic_set_voltage(void *cookie, uint32_t voltage) 698 { 699 return rkpmic_do_set_voltage(cookie, voltage, 0); 700 } 701 702 int 703 rkpmic_do_set_voltage(struct rkpmic_regulator *rr, uint32_t voltage, int sleep) 704 { 705 const struct rkpmic_vsel_range *vsel_range = rr->rr_vsel_range; 706 uint32_t vmin, vmax, volt; 707 uint8_t reg, vsel; 708 709 if (vsel_range == NULL) 710 return ENODEV; 711 712 while (vsel_range->base) { 713 vmin = vsel_range->base; 714 vmax = vmin + (vsel_range->vsel_max - vsel_range->vsel_min) * 715 vsel_range->delta; 716 if (voltage < vmin) 717 return EINVAL; 718 if (voltage <= vmax) { 719 vsel = vsel_range->vsel_min; 720 volt = vsel_range->base; 721 while (vsel <= vsel_range->vsel_max) { 722 if (volt == voltage) 723 break; 724 else { 725 vsel++; 726 volt += vsel_range->delta; 727 } 728 } 729 if (volt != voltage) 730 return EINVAL; 731 break; 732 } 733 vsel_range++; 734 } 735 736 if (vsel_range->base == 0) 737 return EINVAL; 738 739 reg = rkpmic_reg_read(rr->rr_sc, rr->rr_vreg + sleep); 740 reg &= ~rr->rr_vmask; 741 reg |= vsel; 742 rkpmic_reg_write(rr->rr_sc, rr->rr_vreg + sleep, reg); 743 744 return 0; 745 } 746 747 int 748 rkpmic_gettime(struct todr_chip_handle *handle, struct timeval *tv) 749 { 750 struct rkpmic_softc *sc = handle->cookie; 751 struct clock_ymdhms dt; 752 time_t secs; 753 int error; 754 755 error = rkpmic_clock_read(sc, &dt); 756 if (error) 757 return error; 758 759 if (dt.dt_sec > 59 || dt.dt_min > 59 || dt.dt_hour > 23 || 760 dt.dt_day > 31 || dt.dt_day == 0 || 761 dt.dt_mon > 12 || dt.dt_mon == 0 || 762 dt.dt_year < POSIX_BASE_YEAR) 763 return EINVAL; 764 765 /* 766 * The RTC thinks November has 31 days. Match what Linux does 767 * and undo the damage by considering the calendars to be in 768 * sync on January 1st 2016. 769 */ 770 secs = clock_ymdhms_to_secs(&dt); 771 secs += (dt.dt_year - 2016 + (dt.dt_mon == 12 ? 1 : 0)) * 86400; 772 773 tv->tv_sec = secs; 774 tv->tv_usec = 0; 775 return 0; 776 } 777 778 int 779 rkpmic_settime(struct todr_chip_handle *handle, struct timeval *tv) 780 { 781 struct rkpmic_softc *sc = handle->cookie; 782 struct clock_ymdhms dt; 783 time_t secs; 784 785 /* 786 * Take care of the November 31st braindamage here as well. 787 * Don't try to be clever, just do the conversion in two 788 * steps, first taking care of November 31 in previous years, 789 * and then taking care of days in December of the current 790 * year. December 1st turns into November 31st! 791 */ 792 secs = tv->tv_sec; 793 clock_secs_to_ymdhms(secs, &dt); 794 secs -= (dt.dt_year - 2016) * 86400; 795 clock_secs_to_ymdhms(secs, &dt); 796 if (dt.dt_mon == 12) { 797 dt.dt_day--; 798 if (dt.dt_day == 0) { 799 dt.dt_mon = 11; 800 dt.dt_day = 31; 801 } 802 } 803 804 return rkpmic_clock_write(sc, &dt); 805 } 806 807 uint8_t 808 rkpmic_reg_read(struct rkpmic_softc *sc, int reg) 809 { 810 uint8_t cmd = reg; 811 uint8_t val; 812 813 if (sc->sc_read(sc, cmd, &val, sizeof(val))) { 814 printf("%s: can't read register 0x%02x\n", 815 sc->sc_dev.dv_xname, reg); 816 val = 0xff; 817 } 818 819 return val; 820 } 821 822 void 823 rkpmic_reg_write(struct rkpmic_softc *sc, int reg, uint8_t val) 824 { 825 uint8_t cmd = reg; 826 827 if (sc->sc_write(sc, cmd, &val, sizeof(val))) { 828 printf("%s: can't write register 0x%02x\n", 829 sc->sc_dev.dv_xname, reg); 830 } 831 } 832 833 int 834 rkpmic_clock_read(struct rkpmic_softc *sc, struct clock_ymdhms *dt) 835 { 836 uint8_t regs[RK80X_NRTC_REGS]; 837 uint8_t cmd = RK80X_SECONDS; 838 uint8_t status; 839 int error; 840 841 error = sc->sc_read(sc, cmd, regs, RK80X_NRTC_REGS); 842 843 if (error) { 844 printf("%s: can't read RTC\n", sc->sc_dev.dv_xname); 845 return error; 846 } 847 848 /* 849 * Convert the RK80x's register values into something useable. 850 */ 851 dt->dt_sec = FROMBCD(regs[0]); 852 dt->dt_min = FROMBCD(regs[1]); 853 dt->dt_hour = FROMBCD(regs[2]); 854 dt->dt_day = FROMBCD(regs[3]); 855 dt->dt_mon = FROMBCD(regs[4]); 856 dt->dt_year = FROMBCD(regs[5]) + 2000; 857 858 /* Consider the time to be invalid if the POWER_UP bit is set. */ 859 status = rkpmic_reg_read(sc, sc->sc_rtc_status_reg); 860 if (status & RK80X_RTC_STATUS_POWER_UP) 861 return EINVAL; 862 863 return 0; 864 } 865 866 int 867 rkpmic_clock_write(struct rkpmic_softc *sc, struct clock_ymdhms *dt) 868 { 869 uint8_t regs[RK80X_NRTC_REGS]; 870 uint8_t cmd = RK80X_SECONDS; 871 int error; 872 873 /* 874 * Convert our time representation into something the RK80x 875 * can understand. 876 */ 877 regs[0] = TOBCD(dt->dt_sec); 878 regs[1] = TOBCD(dt->dt_min); 879 regs[2] = TOBCD(dt->dt_hour); 880 regs[3] = TOBCD(dt->dt_day); 881 regs[4] = TOBCD(dt->dt_mon); 882 regs[5] = TOBCD(dt->dt_year - 2000); 883 regs[6] = TOBCD(dt->dt_wday); 884 885 /* Stop RTC such that we can write to it. */ 886 rkpmic_reg_write(sc, sc->sc_rtc_ctrl_reg, RK80X_RTC_CTRL_STOP_RTC); 887 888 error = sc->sc_write(sc, cmd, regs, RK80X_NRTC_REGS); 889 890 /* Restart RTC. */ 891 rkpmic_reg_write(sc, sc->sc_rtc_ctrl_reg, 0); 892 893 if (error) { 894 printf("%s: can't write RTC\n", sc->sc_dev.dv_xname); 895 return error; 896 } 897 898 /* Clear POWER_UP bit to indicate the time is now valid. */ 899 rkpmic_reg_write(sc, sc->sc_rtc_status_reg, RK80X_RTC_STATUS_POWER_UP); 900 901 return 0; 902 } 903 904 int 905 rkpmic_i2c_read(struct rkpmic_softc *sc, uint8_t cmd, void *buf, size_t buflen) 906 { 907 int error; 908 909 iic_acquire_bus(sc->sc_i2c_tag, I2C_F_POLL); 910 error = iic_exec(sc->sc_i2c_tag, I2C_OP_READ_WITH_STOP, 911 sc->sc_i2c_addr, &cmd, sizeof(cmd), buf, buflen, I2C_F_POLL); 912 iic_release_bus(sc->sc_i2c_tag, I2C_F_POLL); 913 914 return error; 915 } 916 917 int 918 rkpmic_i2c_write(struct rkpmic_softc *sc, uint8_t cmd, void *buf, size_t buflen) 919 { 920 int error; 921 922 iic_acquire_bus(sc->sc_i2c_tag, I2C_F_POLL); 923 error = iic_exec(sc->sc_i2c_tag, I2C_OP_WRITE_WITH_STOP, 924 sc->sc_i2c_addr, &cmd, sizeof(cmd), buf, buflen, I2C_F_POLL); 925 iic_release_bus(sc->sc_i2c_tag, I2C_F_POLL); 926 927 return error; 928 } 929 930 int 931 rkpmic_spi_read(struct rkpmic_softc *sc, uint8_t cmd, void *buf, size_t buflen) 932 { 933 uint8_t cmdbuf[3]; 934 int error; 935 936 cmdbuf[0] = RKSPI_CMD_READ | (buflen - 1); 937 cmdbuf[1] = cmd; /* 16-bit addr low */ 938 cmdbuf[2] = 0x00; /* 16-bit addr high */ 939 940 spi_acquire_bus(sc->sc_spi_tag, 0); 941 spi_config(sc->sc_spi_tag, &sc->sc_spi_conf); 942 error = spi_transfer(sc->sc_spi_tag, cmdbuf, NULL, sizeof(cmdbuf), 943 SPI_KEEP_CS); 944 if (!error) 945 error = spi_read(sc->sc_spi_tag, buf, buflen); 946 spi_release_bus(sc->sc_spi_tag, 0); 947 948 return error; 949 } 950 951 int 952 rkpmic_spi_write(struct rkpmic_softc *sc, uint8_t cmd, void *buf, size_t buflen) 953 { 954 uint8_t cmdbuf[3]; 955 int error; 956 957 cmdbuf[0] = RKSPI_CMD_WRITE | (buflen - 1); 958 cmdbuf[1] = cmd; /* 16-bit addr low */ 959 cmdbuf[2] = 0x00; /* 16-bit addr high */ 960 961 spi_acquire_bus(sc->sc_spi_tag, 0); 962 spi_config(sc->sc_spi_tag, &sc->sc_spi_conf); 963 error = spi_transfer(sc->sc_spi_tag, cmdbuf, NULL, sizeof(cmdbuf), 964 SPI_KEEP_CS); 965 if (!error) 966 error = spi_write(sc->sc_spi_tag, buf, buflen); 967 spi_release_bus(sc->sc_spi_tag, 0); 968 969 return error; 970 } 971