1 /* $NetBSD: pca9685.c,v 1.3 2019/07/25 04:24:44 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2018, 2019 Jason R. Thorpe 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: pca9685.c,v 1.3 2019/07/25 04:24:44 thorpej Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/device.h> 35 #include <sys/mutex.h> 36 37 #include <dev/i2c/i2cvar.h> 38 #include <dev/i2c/pca9685reg.h> 39 40 #include <dev/pwm/pwmvar.h> 41 42 #include <dev/fdt/fdtvar.h> 43 44 /* 45 * Special channel number used to indicate that we want to set the 46 * pulse mode for all channels on this controller. 47 */ 48 #define PCA9685_ALL_CHANNELS PCA9685_NCHANNELS 49 50 struct pcapwm_channel { 51 struct pwm_controller ch_controller; 52 struct pwm_config ch_conf; 53 u_int ch_number; 54 }; 55 56 struct pcapwm_softc { 57 device_t sc_dev; 58 i2c_tag_t sc_i2c; 59 i2c_addr_t sc_addr; 60 61 /* 62 * Locking order is: 63 * pcapwm mutex -> i2c bus 64 */ 65 kmutex_t sc_lock; 66 67 /* 68 * The PCA9685 only has a single pre-scaler, so the configured 69 * PWM frequency / period is shared by all channels. 70 */ 71 u_int sc_period; /* nanoseconds */ 72 u_int sc_clk_freq; 73 bool sc_ext_clk; 74 bool sc_invert; /* "invert" property specified */ 75 bool sc_open_drain; /* "open-drain" property specified */ 76 77 /* 78 * +1 because we treat channel "16" as the all-channels 79 * pseudo-channel. 80 */ 81 struct pcapwm_channel sc_channels[PCA9685_NCHANNELS+1]; 82 }; 83 84 static int pcapwm_pwm_enable(struct pwm_controller *, bool); 85 static int pcapwm_pwm_get_config(struct pwm_controller *, 86 struct pwm_config *); 87 static int pcapwm_pwm_set_config(struct pwm_controller *, 88 const struct pwm_config *); 89 90 static const struct device_compatible_entry compat_data[] = { 91 { "nxp,pca9685-pwm", 0 }, 92 { NULL } 93 }; 94 95 static int 96 pcapwm_read1(struct pcapwm_softc * const sc, uint8_t reg, uint8_t *valp) 97 { 98 99 return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, 100 sc->sc_addr, ®, sizeof(reg), 101 valp, sizeof(*valp), 0); 102 } 103 104 static int 105 pcapwm_write1(struct pcapwm_softc * const sc, uint8_t reg, uint8_t val) 106 { 107 108 return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, 109 sc->sc_addr, ®, sizeof(reg), 110 &val, sizeof(val), 0); 111 } 112 113 static int 114 pcapwm_read_LEDn(struct pcapwm_softc * const sc, uint8_t reg, uint8_t *buf, 115 size_t buflen) 116 { 117 118 /* We rely on register auto-increment being enabled. */ 119 return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, 120 sc->sc_addr, ®, sizeof(reg), 121 buf, buflen, 0); 122 } 123 124 static int 125 pcapwm_write_LEDn(struct pcapwm_softc * const sc, uint8_t reg, uint8_t *buf, 126 size_t buflen) 127 { 128 129 /* We rely on register auto-increment being enabled. */ 130 return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, 131 sc->sc_addr, ®, sizeof(reg), 132 buf, buflen, 0); 133 } 134 135 static int 136 pcapwm_program_channel(struct pcapwm_softc * const sc, 137 struct pcapwm_channel * const chan, 138 uint16_t on_tick, uint16_t off_tick) 139 { 140 const uint8_t reg = chan->ch_number == PCA9685_ALL_CHANNELS ? 141 PCA9685_ALL_LED_ON_L : PCA9685_LEDx_ON_L(chan->ch_number); 142 uint8_t regs[4]; 143 int error; 144 145 regs[0] = (uint8_t)(on_tick & 0xff); 146 regs[1] = (uint8_t)((on_tick >> 8) & 0xff); 147 regs[2] = (uint8_t)(off_tick & 0xff); 148 regs[3] = (uint8_t)((off_tick >> 8) & 0xff); 149 150 error = iic_acquire_bus(sc->sc_i2c, 0); 151 if (error) { 152 device_printf(sc->sc_dev, 153 "program_channel: failed to acquire I2C bus\n"); 154 return error; 155 } 156 157 error = pcapwm_write_LEDn(sc, reg, regs, sizeof(regs)); 158 159 iic_release_bus(sc->sc_i2c, 0); 160 161 return error; 162 } 163 164 static int 165 pcapwm_inspect_channel(struct pcapwm_softc * const sc, 166 struct pcapwm_channel * const chan, 167 uint16_t *on_tickp, uint16_t *off_tickp) 168 { 169 const uint8_t reg = chan->ch_number == PCA9685_ALL_CHANNELS ? 170 PCA9685_ALL_LED_ON_L : PCA9685_LEDx_ON_L(chan->ch_number); 171 uint8_t regs[4]; 172 int error; 173 174 error = iic_acquire_bus(sc->sc_i2c, 0); 175 if (error) { 176 device_printf(sc->sc_dev, 177 "inspect_channel: failed to acquire I2C bus\n"); 178 return error; 179 } 180 181 error = pcapwm_read_LEDn(sc, reg, regs, sizeof(regs)); 182 183 iic_release_bus(sc->sc_i2c, 0); 184 185 if (error) { 186 return error; 187 } 188 189 *on_tickp = regs[0] | (((uint16_t)regs[1]) << 8); 190 *off_tickp = regs[2] | (((uint16_t)regs[3]) << 8); 191 192 return 0; 193 } 194 195 static struct pcapwm_channel * 196 pcapwm_lookup_channel(struct pcapwm_softc * const sc, u_int index) 197 { 198 199 if (index > PCA9685_ALL_CHANNELS) 200 return NULL; 201 202 return &sc->sc_channels[index]; 203 } 204 205 static void 206 pcapwm_init_channel(struct pcapwm_softc * const sc, u_int index) 207 { 208 struct pcapwm_channel * const chan = pcapwm_lookup_channel(sc, index); 209 210 KASSERT(chan != NULL); 211 212 chan->ch_number = index; 213 214 chan->ch_controller.pwm_enable = pcapwm_pwm_enable; 215 chan->ch_controller.pwm_get_config = pcapwm_pwm_get_config; 216 chan->ch_controller.pwm_set_config = pcapwm_pwm_set_config; 217 218 chan->ch_controller.pwm_dev = sc->sc_dev; 219 chan->ch_controller.pwm_priv = chan; 220 } 221 222 static pwm_tag_t 223 pcapwm_get_tag(device_t dev, const void *data, size_t len) 224 { 225 struct pcapwm_softc * const sc = device_private(dev); 226 const u_int *pwm = data; 227 228 /* #pwm-cells == 2 in the PCA9685 DT bindings. */ 229 if (len != 12) 230 return NULL; 231 232 /* Channel 16 is the special call-channels channel. */ 233 const u_int index = be32toh(pwm[1]); 234 struct pcapwm_channel * const chan = pcapwm_lookup_channel(sc, index); 235 if (chan == NULL) 236 return NULL; 237 238 const u_int period = be32toh(pwm[2]); 239 240 mutex_enter(&sc->sc_lock); 241 242 /* 243 * XXX Should we reflect the value of the "invert" property in 244 * pwm_config::polarity? I'm thinking not, but... 245 */ 246 chan->ch_conf.period = period; 247 chan->ch_conf.polarity = PWM_ACTIVE_HIGH; 248 249 mutex_exit(&sc->sc_lock); 250 251 return &chan->ch_controller; 252 } 253 254 static struct fdtbus_pwm_controller_func pcapwm_pwm_funcs = { 255 .get_tag = pcapwm_get_tag, 256 }; 257 258 static int 259 pcapwm_pwm_enable(pwm_tag_t pwm, bool enable) 260 { 261 struct pcapwm_softc * const sc = device_private(pwm->pwm_dev); 262 struct pcapwm_channel * const chan = pwm->pwm_priv; 263 int error; 264 265 if (enable) { 266 /* Set whatever is programmed for the channel. */ 267 error = pwm_set_config(pwm, &chan->ch_conf); 268 if (error) { 269 device_printf(sc->sc_dev, 270 "enable: unable to set config for channel %u\n", 271 chan->ch_number); 272 } 273 return error; 274 } 275 276 mutex_enter(&sc->sc_lock); 277 278 error = pcapwm_program_channel(sc, chan, 0, PCA9685_PWM_TICKS); 279 if (error) { 280 device_printf(sc->sc_dev, 281 "disable: unable to program channel %u\n", 282 chan->ch_number); 283 } 284 285 mutex_exit(&sc->sc_lock); 286 287 return error; 288 } 289 290 static int 291 pcapwm_pwm_get_config(pwm_tag_t pwm, struct pwm_config *conf) 292 { 293 struct pcapwm_softc * const sc = device_private(pwm->pwm_dev); 294 struct pcapwm_channel * const chan = pwm->pwm_priv; 295 uint16_t on_tick, off_tick; 296 u_int duty_cycle; 297 int error; 298 299 mutex_enter(&sc->sc_lock); 300 301 error = pcapwm_inspect_channel(sc, chan, &on_tick, &off_tick); 302 if (error) { 303 device_printf(sc->sc_dev, 304 "get_config: unable to inspect channel %u\n", 305 chan->ch_number); 306 goto out; 307 } 308 309 if (on_tick & PCA9685_PWM_TICKS) { 310 duty_cycle = chan->ch_conf.period; 311 } else if (off_tick & PCA9685_PWM_TICKS) { 312 duty_cycle = 0; 313 } else { 314 /* 315 * Compute the number of ticks, accounting for a non-zero 316 * on-tick (which the hardware can do, even if the software 317 * can't). 318 */ 319 int signed_off_tick = off_tick; 320 signed_off_tick -= on_tick; 321 if (signed_off_tick < 0) 322 signed_off_tick += PCA9685_PWM_TICKS; 323 const uint64_t nticks = signed_off_tick; 324 duty_cycle = (u_int)((nticks * chan->ch_conf.period) / 325 PCA9685_PWM_TICKS); 326 } 327 328 *conf = chan->ch_conf; 329 conf->duty_cycle = duty_cycle; 330 331 out: 332 mutex_exit(&sc->sc_lock); 333 334 return error; 335 } 336 337 static int 338 pcapwm_pwm_set_config(pwm_tag_t pwm, const struct pwm_config *conf) 339 { 340 struct pcapwm_softc * const sc = device_private(pwm->pwm_dev); 341 struct pcapwm_channel * const chan = pwm->pwm_priv; 342 int error = 0; 343 344 mutex_enter(&sc->sc_lock); 345 346 /* Only active-high is supported. */ 347 if (conf->polarity != PWM_ACTIVE_HIGH) { 348 device_printf(sc->sc_dev, 349 "set_config: invalid polarity: %d\n", conf->polarity); 350 error = EINVAL; 351 goto out; 352 } 353 354 if (sc->sc_period != conf->period) { 355 /* 356 * Formula for the prescale is: 357 * 358 * ( clk_freq ) 359 * round( ----------------- ) - 1 360 * ( 4096 * pwm_freq ) 361 * 362 * pwm_freq == 1000000000 / period. 363 * 364 * To do the rounding step, we scale the oscillator_freq 365 * by 100, check for the rounding condition, and then 366 * de-scale before the subtraction step. 367 */ 368 const u_int pwm_freq = 1000000000 / conf->period; 369 u_int prescale = (sc->sc_clk_freq * 100) / 370 (PCA9685_PWM_TICKS * pwm_freq); 371 if ((prescale % 100) >= 50) 372 prescale += 100; 373 prescale = (prescale / 100) - 1; 374 if (prescale < PCA9685_PRESCALE_MIN || 375 prescale > PCA9685_PRESCALE_MAX) { 376 device_printf(sc->sc_dev, 377 "set_config: invalid period: %uns\n", conf->period); 378 error = EINVAL; 379 goto out; 380 } 381 382 error = iic_acquire_bus(sc->sc_i2c, 0); 383 if (error) { 384 device_printf(sc->sc_dev, 385 "set_config: unable to acquire I2C bus\n"); 386 goto out; 387 } 388 389 uint8_t mode1; 390 error = pcapwm_read1(sc, PCA9685_MODE1, &mode1); 391 if (error) { 392 device_printf(sc->sc_dev, 393 "set_config: unable to read MODE1\n"); 394 goto out_release_i2c; 395 } 396 397 /* Disable the internal oscillator. */ 398 mode1 |= MODE1_SLEEP; 399 error = pcapwm_write1(sc, PCA9685_MODE1, mode1); 400 if (error) { 401 device_printf(sc->sc_dev, 402 "set_config: unable to write MODE1\n"); 403 goto out_release_i2c; 404 } 405 406 /* Update the prescale register. */ 407 error = pcapwm_write1(sc, PCA9685_PRE_SCALE, 408 (uint8_t)(prescale & 0xff)); 409 if (error) { 410 device_printf(sc->sc_dev, 411 "set_config: unable to write PRE_SCALE\n"); 412 goto out_release_i2c; 413 } 414 415 /* 416 * If we're using an external clock source, keep the 417 * internal oscillator turned off. 418 * 419 * XXX The datasheet is a little ambiguous about how this 420 * XXX is supposed to work -- on the same page it says to 421 * XXX perform this procedure, and also that PWM control of 422 * XXX the channels is not possible when the oscillator is 423 * XXX disabled. I haven't tested this with an external 424 * XXX oscillator yet, so I don't know for sure. 425 */ 426 if (sc->sc_ext_clk) { 427 mode1 |= MODE1_EXTCLK; 428 } else { 429 mode1 &= ~MODE1_SLEEP; 430 } 431 432 /* 433 * We rely on auto-increment for the PWM register updates. 434 */ 435 mode1 |= MODE1_AI; 436 437 error = pcapwm_write1(sc, PCA9685_MODE1, mode1); 438 if (error) { 439 device_printf(sc->sc_dev, 440 "set_config: unable to write MODE1\n"); 441 goto out_release_i2c; 442 } 443 444 iic_release_bus(sc->sc_i2c, 0); 445 446 if (sc->sc_ext_clk == false) { 447 /* Wait for 500us for the clock to settle. */ 448 delay(500); 449 } 450 451 sc->sc_period = conf->period; 452 } 453 454 uint16_t on_tick, off_tick; 455 456 /* 457 * The PWM framework doesn't support the phase-shift / start-delay 458 * feature of this chip, so all duty cycles start at 0 ticks. 459 */ 460 461 /* 462 * For full-on and full-off, use the magic FULL-{ON,OFF} values 463 * described in the data sheet. 464 */ 465 if (conf->duty_cycle == 0) { 466 on_tick = 0; 467 off_tick = PCA9685_PWM_TICKS; 468 } else if (conf->duty_cycle == sc->sc_period) { 469 on_tick = PCA9685_PWM_TICKS; 470 off_tick = 0; 471 } else { 472 uint64_t ticks = 473 PCA9685_PWM_TICKS * (uint64_t)conf->duty_cycle; 474 /* Scale up so we can check if we need to round. */ 475 ticks = (ticks * 100) / sc->sc_period; 476 /* Round up. */ 477 if (ticks % 100) 478 ticks += 100; 479 ticks /= 100; 480 if (ticks >= PCA9685_PWM_TICKS) { 481 ticks = PCA9685_PWM_TICKS - 1; 482 } 483 484 on_tick = 0; 485 off_tick = (u_int)ticks; 486 } 487 488 error = pcapwm_program_channel(sc, chan, on_tick, off_tick); 489 if (error) { 490 device_printf(sc->sc_dev, 491 "set_config: unable to program channel %u\n", 492 chan->ch_number); 493 goto out; 494 } 495 496 chan->ch_conf = *conf; 497 498 out: 499 mutex_exit(&sc->sc_lock); 500 501 return error; 502 503 out_release_i2c: 504 iic_release_bus(sc->sc_i2c, 0); 505 goto out; 506 } 507 508 static int 509 pcapwm_match(device_t parent, cfdata_t cf, void *aux) 510 { 511 struct i2c_attach_args * const ia = aux; 512 int match_result; 513 514 if (iic_use_direct_match(ia, cf, compat_data, &match_result)) { 515 return match_result; 516 } 517 518 /* This device is direct-config only. */ 519 520 return 0; 521 } 522 523 static void 524 pcapwm_attach(device_t parent, device_t self, void *aux) 525 { 526 struct pcapwm_softc * const sc = device_private(self); 527 struct i2c_attach_args * const ia = aux; 528 struct clk *clk; 529 const int phandle = (int)ia->ia_cookie; 530 u_int index; 531 int error; 532 533 sc->sc_dev = self; 534 sc->sc_i2c = ia->ia_tag; 535 sc->sc_addr = ia->ia_addr; 536 537 aprint_naive("\n"); 538 aprint_normal(": PCA9685 PWM controller\n"); 539 540 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 541 542 for (index = 0; index <= PCA9685_ALL_CHANNELS; index++) { 543 pcapwm_init_channel(sc, index); 544 } 545 546 clk = fdtbus_clock_get_index(phandle, 0); 547 if (clk != NULL) { 548 sc->sc_ext_clk = true; 549 sc->sc_clk_freq = clk_get_rate(clk); 550 } else { 551 sc->sc_clk_freq = PCA9685_INTERNAL_FREQ; 552 } 553 554 if (of_hasprop(phandle, "invert")) { 555 sc->sc_invert = true; 556 } 557 558 if (of_hasprop(phandle, "open-drain")) { 559 sc->sc_open_drain = true; 560 } 561 562 /* 563 * XXX No DT bindings for the OUTNEx configurations in 564 * MODE2. 565 */ 566 567 error = iic_acquire_bus(sc->sc_i2c, 0); 568 if (error) { 569 aprint_error_dev(sc->sc_dev, "failed to acquire I2C bus\n"); 570 return; 571 } 572 573 /* 574 * Set up the outputs. We want the channel to update when 575 * we send the I2C "STOP" condition. 576 */ 577 uint8_t mode2; 578 error = pcapwm_read1(sc, PCA9685_MODE2, &mode2); 579 if (error == 0) { 580 mode2 &= ~(MODE2_OUTDRV | MODE2_OCH | MODE2_INVRT); 581 if (sc->sc_invert) { 582 mode2 |= MODE2_INVRT; 583 } 584 if (sc->sc_open_drain == false) { 585 mode2 |= MODE2_OUTDRV; 586 } 587 error = pcapwm_write1(sc, PCA9685_MODE2, mode2); 588 } 589 iic_release_bus(sc->sc_i2c, 0); 590 if (error) { 591 aprint_error_dev(sc->sc_dev, "failed to configure MODE2\n"); 592 return; 593 } 594 595 fdtbus_register_pwm_controller(self, phandle, 596 &pcapwm_pwm_funcs); 597 } 598 599 CFATTACH_DECL_NEW(pcapwm, sizeof(struct pcapwm_softc), 600 pcapwm_match, pcapwm_attach, NULL, NULL); 601