1 /* $OpenBSD: macgpio.c,v 1.9 2017/09/08 05:36:52 deraadt Exp $ */ 2 /* $NetBSD: gpio.c,v 1.2 2001/02/27 05:16:33 matt Exp $ */ 3 4 /*- 5 * Copyright (C) 1998 Internet Research Institute, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by 19 * Internet Research Institute, Inc. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/device.h> 39 #include <sys/malloc.h> 40 41 #include <dev/ofw/openfirm.h> 42 43 #include <machine/autoconf.h> 44 #include <machine/pio.h> 45 46 #include "adb.h" 47 48 static void macgpio_attach (struct device *, struct device *, void *); 49 static int macgpio_match (struct device *, void *, void *); 50 static int macgpio_print (void *aux, const char *gpio); 51 52 static void macgpio_gpio_attach (struct device *, struct device *, void *); 53 static int macgpio_gpio_match (struct device *, void *, void *); 54 static int gpio_intr (void *); 55 56 struct gpio_softc { 57 struct device sc_dev; 58 u_int8_t *sc_port; 59 }; 60 61 struct cfattach macgpio_ca = { 62 sizeof(struct gpio_softc), macgpio_match, macgpio_attach 63 }; 64 65 struct cfattach macgpio_gpio_ca = { 66 sizeof(struct gpio_softc), macgpio_gpio_match, macgpio_gpio_attach 67 }; 68 69 struct cfdriver macgpio_cd = { 70 NULL, "macgpio", DV_DULL 71 }; 72 73 int 74 macgpio_match(struct device *parent, void *cf, void *aux) 75 { 76 struct confargs *ca = aux; 77 78 if (strcmp(ca->ca_name, "gpio") != 0) 79 return 0; 80 81 if (ca->ca_nreg < 8) 82 return 0; 83 84 return 1; 85 } 86 87 void 88 macgpio_attach(struct device *parent, struct device *self, void *aux) 89 { 90 struct gpio_softc *sc = (struct gpio_softc *)self; 91 struct confargs *ca = aux, ca2; 92 int child; 93 int namelen; 94 int intr[6]; 95 u_int reg[20]; 96 char name[32]; 97 98 printf("\n"); 99 100 sc->sc_port = mapiodev(ca->ca_baseaddr + ca->ca_reg[0], ca->ca_reg[1]); 101 102 ca2.ca_baseaddr = ca->ca_baseaddr; 103 for (child = OF_child(ca->ca_node); child; child = OF_peer(child)) { 104 namelen = OF_getprop(child, "name", name, sizeof(name)); 105 if (namelen < 0) 106 continue; 107 if (namelen >= sizeof(name)) 108 continue; 109 110 name[namelen] = 0; 111 ca2.ca_name = name; 112 ca2.ca_node = child; 113 114 ca2.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg)); 115 ca2.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr, 116 sizeof(intr)); 117 if (ca2.ca_nintr == -1) 118 ca2.ca_nintr = OF_getprop(child, "interrupts", intr, 119 sizeof(intr)); 120 121 ca2.ca_reg = reg; 122 ca2.ca_intr = intr; 123 124 config_found(self, &ca2, macgpio_print); 125 } 126 } 127 128 int 129 macgpio_print(void *aux, const char *gpio) 130 { 131 struct confargs *ca = aux; 132 if (gpio) 133 printf("\"%s\" at %s", ca->ca_name, gpio); 134 135 if (ca->ca_nreg > 0) 136 printf(" offset 0x%x", ca->ca_reg[0]); 137 138 return UNCONF; 139 } 140 141 int 142 macgpio_gpio_match(struct device *parent, void *cf, void *aux) 143 { 144 struct confargs *ca = aux; 145 146 if (strcmp(ca->ca_name, "extint-gpio1") != 0) 147 return 0; 148 149 if (ca->ca_nintr < 4) 150 return 0; 151 152 return 1; 153 } 154 155 void 156 macgpio_gpio_attach(struct device *parent, struct device *self, void *aux) 157 { 158 struct gpio_softc *sc = (struct gpio_softc *)self; 159 struct confargs *ca = aux; 160 161 162 sc->sc_port = ((struct gpio_softc *) parent)->sc_port; 163 mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_TTY, 164 gpio_intr, sc, sc->sc_dev.dv_xname); 165 166 printf(": irq %d\n", ca->ca_intr[0]); 167 } 168 169 #if NADB > 0 170 extern int adb_intr (void *); 171 extern struct cfdriver adb_cd; 172 #endif 173 174 int 175 gpio_intr(void *arg) 176 { 177 int rv = 0; 178 179 #if NADB > 0 180 if (adb_cd.cd_devs[0] != NULL) 181 rv = adb_intr(adb_cd.cd_devs[0]); 182 #endif 183 184 return rv; 185 } 186