1 /* $OpenBSD: macgpio.c,v 1.6 2007/04/22 22:31:14 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/types.h> 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/device.h> 40 #include <sys/malloc.h> 41 42 #include <dev/ofw/openfirm.h> 43 44 #include <machine/autoconf.h> 45 #include <machine/pio.h> 46 47 #include "adb.h" 48 49 static void macgpio_attach (struct device *, struct device *, void *); 50 static int macgpio_match (struct device *, void *, void *); 51 static int macgpio_print (void *aux, const char *gpio); 52 53 static void macgpio_gpio_attach (struct device *, struct device *, void *); 54 static int macgpio_gpio_match (struct device *, void *, void *); 55 static int gpio_intr (void *); 56 57 struct gpio_softc { 58 struct device sc_dev; 59 u_int8_t *sc_port; 60 }; 61 62 struct cfattach macgpio_ca = { 63 sizeof(struct gpio_softc), macgpio_match, macgpio_attach 64 }; 65 66 struct cfattach macgpio_gpio_ca = { 67 sizeof(struct gpio_softc), macgpio_gpio_match, macgpio_gpio_attach 68 }; 69 70 struct cfdriver macgpio_cd = { 71 NULL, "macgpio", DV_DULL 72 }; 73 74 int 75 macgpio_match(struct device *parent, void *cf, void *aux) 76 { 77 struct confargs *ca = aux; 78 79 if (strcmp(ca->ca_name, "gpio") != 0) 80 return 0; 81 82 if (ca->ca_nreg < 8) 83 return 0; 84 85 return 1; 86 } 87 88 void 89 macgpio_attach(struct device *parent, struct device *self, void *aux) 90 { 91 struct gpio_softc *sc = (struct gpio_softc *)self; 92 struct confargs *ca = aux, ca2; 93 int child; 94 int namelen; 95 int intr[6]; 96 u_int reg[20]; 97 char name[32]; 98 99 printf("\n"); 100 101 sc->sc_port = mapiodev(ca->ca_baseaddr + ca->ca_reg[0], ca->ca_reg[1]); 102 103 ca2.ca_baseaddr = ca->ca_baseaddr; 104 for (child = OF_child(ca->ca_node); child; child = OF_peer(child)) { 105 namelen = OF_getprop(child, "name", name, sizeof(name)); 106 if (namelen < 0) 107 continue; 108 if (namelen >= sizeof(name)) 109 continue; 110 111 name[namelen] = 0; 112 ca2.ca_name = name; 113 ca2.ca_node = child; 114 115 ca2.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg)); 116 ca2.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr, 117 sizeof(intr)); 118 if (ca2.ca_nintr == -1) 119 ca2.ca_nintr = OF_getprop(child, "interrupts", intr, 120 sizeof(intr)); 121 122 ca2.ca_reg = reg; 123 ca2.ca_intr = intr; 124 125 config_found(self, &ca2, macgpio_print); 126 } 127 } 128 129 int 130 macgpio_print(void *aux, const char *gpio) 131 { 132 struct confargs *ca = aux; 133 if (gpio) 134 printf("\"%s\" at %s", ca->ca_name, gpio); 135 136 if (ca->ca_nreg > 0) 137 printf(" offset 0x%x", ca->ca_reg[0]); 138 139 return UNCONF; 140 } 141 142 int 143 macgpio_gpio_match(struct device *parent, void *cf, void *aux) 144 { 145 struct confargs *ca = aux; 146 147 if (strcmp(ca->ca_name, "extint-gpio1") != 0) 148 return 0; 149 150 if (ca->ca_nintr < 4) 151 return 0; 152 153 return 1; 154 } 155 156 void 157 macgpio_gpio_attach(struct device *parent, struct device *self, void *aux) 158 { 159 struct gpio_softc *sc = (struct gpio_softc *)self; 160 struct confargs *ca = aux; 161 162 163 sc->sc_port = ((struct gpio_softc *) parent)->sc_port; 164 mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH, 165 gpio_intr, sc, sc->sc_dev.dv_xname); 166 167 printf(" irq %d\n", ca->ca_intr[0]); 168 } 169 170 #if NADB > 0 171 extern int adb_intr (void *); 172 extern struct cfdriver adb_cd; 173 #endif 174 175 int 176 gpio_intr(void *arg) 177 { 178 int rv = 0; 179 180 #if NADB > 0 181 if (adb_cd.cd_devs[0] != NULL) 182 rv = adb_intr(adb_cd.cd_devs[0]); 183 #endif 184 185 return rv; 186 } 187