1 /* $NetBSD: auxiotwo.c,v 1.6 2002/10/02 16:02:09 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Based on software developed by the Computer Systems Engineering group 41 * at Lawrence Berkeley Laboratory. 42 */ 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/device.h> 47 #include <sys/kernel.h> 48 49 #include <machine/autoconf.h> 50 51 #include <sparc/include/tctrl.h> 52 #include <sparc/sparc/auxiotwo.h> 53 #include <sparc/sparc/vaddrs.h> 54 55 static int serial_refcount; 56 static int serial_power; 57 58 static int auxiotwomatch __P((struct device *, struct cfdata *, void *)); 59 60 static void auxiotwoattach 61 __P((struct device *, struct device *, void *)); 62 63 CFATTACH_DECL(auxiotwo_obio, sizeof(struct device), 64 auxiotwomatch, auxiotwoattach, NULL, NULL); 65 66 /* 67 * The OPENPROM calls this "auxio2". 68 */ 69 static int 70 auxiotwomatch(parent, cf, aux) 71 struct device *parent; 72 struct cfdata *cf; 73 void *aux; 74 { 75 union obio_attach_args *uoba = aux; 76 77 if (uoba->uoba_isobio4 != 0) 78 return (0); 79 80 return (strcmp("auxio2", uoba->uoba_sbus.sa_name) == 0); 81 } 82 83 static void 84 auxiotwoattach(parent, self, aux) 85 struct device *parent, *self; 86 void *aux; 87 { 88 union obio_attach_args *uoba = aux; 89 struct sbus_attach_args *sa = &uoba->uoba_sbus; 90 bus_space_handle_t bh; 91 92 if (sbus_bus_map(sa->sa_bustag, 93 sa->sa_slot, sa->sa_offset, 94 sizeof(long), 95 BUS_SPACE_MAP_LINEAR, &bh) != 0) { 96 printf("auxiotwoattach: can't map register\n"); 97 return; 98 } 99 100 auxiotwo_reg = (volatile u_char *)bh; 101 auxiotwo_regval = *auxiotwo_reg; 102 serial_refcount = 0; 103 serial_power = PORT_PWR_STANDBY; 104 printf("\n"); 105 } 106 107 unsigned int 108 auxiotwobisc(bis, bic) 109 int bis, bic; 110 { 111 register int s; 112 113 if (auxiotwo_reg == 0) 114 /* 115 * Most machines do not have an `aux2' register; devices that 116 * depend on it should not get configured if it's absent. 117 */ 118 panic("no aux2 register"); 119 120 s = splhigh(); 121 auxiotwo_regval = (auxiotwo_regval | bis) & ~bic; 122 *auxiotwo_reg = auxiotwo_regval; 123 splx(s); 124 return (auxiotwo_regval); 125 } 126 127 /* 128 * Serial port state - called from zs_enable()/zs_disable() 129 */ 130 void 131 auxiotwoserialendis (state) 132 int state; 133 { 134 switch (state) { 135 136 case ZS_ENABLE: 137 /* Power on the serial ports? */ 138 serial_refcount++; 139 if (serial_refcount == 1 && serial_power == PORT_PWR_STANDBY) 140 auxiotwobisc(AUXIOTWO_SON, 0); 141 break; 142 case ZS_DISABLE: 143 /* Power off the serial ports? */ 144 serial_refcount--; 145 if (!serial_refcount && serial_power == PORT_PWR_STANDBY) 146 auxiotwobisc(AUXIOTWO_SOF, 1); 147 break; 148 } 149 } 150 151 /* 152 * Set power management - called by tctrl 153 */ 154 void 155 auxiotwoserialsetapm (state) 156 int state; 157 { 158 switch (state) { 159 160 case PORT_PWR_ON: 161 /* Change to: power always on */ 162 if (serial_power == PORT_PWR_OFF || 163 (serial_power == PORT_PWR_STANDBY && !serial_refcount)) 164 auxiotwobisc(AUXIOTWO_SON, 0); 165 serial_power = PORT_PWR_ON; 166 break; 167 168 case PORT_PWR_STANDBY: 169 /* Change to: power on if open */ 170 if (serial_power == PORT_PWR_ON && !serial_refcount) 171 auxiotwobisc(AUXIOTWO_SOF, 1); 172 if (serial_power == PORT_PWR_OFF && serial_refcount) 173 auxiotwobisc(AUXIOTWO_SON, 0); 174 serial_power = PORT_PWR_STANDBY; 175 break; 176 177 case PORT_PWR_OFF: 178 /* Change to: power always off */ 179 if (serial_power == PORT_PWR_ON || 180 (serial_power == PORT_PWR_STANDBY && serial_refcount)) 181 auxiotwobisc(AUXIOTWO_SOF, 1); 182 serial_power = PORT_PWR_OFF; 183 break; 184 } 185 } 186 187 /* 188 * Get power management - called by tctrl 189 */ 190 int 191 auxiotwoserialgetapm () 192 { 193 return (serial_power); 194 } 195