xref: /netbsd/sys/arch/sparc/sparc/auxiotwo.c (revision c4a72b64)
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