1 /* $NetBSD: auxiotwo.c,v 1.3 2002/03/11 16:27:03 pk 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 struct cfattach auxiotwo_obio_ca = { 64 sizeof(struct device), auxiotwomatch, auxiotwoattach 65 }; 66 67 /* 68 * The OPENPROM calls this "auxio2". 69 */ 70 static int 71 auxiotwomatch(parent, cf, aux) 72 struct device *parent; 73 struct cfdata *cf; 74 void *aux; 75 { 76 union obio_attach_args *uoba = aux; 77 78 if (uoba->uoba_isobio4 != 0) 79 return (0); 80 81 return (strcmp("auxio2", uoba->uoba_sbus.sa_name) == 0); 82 } 83 84 static void 85 auxiotwoattach(parent, self, aux) 86 struct device *parent, *self; 87 void *aux; 88 { 89 union obio_attach_args *uoba = aux; 90 struct sbus_attach_args *sa = &uoba->uoba_sbus; 91 bus_space_handle_t bh; 92 93 if (sbus_bus_map(sa->sa_bustag, 94 sa->sa_slot, sa->sa_offset, 95 sizeof(long), 96 BUS_SPACE_MAP_LINEAR, &bh) != 0) { 97 printf("auxiotwoattach: can't map register\n"); 98 return; 99 } 100 101 auxiotwo_reg = (volatile u_char *)bh; 102 auxiotwo_regval = *auxiotwo_reg; 103 serial_refcount = 0; 104 serial_power = PORT_PWR_STANDBY; 105 printf("\n"); 106 } 107 108 unsigned int 109 auxiotwobisc(bis, bic) 110 int bis, bic; 111 { 112 register int s; 113 114 if (auxiotwo_reg == 0) 115 /* 116 * Most machines do not have an `aux2' register; devices that 117 * depend on it should not get configured if it's absent. 118 */ 119 panic("no aux2 register"); 120 121 s = splhigh(); 122 auxiotwo_regval = (auxiotwo_regval | bis) & ~bic; 123 *auxiotwo_reg = auxiotwo_regval; 124 splx(s); 125 return (auxiotwo_regval); 126 } 127 128 /* 129 * Serial port state - called from zs_enable()/zs_disable() 130 */ 131 void 132 auxiotwoserialendis (state) 133 int state; 134 { 135 switch (state) { 136 137 case ZS_ENABLE: 138 /* Power on the serial ports? */ 139 serial_refcount++; 140 if (serial_refcount == 1 && serial_power == PORT_PWR_STANDBY) 141 auxiotwobisc(AUXIOTWO_SON, 0); 142 break; 143 case ZS_DISABLE: 144 /* Power off the serial ports? */ 145 serial_refcount--; 146 if (!serial_refcount && serial_power == PORT_PWR_STANDBY) 147 auxiotwobisc(AUXIOTWO_SOF, 1); 148 break; 149 } 150 } 151 152 /* 153 * Set power management - called by tctrl 154 */ 155 void 156 auxiotwoserialsetapm (state) 157 int state; 158 { 159 switch (state) { 160 161 case PORT_PWR_ON: 162 /* Change to: power always on */ 163 if (serial_power == PORT_PWR_OFF || 164 (serial_power == PORT_PWR_STANDBY && !serial_refcount)) 165 auxiotwobisc(AUXIOTWO_SON, 0); 166 serial_power = PORT_PWR_ON; 167 break; 168 169 case PORT_PWR_STANDBY: 170 /* Change to: power on if open */ 171 if (serial_power == PORT_PWR_ON && !serial_refcount) 172 auxiotwobisc(AUXIOTWO_SOF, 1); 173 if (serial_power == PORT_PWR_OFF && serial_refcount) 174 auxiotwobisc(AUXIOTWO_SON, 0); 175 serial_power = PORT_PWR_STANDBY; 176 break; 177 178 case PORT_PWR_OFF: 179 /* Change to: power always off */ 180 if (serial_power == PORT_PWR_ON || 181 (serial_power == PORT_PWR_STANDBY && serial_refcount)) 182 auxiotwobisc(AUXIOTWO_SOF, 1); 183 serial_power = PORT_PWR_OFF; 184 break; 185 } 186 } 187 188 /* 189 * Get power management - called by tctrl 190 */ 191 int 192 auxiotwoserialgetapm () 193 { 194 return (serial_power); 195 } 196