tctrl.c revision 1.2 1 1.2 matt /* $NetBSD: tctrl.c,v 1.2 1999/08/11 00:46:06 matt Exp $ */
2 1.1 matt
3 1.1 matt /*-
4 1.1 matt * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 1.1 matt * All rights reserved.
6 1.1 matt *
7 1.1 matt * This code is derived from software contributed to The NetBSD Foundation
8 1.1 matt * by Matt Thomas.
9 1.1 matt *
10 1.1 matt * Redistribution and use in source and binary forms, with or without
11 1.1 matt * modification, are permitted provided that the following conditions
12 1.1 matt * are met:
13 1.1 matt * 1. Redistributions of source code must retain the above copyright
14 1.1 matt * notice, this list of conditions and the following disclaimer.
15 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 matt * notice, this list of conditions and the following disclaimer in the
17 1.1 matt * documentation and/or other materials provided with the distribution.
18 1.1 matt * 3. All advertising materials mentioning features or use of this software
19 1.1 matt * must display the following acknowledgement:
20 1.1 matt * This product includes software developed by the NetBSD
21 1.1 matt * Foundation, Inc. and its contributors.
22 1.1 matt * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1 matt * contributors may be used to endorse or promote products derived
24 1.1 matt * from this software without specific prior written permission.
25 1.1 matt *
26 1.1 matt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1 matt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1 matt * POSSIBILITY OF SUCH DAMAGE.
37 1.1 matt */
38 1.1 matt
39 1.1 matt #include <sys/param.h>
40 1.1 matt #include <sys/systm.h>
41 1.1 matt #include <sys/ioctl.h>
42 1.1 matt #include <sys/select.h>
43 1.1 matt #include <sys/tty.h>
44 1.1 matt #include <sys/proc.h>
45 1.1 matt #include <sys/user.h>
46 1.1 matt #include <sys/conf.h>
47 1.1 matt #include <sys/file.h>
48 1.1 matt #include <sys/uio.h>
49 1.1 matt #include <sys/kernel.h>
50 1.1 matt #include <sys/syslog.h>
51 1.1 matt #include <sys/types.h>
52 1.1 matt #include <sys/device.h>
53 1.1 matt
54 1.1 matt #include <machine/autoconf.h>
55 1.1 matt #include <machine/cpu.h>
56 1.1 matt #include <machine/bus.h>
57 1.1 matt
58 1.1 matt #include <sparc/dev/ts102reg.h>
59 1.1 matt #include <sparc/dev/tctrlvar.h>
60 1.1 matt
61 1.1 matt static const char *tctrl_ext_statuses[16] = {
62 1.1 matt "main power available",
63 1.1 matt "internal battery attached",
64 1.1 matt "external battery attached",
65 1.1 matt "external VGA attached",
66 1.1 matt "external keyboard attached",
67 1.1 matt "external mouse attached",
68 1.1 matt "lid down",
69 1.1 matt "internal battery charging",
70 1.1 matt "external battery charging",
71 1.1 matt "internal battery discharging",
72 1.1 matt "external battery discharging",
73 1.1 matt };
74 1.1 matt
75 1.1 matt struct tctrl_softc {
76 1.1 matt struct device sc_dev;
77 1.1 matt bus_space_tag_t sc_memt;
78 1.1 matt bus_space_handle_t sc_memh;
79 1.1 matt unsigned int sc_junk;
80 1.1 matt unsigned int sc_ext_status;
81 1.1 matt unsigned int sc_pending;
82 1.1 matt #define TCTRL_SEND_BITPORT 0x0001
83 1.1 matt #define TCTRL_SEND_POWEROFF 0x0002
84 1.1 matt #define TCTRL_SEND_RD_EXT_STATUS 0x0004
85 1.1 matt #define TCTRL_SEND_RD_EVENT_STATUS 0x0008
86 1.2 matt #define TCTRL_SEND_BITPORT_NOP 0x0010
87 1.1 matt enum { TCTRL_IDLE, TCTRL_ARGS,
88 1.1 matt TCTRL_ACK, TCTRL_DATA } sc_state;
89 1.1 matt u_int8_t sc_cmdbuf[16];
90 1.1 matt u_int8_t sc_rspbuf[16];
91 1.1 matt u_int8_t sc_bitport;
92 1.1 matt u_int8_t sc_tft_on;
93 1.1 matt u_int8_t sc_op;
94 1.1 matt u_int8_t sc_cmdoff;
95 1.1 matt u_int8_t sc_cmdlen;
96 1.1 matt u_int8_t sc_rspoff;
97 1.1 matt u_int8_t sc_rsplen;
98 1.1 matt
99 1.1 matt struct evcnt sc_intrcnt; /* interrupt counting */
100 1.1 matt };
101 1.1 matt
102 1.1 matt static int tctrl_match(struct device *parent, struct cfdata *cf, void *aux);
103 1.1 matt static void tctrl_attach(struct device *parent, struct device *self, void *aux);
104 1.1 matt
105 1.1 matt static void tctrl_write(struct tctrl_softc *sc, bus_size_t off, u_int8_t v);
106 1.1 matt static u_int8_t tctrl_read(struct tctrl_softc *sc, bus_size_t off);
107 1.1 matt static void tctrl_write_data(struct tctrl_softc *sc, u_int8_t v);
108 1.1 matt static u_int8_t tctrl_read_data(struct tctrl_softc *sc);
109 1.1 matt static int tctrl_intr(void *arg);
110 1.2 matt static void tctrl_setup_bitport(struct tctrl_softc *sc, int nop);
111 1.1 matt static void tctrl_process_response(struct tctrl_softc *sc);
112 1.1 matt
113 1.1 matt struct cfattach tctrl_ca = {
114 1.1 matt sizeof(struct tctrl_softc), tctrl_match, tctrl_attach
115 1.1 matt };
116 1.1 matt
117 1.1 matt extern struct cfdriver tctrl_cd;
118 1.1 matt
119 1.1 matt static int
120 1.1 matt tctrl_match(struct device *parent, struct cfdata *cf, void *aux)
121 1.1 matt {
122 1.1 matt union obio_attach_args *uoba = aux;
123 1.1 matt struct sbus_attach_args *sa = &uoba->uoba_sbus;
124 1.1 matt
125 1.1 matt if (uoba->uoba_isobio4 != 0) {
126 1.1 matt return (0);
127 1.1 matt }
128 1.1 matt
129 1.1 matt /* Tadpole 3GX/3GS uses "uctrl" for the Tadpole Microcontroller
130 1.1 matt * (who's interface is off the TS102 PCMCIA controller but there
131 1.1 matt * exists a OpenProm for microcontroller interface).
132 1.1 matt */
133 1.1 matt return strcmp("uctrl", sa->sa_name) == 0;
134 1.1 matt }
135 1.1 matt
136 1.1 matt static void
137 1.1 matt tctrl_attach(struct device *parent, struct device *self, void *aux)
138 1.1 matt {
139 1.1 matt struct tctrl_softc *sc = (void *)self;
140 1.1 matt union obio_attach_args *uoba = aux;
141 1.1 matt struct sbus_attach_args *sa = &uoba->uoba_sbus;
142 1.2 matt unsigned int i, v;
143 1.2 matt #if 0
144 1.1 matt unsigned int ack, msb, lsb;
145 1.2 matt #endif
146 1.1 matt
147 1.1 matt /* We're living on a sbus slot that looks like an obio that
148 1.1 matt * looks like an sbus slot.
149 1.1 matt */
150 1.1 matt sc->sc_memt = sa->sa_bustag;
151 1.1 matt if (sbus_bus_map(sc->sc_memt, sa->sa_slot,
152 1.1 matt sa->sa_offset - TS102_REG_UCTRL_INT, sa->sa_size,
153 1.1 matt BUS_SPACE_MAP_LINEAR, 0,
154 1.1 matt &sc->sc_memh) != 0) {
155 1.1 matt printf(": can't map registers\n");
156 1.1 matt return;
157 1.1 matt }
158 1.1 matt
159 1.2 matt printf("\n");
160 1.2 matt
161 1.1 matt sc->sc_tft_on = 1;
162 1.2 matt
163 1.1 matt /* clear any pending data.
164 1.1 matt */
165 1.1 matt for (i = 0; i < 10000; i++) {
166 1.2 matt if ((TS102_UCTRL_STS_RXNE_STA & tctrl_read(sc, TS102_REG_UCTRL_STS)) == 0) {
167 1.1 matt break;
168 1.1 matt }
169 1.1 matt v = tctrl_read(sc, TS102_REG_UCTRL_DATA);
170 1.2 matt tctrl_write(sc, TS102_REG_UCTRL_STS, TS102_UCTRL_STS_RXNE_STA);
171 1.1 matt }
172 1.1 matt
173 1.2 matt (void)bus_intr_establish(sc->sc_memt, sa->sa_pri, 0, tctrl_intr, sc);
174 1.2 matt evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
175 1.2 matt
176 1.2 matt /* See what the external status is
177 1.2 matt */
178 1.2 matt sc->sc_pending |= TCTRL_SEND_RD_EXT_STATUS;
179 1.2 matt do {
180 1.2 matt tctrl_intr(sc);
181 1.2 matt } while (sc->sc_state != TCTRL_IDLE);
182 1.1 matt
183 1.2 matt if (sc->sc_ext_status != 0) {
184 1.2 matt const char *sep;
185 1.1 matt
186 1.1 matt printf("%s: ", sc->sc_dev.dv_xname);
187 1.2 matt v = sc->sc_ext_status;
188 1.1 matt for (i = 0, sep = ""; v != 0; i++, v >>= 1) {
189 1.1 matt if (v & 1) {
190 1.1 matt printf("%s%s", sep, tctrl_ext_statuses[i]);
191 1.1 matt sep = ", ";
192 1.1 matt }
193 1.1 matt }
194 1.1 matt printf("\n");
195 1.1 matt }
196 1.1 matt
197 1.2 matt /* Get a current of the control bitport;
198 1.2 matt */
199 1.2 matt sc->sc_pending |= TCTRL_SEND_BITPORT_NOP;
200 1.2 matt do {
201 1.2 matt tctrl_intr(sc);
202 1.2 matt } while (sc->sc_state != TCTRL_IDLE);
203 1.1 matt
204 1.2 matt tctrl_write(sc, TS102_REG_UCTRL_INT,
205 1.2 matt TS102_UCTRL_INT_RXNE_REQ|TS102_UCTRL_INT_RXNE_MSK);
206 1.1 matt
207 1.1 matt }
208 1.1 matt
209 1.1 matt static int
210 1.1 matt tctrl_intr(void *arg)
211 1.1 matt {
212 1.1 matt struct tctrl_softc *sc = arg;
213 1.1 matt unsigned int v, d;
214 1.1 matt int progress = 0;
215 1.1 matt
216 1.1 matt again:
217 1.1 matt /* find out the cause(s) of the interrupt */
218 1.1 matt v = tctrl_read(sc, TS102_REG_UCTRL_STS);
219 1.1 matt
220 1.1 matt /* clear the cause(s) of the interrupt */
221 1.1 matt tctrl_write(sc, TS102_REG_UCTRL_STS, v);
222 1.1 matt
223 1.2 matt v &= ~(TS102_UCTRL_STS_RXO_STA|TS102_UCTRL_STS_TXE_STA);
224 1.1 matt if (sc->sc_cmdoff >= sc->sc_cmdlen) {
225 1.2 matt v &= ~TS102_UCTRL_STS_TXNF_STA;
226 1.1 matt }
227 1.1 matt if ((v == 0) && (sc->sc_pending == 0 || sc->sc_state != TCTRL_IDLE)) {
228 1.1 matt return progress;
229 1.1 matt }
230 1.1 matt
231 1.1 matt progress = 1;
232 1.2 matt if (v & TS102_UCTRL_STS_RXNE_STA) {
233 1.1 matt d = tctrl_read_data(sc);
234 1.1 matt switch (sc->sc_state) {
235 1.1 matt case TCTRL_IDLE:
236 1.2 matt if (d == 0xfa) {
237 1.1 matt sc->sc_pending |= TCTRL_SEND_RD_EVENT_STATUS;
238 1.2 matt } else {
239 1.2 matt printf("%s: (op=0x%02x): unexpected data (0x%02x)\n",
240 1.2 matt sc->sc_dev.dv_xname, sc->sc_op, d);
241 1.1 matt }
242 1.2 matt goto again;
243 1.1 matt case TCTRL_ACK:
244 1.1 matt if (d != 0xfe) {
245 1.2 matt printf("%s: (op=0x%02x): unexpected ack value (0x%02x)\n",
246 1.1 matt sc->sc_dev.dv_xname, sc->sc_op, d);
247 1.1 matt }
248 1.2 matt #if 0
249 1.2 matt printf(" ack=0x%02x", d);
250 1.2 matt #endif
251 1.2 matt sc->sc_rsplen--;
252 1.2 matt sc->sc_rspoff = 0;
253 1.1 matt sc->sc_state = sc->sc_rsplen ? TCTRL_DATA : TCTRL_IDLE;
254 1.2 matt #if 0
255 1.2 matt if (sc->sc_rsplen > 0) {
256 1.2 matt printf(" [data(%u)]", sc->sc_rsplen);
257 1.2 matt } else {
258 1.2 matt printf(" [idle]\n");
259 1.2 matt }
260 1.2 matt #endif
261 1.2 matt goto again;
262 1.1 matt case TCTRL_DATA:
263 1.1 matt sc->sc_rspbuf[sc->sc_rspoff++] = d;
264 1.2 matt #if 0
265 1.2 matt printf(" [%d]=0x%02x", sc->sc_rspoff-1, d);
266 1.2 matt #endif
267 1.1 matt if (sc->sc_rspoff == sc->sc_rsplen) {
268 1.2 matt #if 0
269 1.2 matt printf(" [idle]\n");
270 1.2 matt #endif
271 1.1 matt sc->sc_state = TCTRL_IDLE;
272 1.2 matt tctrl_process_response(sc);
273 1.1 matt }
274 1.2 matt goto again;
275 1.1 matt default:
276 1.1 matt printf("%s: (op=0x%02x): unexpected data (0x%02x) in state %d\n",
277 1.1 matt sc->sc_dev.dv_xname, sc->sc_op, d, sc->sc_state);
278 1.2 matt goto again;
279 1.1 matt }
280 1.1 matt }
281 1.1 matt if (sc->sc_state == TCTRL_IDLE) {
282 1.1 matt sc->sc_cmdoff = 0;
283 1.2 matt sc->sc_cmdlen = 0;
284 1.1 matt if (sc->sc_pending & TCTRL_SEND_POWEROFF) {
285 1.1 matt sc->sc_pending &= ~TCTRL_SEND_POWEROFF;
286 1.1 matt sc->sc_cmdbuf[0] = TS102_OP_ADMIN_POWER_OFF;
287 1.1 matt sc->sc_cmdlen = 1;
288 1.1 matt sc->sc_rsplen = 0;
289 1.1 matt } else if (sc->sc_pending & TCTRL_SEND_RD_EVENT_STATUS) {
290 1.1 matt sc->sc_pending &= ~TCTRL_SEND_RD_EVENT_STATUS;
291 1.1 matt sc->sc_cmdbuf[0] = TS102_OP_RD_EVENT_STATUS;
292 1.1 matt sc->sc_cmdlen = 1;
293 1.1 matt sc->sc_rsplen = 3;
294 1.1 matt } else if (sc->sc_pending & TCTRL_SEND_RD_EXT_STATUS) {
295 1.1 matt sc->sc_pending &= ~TCTRL_SEND_RD_EXT_STATUS;
296 1.1 matt sc->sc_cmdbuf[0] = TS102_OP_RD_EXT_STATUS;
297 1.1 matt sc->sc_cmdlen = 1;
298 1.1 matt sc->sc_rsplen = 3;
299 1.2 matt } else if (sc->sc_pending & TCTRL_SEND_BITPORT_NOP) {
300 1.2 matt sc->sc_pending &= ~TCTRL_SEND_BITPORT_NOP;
301 1.2 matt tctrl_setup_bitport(sc, 1);
302 1.1 matt } else if (sc->sc_pending & TCTRL_SEND_BITPORT) {
303 1.1 matt sc->sc_pending &= ~TCTRL_SEND_BITPORT;
304 1.2 matt tctrl_setup_bitport(sc, 0);
305 1.1 matt }
306 1.1 matt if (sc->sc_cmdlen > 0) {
307 1.1 matt tctrl_write(sc, TS102_REG_UCTRL_INT,
308 1.1 matt tctrl_read(sc, TS102_REG_UCTRL_INT)
309 1.1 matt |TS102_UCTRL_INT_TXNF_MSK
310 1.1 matt |TS102_UCTRL_INT_TXNF_REQ);
311 1.1 matt v = tctrl_read(sc, TS102_REG_UCTRL_STS);
312 1.1 matt }
313 1.1 matt }
314 1.2 matt if ((sc->sc_cmdoff < sc->sc_cmdlen) && (v & TS102_UCTRL_STS_TXNF_STA)) {
315 1.1 matt tctrl_write_data(sc, sc->sc_cmdbuf[sc->sc_cmdoff++]);
316 1.2 matt #if 0
317 1.2 matt if (sc->sc_cmdoff == 1) {
318 1.2 matt printf("%s: op=0x%02x(l=%u)", sc->sc_dev.dv_xname,
319 1.2 matt sc->sc_cmdbuf[0], sc->sc_rsplen);
320 1.2 matt } else {
321 1.2 matt printf(" [%d]=0x%02x", sc->sc_cmdoff-1,
322 1.2 matt sc->sc_cmdbuf[sc->sc_cmdoff-1]);
323 1.2 matt }
324 1.2 matt #endif
325 1.1 matt if (sc->sc_cmdoff == sc->sc_cmdlen) {
326 1.1 matt sc->sc_state = sc->sc_rsplen ? TCTRL_ACK : TCTRL_IDLE;
327 1.2 matt #if 0
328 1.2 matt printf(" %s", sc->sc_rsplen ? "[ack]" : "[idle]\n");
329 1.2 matt #endif
330 1.2 matt if (sc->sc_cmdoff == 1) {
331 1.2 matt sc->sc_op = sc->sc_cmdbuf[0];
332 1.2 matt }
333 1.1 matt tctrl_write(sc, TS102_REG_UCTRL_INT,
334 1.1 matt tctrl_read(sc, TS102_REG_UCTRL_INT)
335 1.1 matt & (~TS102_UCTRL_INT_TXNF_MSK
336 1.1 matt |TS102_UCTRL_INT_TXNF_REQ));
337 1.1 matt } else if (sc->sc_state == TCTRL_IDLE) {
338 1.1 matt sc->sc_op = sc->sc_cmdbuf[0];
339 1.1 matt sc->sc_state = TCTRL_ARGS;
340 1.2 matt #if 0
341 1.2 matt printf(" [args]");
342 1.2 matt #endif
343 1.1 matt }
344 1.1 matt }
345 1.1 matt goto again;
346 1.1 matt }
347 1.1 matt
348 1.1 matt static void
349 1.2 matt tctrl_setup_bitport(struct tctrl_softc *sc, int nop)
350 1.1 matt {
351 1.2 matt if (nop) {
352 1.2 matt sc->sc_cmdbuf[0] = TS102_OP_CTL_BITPORT;
353 1.2 matt sc->sc_cmdbuf[1] = 0xff;
354 1.1 matt sc->sc_cmdbuf[2] = 0;
355 1.2 matt sc->sc_cmdlen = 3;
356 1.2 matt sc->sc_rsplen = 2;
357 1.1 matt } else {
358 1.2 matt if ((sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN)
359 1.2 matt || (!sc->sc_tft_on)) {
360 1.2 matt sc->sc_cmdbuf[2] = TS102_BITPORT_TFTPWR;
361 1.2 matt } else {
362 1.2 matt sc->sc_cmdbuf[2] = 0;
363 1.2 matt }
364 1.2 matt sc->sc_cmdbuf[0] = TS102_OP_CTL_BITPORT;
365 1.2 matt sc->sc_cmdbuf[1] = ~TS102_BITPORT_TFTPWR;
366 1.2 matt sc->sc_cmdlen = 3;
367 1.2 matt sc->sc_rsplen = 2;
368 1.1 matt }
369 1.1 matt }
370 1.1 matt
371 1.1 matt static void
372 1.1 matt tctrl_process_response(struct tctrl_softc *sc)
373 1.1 matt {
374 1.1 matt switch (sc->sc_op) {
375 1.1 matt case TS102_OP_RD_EXT_STATUS: {
376 1.1 matt sc->sc_ext_status = sc->sc_rspbuf[0] * 256 + sc->sc_rspbuf[1];
377 1.1 matt break;
378 1.1 matt }
379 1.1 matt case TS102_OP_RD_EVENT_STATUS: {
380 1.1 matt unsigned int v = sc->sc_rspbuf[0] * 256 + sc->sc_rspbuf[1];
381 1.1 matt if (v & TS102_EVENT_STATUS_SHUTDOWN_REQUEST) {
382 1.1 matt printf("%s: SHUTDOWN REQUEST!\n", sc->sc_dev.dv_xname);
383 1.1 matt }
384 1.1 matt if (v & TS102_EVENT_STATUS_VERY_LOW_POWER_WARNING) {
385 1.1 matt printf("%s: VERY LOW POWER WARNING!\n", sc->sc_dev.dv_xname);
386 1.1 matt }
387 1.1 matt if (v & TS102_EVENT_STATUS_LOW_POWER_WARNING) {
388 1.1 matt printf("%s: LOW POWER WARNING!\n", sc->sc_dev.dv_xname);
389 1.1 matt }
390 1.1 matt if (v & TS102_EVENT_STATUS_DC_STATUS_CHANGE) {
391 1.1 matt sc->sc_pending |= TCTRL_SEND_RD_EXT_STATUS;
392 1.1 matt printf("%s: main power %s\n", sc->sc_dev.dv_xname,
393 1.1 matt (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) ? "removed" : "restored");
394 1.1 matt }
395 1.1 matt if (v & TS102_EVENT_STATUS_LID_STATUS_CHANGE) {
396 1.1 matt sc->sc_pending |= TCTRL_SEND_RD_EXT_STATUS;
397 1.1 matt sc->sc_pending |= TCTRL_SEND_BITPORT;
398 1.2 matt #if 0
399 1.2 matt printf("%s: lid %s\n", sc->sc_dev.dv_xname,
400 1.2 matt (sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) ? "opened" : "closed");
401 1.2 matt #endif
402 1.1 matt }
403 1.1 matt break;
404 1.1 matt }
405 1.1 matt case TS102_OP_CTL_BITPORT:
406 1.2 matt sc->sc_bitport = (sc->sc_rspbuf[0] & sc->sc_cmdbuf[1]) ^ sc->sc_cmdbuf[2];
407 1.1 matt break;
408 1.1 matt default:
409 1.1 matt break;
410 1.1 matt }
411 1.1 matt }
412 1.1 matt
413 1.1 matt void
414 1.1 matt tadpole_powerdown(void)
415 1.1 matt {
416 1.1 matt struct tctrl_softc *sc;
417 1.1 matt int i, s;
418 1.1 matt
419 1.1 matt if (tctrl_cd.cd_devs == NULL
420 1.1 matt || tctrl_cd.cd_ndevs == 0
421 1.1 matt || tctrl_cd.cd_devs[0] == NULL) {
422 1.1 matt return;
423 1.1 matt }
424 1.1 matt
425 1.1 matt sc = (struct tctrl_softc *) tctrl_cd.cd_devs[0];
426 1.1 matt s = splhigh();
427 1.1 matt sc->sc_pending |= TCTRL_SEND_POWEROFF;
428 1.1 matt for (i = 0; i < 10000; i++) {
429 1.1 matt tctrl_intr(sc);
430 1.1 matt DELAY(1);
431 1.1 matt }
432 1.1 matt splx(s);
433 1.1 matt }
434 1.1 matt
435 1.1 matt void
436 1.1 matt tadpole_set_video(int enabled)
437 1.1 matt {
438 1.1 matt struct tctrl_softc *sc;
439 1.1 matt int s;
440 1.1 matt
441 1.1 matt if (tctrl_cd.cd_devs == NULL
442 1.1 matt || tctrl_cd.cd_ndevs == 0
443 1.1 matt || tctrl_cd.cd_devs[0] == NULL) {
444 1.1 matt return;
445 1.1 matt }
446 1.1 matt
447 1.1 matt sc = (struct tctrl_softc *) tctrl_cd.cd_devs[0];
448 1.1 matt s = splhigh();
449 1.1 matt if ((sc->sc_tft_on && !enabled) || (!sc->sc_tft_on && enabled)) {
450 1.1 matt sc->sc_tft_on = enabled;
451 1.1 matt if (sc->sc_ext_status & TS102_EXT_STATUS_LID_DOWN) {
452 1.1 matt splx(s);
453 1.1 matt return;
454 1.1 matt }
455 1.1 matt sc->sc_pending |= TCTRL_SEND_BITPORT;
456 1.1 matt tctrl_intr(sc);
457 1.1 matt }
458 1.1 matt splx(s);
459 1.1 matt }
460 1.1 matt
461 1.1 matt static void
462 1.1 matt tctrl_write_data(struct tctrl_softc *sc, u_int8_t v)
463 1.1 matt {
464 1.1 matt unsigned int i;
465 1.1 matt for (i = 0; i < 100; i++) {
466 1.2 matt if (TS102_UCTRL_STS_TXNF_STA & tctrl_read(sc, TS102_REG_UCTRL_STS))
467 1.1 matt break;
468 1.1 matt }
469 1.1 matt tctrl_write(sc, TS102_REG_UCTRL_DATA, v);
470 1.1 matt }
471 1.1 matt
472 1.1 matt static u_int8_t
473 1.1 matt tctrl_read_data(struct tctrl_softc *sc)
474 1.1 matt {
475 1.1 matt unsigned int i, v;
476 1.1 matt
477 1.1 matt for (i = 0; i < 100000; i++) {
478 1.2 matt if (TS102_UCTRL_STS_RXNE_STA & tctrl_read(sc, TS102_REG_UCTRL_STS))
479 1.1 matt break;
480 1.1 matt DELAY(1);
481 1.1 matt }
482 1.1 matt
483 1.1 matt v = tctrl_read(sc, TS102_REG_UCTRL_DATA);
484 1.2 matt tctrl_write(sc, TS102_REG_UCTRL_STS, TS102_UCTRL_STS_RXNE_STA);
485 1.1 matt return v;
486 1.1 matt }
487 1.1 matt
488 1.1 matt static u_int8_t
489 1.1 matt tctrl_read(struct tctrl_softc *sc, bus_size_t off)
490 1.1 matt {
491 1.2 matt sc->sc_junk = bus_space_read_1(sc->sc_memt, sc->sc_memh, off);
492 1.1 matt return sc->sc_junk;
493 1.1 matt }
494 1.1 matt
495 1.1 matt static void
496 1.1 matt tctrl_write(struct tctrl_softc *sc, bus_size_t off, u_int8_t v)
497 1.1 matt {
498 1.1 matt sc->sc_junk = v;
499 1.2 matt bus_space_write_1(sc->sc_memt, sc->sc_memh, off, v);
500 1.1 matt }
501