syscons_cbus.c revision 58779
1/*-
2 * Copyright (c) 1999 FreeBSD(98) Porting Team.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer as
10 *    the first lines of this file unmodified.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/pc98/cbus/syscons_cbus.c 58779 2000-03-29 12:26:41Z nyan $
27 */
28
29#include "opt_syscons.h"
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/bus.h>
36
37#include <sys/cons.h>
38#include <machine/console.h>
39#include <machine/clock.h>
40
41#include <pc98/pc98/pc98.h>
42#include <pc98/pc98/pc98_machdep.h>
43
44#include <dev/syscons/syscons.h>
45
46#include <i386/isa/timerreg.h>
47
48#include <isa/isavar.h>
49
50static devclass_t	sc_devclass;
51
52static int	scprobe(device_t dev);
53static int	scattach(device_t dev);
54static int	scresume(device_t dev);
55
56static device_method_t sc_methods[] = {
57	DEVMETHOD(device_probe,         scprobe),
58	DEVMETHOD(device_attach,        scattach),
59	DEVMETHOD(device_resume,        scresume),
60	{ 0, 0 }
61};
62
63static driver_t sc_driver = {
64	SC_DRIVER_NAME,
65	sc_methods,
66	sizeof(sc_softc_t),
67};
68
69static sc_softc_t main_softc;
70
71static int
72scprobe(device_t dev)
73{
74	/* No pnp support */
75	if (isa_get_vendorid(dev))
76		return (ENXIO);
77
78	device_set_desc(dev, "System console");
79	return sc_probe_unit(device_get_unit(dev), device_get_flags(dev));
80}
81
82static int
83scattach(device_t dev)
84{
85	return sc_attach_unit(device_get_unit(dev), device_get_flags(dev));
86}
87
88static int
89scresume(device_t dev)
90{
91	return sc_resume_unit(device_get_unit(dev));
92}
93
94int
95sc_max_unit(void)
96{
97	return devclass_get_maxunit(sc_devclass);
98}
99
100sc_softc_t
101*sc_get_softc(int unit, int flags)
102{
103	sc_softc_t *sc;
104
105	if (unit < 0)
106		return NULL;
107	if (flags & SC_KERNEL_CONSOLE) {
108		/* FIXME: clear if it is wired to another unit! */
109		sc = &main_softc;
110	} else {
111	        sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, unit));
112		if (sc == NULL)
113			return NULL;
114	}
115	sc->unit = unit;
116	if (!(sc->flags & SC_INIT_DONE)) {
117		sc->keyboard = -1;
118		sc->adapter = -1;
119		sc->mouse_char = SC_MOUSE_CHAR;
120	}
121	return sc;
122}
123
124sc_softc_t
125*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
126{
127	sc_softc_t *sc;
128	int units;
129	int i;
130
131	sc = &main_softc;
132	if (((adp == NULL) || (adp == sc->adp))
133	    && ((kbd == NULL) || (kbd == sc->kbd)))
134		return sc;
135	units = devclass_get_maxunit(sc_devclass);
136	for (i = 0; i < units; ++i) {
137	        sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, i));
138		if (sc == NULL)
139			continue;
140		if (((adp == NULL) || (adp == sc->adp))
141		    && ((kbd == NULL) || (kbd == sc->kbd)))
142			return sc;
143	}
144	return NULL;
145}
146
147int
148sc_get_cons_priority(int *unit, int *flags)
149{
150	int disabled;
151	int u, f;
152	int i;
153
154	*unit = -1;
155	for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) {
156		u = resource_query_unit(i);
157		if ((resource_int_value(SC_DRIVER_NAME, u, "disabled",
158					&disabled) == 0) && disabled)
159			continue;
160		if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
161			f = 0;
162		if (f & SC_KERNEL_CONSOLE) {
163			/* the user designates this unit to be the console */
164			*unit = u;
165			*flags = f;
166			break;
167		}
168		if (*unit < 0) {
169			/* ...otherwise remember the first found unit */
170			*unit = u;
171			*flags = f;
172		}
173	}
174	if ((i < 0) && (*unit < 0))
175		return CN_DEAD;
176	return CN_INTERNAL;
177}
178
179void
180sc_get_bios_values(bios_values_t *values)
181{
182	values->cursor_start = 0;
183	values->cursor_end = 16;
184	values->shift_state = 0;
185	if (pc98_machine_type & M_8M)
186		values->bell_pitch = BELL_PITCH_8M;
187	else
188		values->bell_pitch = BELL_PITCH_5M;
189}
190
191int
192sc_tone(int herz)
193{
194	int pitch;
195
196	if (herz) {
197		/* enable counter 1 */
198		outb(0x35, inb(0x35) & 0xf7);
199		/* set command for counter 1, 2 byte write */
200		if (acquire_timer1(TIMER_16BIT | TIMER_SQWAVE))
201			return EBUSY;
202		/* set pitch */
203		pitch = timer_freq/herz;
204		outb(TIMER_CNTR1, pitch);
205		outb(TIMER_CNTR1, pitch >> 8);
206	} else {
207		/* disable counter 1 */
208		outb(0x35, inb(0x35) | 0x08);
209		release_timer1();
210	}
211	return 0;
212}
213
214DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
215