1 /* $NetBSD: gpiopps.c,v 1.2 2018/06/01 13:42:14 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2016 Brad Spencer <brad@anduin.eldar.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions, and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: gpiopps.c,v 1.2 2018/06/01 13:42:14 thorpej Exp $"); 30 31 /* 32 * GPIO interface to the pps subsystem for ntp support. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/bitops.h> 38 #include <sys/device.h> 39 #include <sys/module.h> 40 #include <sys/conf.h> 41 #include <sys/proc.h> 42 #include <sys/ioctl.h> 43 #include <sys/timepps.h> 44 45 #include <sys/gpio.h> 46 #include <dev/gpio/gpiovar.h> 47 48 #define GPIOPPS_NPINS 2 49 50 struct gpiopps_softc { 51 device_t sc_dev; 52 void * sc_gpio; 53 struct gpio_pinmap sc_map; 54 int _map[GPIOPPS_NPINS]; 55 struct { 56 char sc_intrstr[128]; 57 void * sc_ih; 58 int sc_irqmode; 59 } sc_intrs[GPIOPPS_NPINS]; 60 int sc_assert_val; 61 int sc_npins; 62 struct pps_state sc_pps_state; 63 bool sc_functional; 64 bool sc_busy; 65 }; 66 67 #define GPIOPPS_FLAGS_ASSERT_NEG_EDGE 0x01 68 #define GPIOPPS_FLAGS_NO_DOUBLE_EDGE 0x02 69 70 static int gpiopps_match(device_t, cfdata_t, void *); 71 static void gpiopps_attach(device_t, device_t, void *); 72 static int gpiopps_detach(device_t, int); 73 74 CFATTACH_DECL_NEW(gpiopps, sizeof(struct gpiopps_softc), 75 gpiopps_match, gpiopps_attach, 76 gpiopps_detach, NULL /*activate*/); 77 78 extern struct cfdriver gpiopps_cd; 79 80 static dev_type_open(gpioppsopen); 81 static dev_type_close(gpioppsclose); 82 static dev_type_ioctl(gpioppsioctl); 83 const struct cdevsw gpiopps_cdevsw = { 84 .d_open = gpioppsopen, 85 .d_close = gpioppsclose, 86 .d_read = noread, 87 .d_write = nowrite, 88 .d_ioctl = gpioppsioctl, 89 .d_stop = nostop, 90 .d_tty = notty, 91 .d_poll = nopoll, 92 .d_mmap = nommap, 93 .d_kqfilter = nokqfilter, 94 .d_discard = nodiscard, 95 .d_flag = D_OTHER 96 }; 97 98 static int 99 gpiopps_match(device_t parent, cfdata_t cf, void *aux) 100 { 101 struct gpio_attach_args *ga = aux; 102 int bits; 103 104 if (strcmp(ga->ga_dvname, cf->cf_name)) 105 return (0); 106 107 if (ga->ga_offset == -1) 108 return (0); 109 110 /* One or 2 pins (unspecified, assume 1) */ 111 bits = gpio_npins(ga->ga_mask); 112 if (bits > 2) 113 return (0); 114 115 return (1); 116 } 117 118 static void 119 gpiopps_attach(device_t parent, device_t self, void *aux) 120 { 121 struct gpiopps_softc *sc = device_private(self); 122 struct gpio_attach_args *ga = aux; 123 int flags, intrcaps, npins; 124 int assert_edge = GPIO_INTR_POS_EDGE; 125 int clear_edge = GPIO_INTR_NEG_EDGE; 126 int mask = ga->ga_mask; 127 128 sc->sc_dev = self; 129 sc->sc_assert_val = GPIO_PIN_HIGH; 130 131 /* Map pins */ 132 sc->sc_gpio = ga->ga_gpio; 133 sc->sc_map.pm_map = sc->_map; 134 135 /* Determine our pin configuation. */ 136 npins = gpio_npins(mask); 137 if (npins == 0) { 138 npins = 1; 139 mask = 0x1; 140 } 141 142 /* 143 * Here's the different pin configurations we handle: 144 * 145 * 1 pin, single-edge capable pin -- interrupt on single-edge, 146 * only trigger ASSERT signal. 147 * 148 * 1 pin, double-edge capable pin -- interrupt on double-edge, 149 * trigger ASSERT and CLEAR signals, unless 0x2 is set in ga_flags, 150 * in which case we degrade to ASSERT only. 151 * 152 * 2 pins -- pin #0 is ASSERT signal, pin #1 is CLEAR signal. 153 * 154 * If 0x1 is set in ga_flags, ASSERT is negative edge, otherwise 155 * assert is positive edge. 156 */ 157 if (npins < 1 || npins > 2) { 158 aprint_error(": invalid pin configuration\n"); 159 return; 160 } 161 if (ga->ga_flags & GPIOPPS_FLAGS_ASSERT_NEG_EDGE) { 162 assert_edge = GPIO_INTR_NEG_EDGE; 163 clear_edge = GPIO_INTR_POS_EDGE; 164 sc->sc_assert_val = GPIO_PIN_LOW; 165 } 166 167 if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, mask, 168 &sc->sc_map)) { 169 aprint_error(": can't map pins\n"); 170 return; 171 } 172 sc->sc_npins = npins; 173 174 aprint_normal("\n"); 175 176 if (sc->sc_npins == 2) { 177 intrcaps = gpio_pin_intrcaps(sc->sc_gpio, &sc->sc_map, 0); 178 if ((intrcaps & assert_edge) == 0) { 179 aprint_error_dev(sc->sc_dev, 180 "%s edge interrupt not supported for ASSERT\n", 181 assert_edge == GPIO_INTR_POS_EDGE ? "positive" 182 : "negative"); 183 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 184 return; 185 } 186 sc->sc_intrs[0].sc_irqmode = assert_edge; 187 if (!gpio_intr_str(sc->sc_gpio, &sc->sc_map, 0, 188 sc->sc_intrs[0].sc_irqmode, 189 sc->sc_intrs[0].sc_intrstr, 190 sizeof(sc->sc_intrs[0].sc_intrstr))) { 191 aprint_error_dev(self, 192 "failed to decode ASSERT interrupt\n"); 193 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 194 return; 195 } 196 flags = gpio_pin_get_conf(sc->sc_gpio, &sc->sc_map, 0); 197 flags = (flags & ~(GPIO_PIN_OUTPUT|GPIO_PIN_INOUT)) | 198 GPIO_PIN_INPUT; 199 if (!gpio_pin_set_conf(sc->sc_gpio, &sc->sc_map, 0, flags)) { 200 aprint_error_dev(sc->sc_dev, 201 "ASSERT pin not capable of input\n"); 202 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 203 return; 204 } 205 206 intrcaps = gpio_pin_intrcaps(sc->sc_gpio, &sc->sc_map, 1); 207 if ((intrcaps & clear_edge) == 0) { 208 aprint_error_dev(sc->sc_dev, 209 "%s edge interrupt not supported for CLEAR\n", 210 clear_edge == GPIO_INTR_POS_EDGE ? "positive" 211 : "negative"); 212 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 213 return; 214 } 215 sc->sc_intrs[1].sc_irqmode = clear_edge; 216 if (!gpio_intr_str(sc->sc_gpio, &sc->sc_map, 1, 217 sc->sc_intrs[1].sc_irqmode, 218 sc->sc_intrs[1].sc_intrstr, 219 sizeof(sc->sc_intrs[1].sc_intrstr))) { 220 aprint_error_dev(self, 221 "failed to decode CLEAR interrupt\n"); 222 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 223 return; 224 } 225 flags = gpio_pin_get_conf(sc->sc_gpio, &sc->sc_map, 1); 226 flags = (flags & ~(GPIO_PIN_OUTPUT|GPIO_PIN_INOUT)) | 227 GPIO_PIN_INPUT; 228 if (!gpio_pin_set_conf(sc->sc_gpio, &sc->sc_map, 1, flags)) { 229 aprint_error_dev(sc->sc_dev, 230 "CLEAR pin not capable of input\n"); 231 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 232 return; 233 } 234 235 aprint_normal_dev(self, "ASSERT interrupting on %s\n", 236 sc->sc_intrs[0].sc_intrstr); 237 aprint_normal_dev(self, "CLEAR interrupting on %s\n", 238 sc->sc_intrs[1].sc_intrstr); 239 } else { 240 intrcaps = gpio_pin_intrcaps(sc->sc_gpio, &sc->sc_map, 0); 241 bool double_edge = false; 242 if ((intrcaps & GPIO_INTR_DOUBLE_EDGE) && 243 (ga->ga_flags & GPIOPPS_FLAGS_NO_DOUBLE_EDGE) == 0) { 244 sc->sc_intrs[0].sc_irqmode = GPIO_INTR_DOUBLE_EDGE; 245 double_edge = true; 246 } else if (intrcaps & assert_edge) { 247 sc->sc_intrs[0].sc_irqmode = assert_edge; 248 } else { 249 aprint_error_dev(sc->sc_dev, 250 "%s edge interrupt not supported for ASSERT\n", 251 assert_edge == GPIO_INTR_POS_EDGE ? "positive" 252 : "negative"); 253 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 254 return; 255 } 256 if (!gpio_intr_str(sc->sc_gpio, &sc->sc_map, 0, 257 sc->sc_intrs[0].sc_irqmode, 258 sc->sc_intrs[0].sc_intrstr, 259 sizeof(sc->sc_intrs[0].sc_intrstr))) { 260 aprint_error_dev(self, 261 "failed to decode interrupt\n"); 262 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 263 return; 264 } 265 flags = gpio_pin_get_conf(sc->sc_gpio, &sc->sc_map, 0); 266 flags = (flags & ~(GPIO_PIN_OUTPUT|GPIO_PIN_INOUT)) | 267 GPIO_PIN_INPUT; 268 if (!gpio_pin_set_conf(sc->sc_gpio, &sc->sc_map, 0, flags)) { 269 aprint_error_dev(sc->sc_dev, 270 "ASSERT%s pin not capable of input\n", 271 double_edge ? "+CLEAR" : ""); 272 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 273 return; 274 } 275 276 aprint_normal_dev(self, "ASSERT%s interrupting on %s\n", 277 double_edge ? "+CLEAR" : "", 278 sc->sc_intrs[0].sc_intrstr); 279 } 280 281 /* Interrupt will be registered when device is opened for use. */ 282 283 sc->sc_functional = true; 284 } 285 286 static int 287 gpiopps_assert_intr(void *arg) 288 { 289 struct gpiopps_softc *sc = arg; 290 291 mutex_spin_enter(&timecounter_lock); 292 pps_capture(&sc->sc_pps_state); 293 pps_event(&sc->sc_pps_state, PPS_CAPTUREASSERT); 294 mutex_spin_exit(&timecounter_lock); 295 296 return (1); 297 } 298 299 static int 300 gpiopps_clear_intr(void *arg) 301 { 302 struct gpiopps_softc *sc = arg; 303 304 mutex_spin_enter(&timecounter_lock); 305 pps_capture(&sc->sc_pps_state); 306 pps_event(&sc->sc_pps_state, PPS_CAPTURECLEAR); 307 mutex_spin_exit(&timecounter_lock); 308 309 return (1); 310 } 311 312 static int 313 gpiopps_double_intr(void *arg) 314 { 315 struct gpiopps_softc *sc = arg; 316 int val = gpio_pin_read(sc->sc_gpio, &sc->sc_map, 0); 317 318 if (val == sc->sc_assert_val) 319 return (gpiopps_assert_intr(arg)); 320 return (gpiopps_clear_intr(arg)); 321 } 322 323 static void 324 gpiopps_disable_interrupts(struct gpiopps_softc *sc) 325 { 326 int i; 327 328 for (i = 0; i < GPIOPPS_NPINS; i++) { 329 if (sc->sc_intrs[i].sc_ih != NULL) { 330 gpio_intr_disestablish(sc->sc_gpio, 331 sc->sc_intrs[i].sc_ih); 332 sc->sc_intrs[i].sc_ih = NULL; 333 } 334 } 335 } 336 337 static void 338 gpiopps_reset(struct gpiopps_softc *sc) 339 { 340 mutex_spin_enter(&timecounter_lock); 341 sc->sc_pps_state.ppsparam.mode = 0; 342 sc->sc_busy = false; 343 mutex_spin_exit(&timecounter_lock); 344 } 345 346 static int 347 gpiopps_detach(device_t self, int flags) 348 { 349 struct gpiopps_softc *sc = device_private(self); 350 351 if (!sc->sc_functional) { 352 /* Attach failed, no work to do; resources already released. */ 353 return (0); 354 } 355 356 if (sc->sc_busy) 357 return (EBUSY); 358 359 /* 360 * Clear the handler and disable the interrupt. 361 * NOTE: This should never be true, because we 362 * register the interrupt handler at open, and 363 * remove it at close. We keep this as a backstop. 364 */ 365 gpiopps_disable_interrupts(sc); 366 367 /* Release the pin. */ 368 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); 369 370 return (0); 371 } 372 373 static int 374 gpioppsopen(dev_t dev, int flags, int fmt, struct lwp *l) 375 { 376 struct gpiopps_softc *sc; 377 int error = EIO; 378 379 sc = device_lookup_private(&gpiopps_cd, minor(dev)); 380 if (sc == NULL) 381 return (ENXIO); 382 383 if (!sc->sc_functional) 384 return (EIO); 385 386 mutex_spin_enter(&timecounter_lock); 387 388 if (sc->sc_busy) { 389 mutex_spin_exit(&timecounter_lock); 390 return (0); 391 } 392 393 memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); 394 sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT; 395 if (sc->sc_npins == 2 || 396 sc->sc_intrs[0].sc_irqmode == GPIO_INTR_DOUBLE_EDGE) 397 sc->sc_pps_state.ppscap |= PPS_CAPTURECLEAR; 398 pps_init(&sc->sc_pps_state); 399 sc->sc_busy = true; 400 401 mutex_spin_exit(&timecounter_lock); 402 403 if (sc->sc_npins == 2) { 404 sc->sc_intrs[0].sc_ih = gpio_intr_establish(sc->sc_gpio, 405 &sc->sc_map, 0, IPL_VM, 406 sc->sc_intrs[0].sc_irqmode | GPIO_INTR_MPSAFE, 407 gpiopps_assert_intr, sc); 408 if (sc->sc_intrs[0].sc_ih == NULL) { 409 aprint_error_dev(sc->sc_dev, 410 "unable to establish ASSERT interrupt on %s\n", 411 sc->sc_intrs[0].sc_intrstr); 412 goto out; 413 } 414 415 sc->sc_intrs[1].sc_ih = gpio_intr_establish(sc->sc_gpio, 416 &sc->sc_map, 1, IPL_VM, 417 sc->sc_intrs[1].sc_irqmode | GPIO_INTR_MPSAFE, 418 gpiopps_clear_intr, sc); 419 if (sc->sc_intrs[1].sc_ih == NULL) { 420 aprint_error_dev(sc->sc_dev, 421 "unable to establish CLEAR interrupt on %s\n", 422 sc->sc_intrs[0].sc_intrstr); 423 gpio_intr_disestablish(sc->sc_gpio, 424 sc->sc_intrs[0].sc_ih); 425 goto out; 426 } 427 } else { 428 bool double_edge = 429 sc->sc_intrs[0].sc_irqmode == GPIO_INTR_DOUBLE_EDGE; 430 sc->sc_intrs[0].sc_ih = gpio_intr_establish(sc->sc_gpio, 431 &sc->sc_map, 0, IPL_VM, 432 sc->sc_intrs[0].sc_irqmode | GPIO_INTR_MPSAFE, 433 double_edge ? gpiopps_double_intr 434 : gpiopps_assert_intr, sc); 435 if (sc->sc_intrs[0].sc_ih == NULL) { 436 aprint_error_dev(sc->sc_dev, 437 "unable to establish ASSERT%s interrupt on %s\n", 438 double_edge ? "+CLEAR" : "", 439 sc->sc_intrs[0].sc_intrstr); 440 goto out; 441 } 442 } 443 444 error = 0; 445 446 out: 447 if (error) { 448 gpiopps_disable_interrupts(sc); 449 gpiopps_reset(sc); 450 } 451 return (error); 452 } 453 454 static int 455 gpioppsclose(dev_t dev, int flags, int fmt, struct lwp *l) 456 { 457 struct gpiopps_softc *sc; 458 459 sc = device_lookup_private(&gpiopps_cd, minor(dev)); 460 461 gpiopps_disable_interrupts(sc); 462 gpiopps_reset(sc); 463 464 return (0); 465 } 466 467 static int 468 gpioppsioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 469 { 470 struct gpiopps_softc *sc; 471 int error = 0; 472 473 sc = device_lookup_private(&gpiopps_cd, minor(dev)); 474 475 switch (cmd) { 476 case PPS_IOC_CREATE: 477 case PPS_IOC_DESTROY: 478 case PPS_IOC_GETPARAMS: 479 case PPS_IOC_SETPARAMS: 480 case PPS_IOC_GETCAP: 481 case PPS_IOC_FETCH: 482 case PPS_IOC_KCBIND: 483 mutex_spin_enter(&timecounter_lock); 484 error = pps_ioctl(cmd, data, &sc->sc_pps_state); 485 mutex_spin_exit(&timecounter_lock); 486 break; 487 488 default: 489 error = EPASSTHROUGH; 490 } 491 492 return (error); 493 } 494 495 MODULE(MODULE_CLASS_DRIVER, gpiopps, NULL); 496 497 #ifdef _MODULE 498 #include "ioconf.c" 499 #endif 500 501 static int 502 gpiopps_modcmd(modcmd_t cmd, void *opaque) 503 { 504 int error = 0; 505 #ifdef _MODULE 506 int bmaj = -1, cmaj = -1; 507 #endif 508 509 switch (cmd) { 510 case MODULE_CMD_INIT: 511 #ifdef _MODULE 512 error = config_init_component(cfdriver_ioconf_gpiopps, 513 cfattach_ioconf_gpiopps, cfdata_ioconf_gpiopps); 514 if (error) { 515 aprint_error("%s: unable to init component\n", 516 gpiopps_cd.cd_name); 517 return (error); 518 } 519 520 error = devsw_attach("gpiopps", NULL, &bmaj, 521 &gpiopps_cdevsw, &cmaj); 522 if (error) { 523 aprint_error("%s: unable to attach devsw\n", 524 gpiopps_cd.cd_name); 525 config_fini_component(cfdriver_ioconf_gpiopps, 526 cfattach_ioconf_gpiopps, cfdata_ioconf_gpiopps); 527 } 528 #endif 529 return (error); 530 case MODULE_CMD_FINI: 531 #ifdef _MODULE 532 devsw_detach(NULL, &gpiopps_cdevsw); 533 config_fini_component(cfdriver_ioconf_gpiopps, 534 cfattach_ioconf_gpiopps, cfdata_ioconf_gpiopps); 535 #endif 536 return (0); 537 default: 538 return (ENOTTY); 539 } 540 } 541