Annotation of sys/arch/mac68k/dev/asc.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: asc.c,v 1.25 2006/09/16 10:42:23 miod Exp $ */
2: /* $NetBSD: asc.c,v 1.20 1997/02/24 05:47:33 scottr Exp $ */
3:
4: /*
5: * Copyright (C) 1997 Scott Reynolds
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. The name of the author may not be used to endorse or promote products
17: * derived from this software without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29: */
30: /*-
31: * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
32: * Michael L. Finch, Bradley A. Grantham, and
33: * Lawrence A. Kesteloot
34: * All rights reserved.
35: *
36: * Redistribution and use in source and binary forms, with or without
37: * modification, are permitted provided that the following conditions
38: * are met:
39: * 1. Redistributions of source code must retain the above copyright
40: * notice, this list of conditions and the following disclaimer.
41: * 2. Redistributions in binary form must reproduce the above copyright
42: * notice, this list of conditions and the following disclaimer in the
43: * documentation and/or other materials provided with the distribution.
44: * 3. All advertising materials mentioning features or use of this software
45: * must display the following acknowledgement:
46: * This product includes software developed by the Alice Group.
47: * 4. The names of the Alice Group or any of its members may not be used
48: * to endorse or promote products derived from this software without
49: * specific prior written permission.
50: *
51: * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
52: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
53: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
54: * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
55: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61: */
62:
63: /*
64: * ASC driver code and console bell support
65: */
66:
67: #include <sys/types.h>
68: #include <sys/cdefs.h>
69: #include <sys/errno.h>
70: #include <sys/time.h>
71: #include <sys/systm.h>
72: #include <sys/param.h>
73: #include <sys/device.h>
74: #include <sys/fcntl.h>
75: #include <sys/poll.h>
76: #include <sys/timeout.h>
77:
78: #include <uvm/uvm_extern.h>
79: #include <uvm/uvm_pmap.h>
80:
81: #include <machine/autoconf.h>
82: #include <machine/cpu.h>
83: #include <machine/bus.h>
84:
85: #include <mac68k/dev/ascvar.h>
86: #include <mac68k/dev/obiovar.h>
87:
88: #define MAC68K_ASC_BASE 0x50f14000
89: #define MAC68K_IIFX_ASC_BASE 0x50f10000
90: #define MAC68K_ASC_LEN 0x01000
91:
92: static u_int8_t asc_wave_tab[0x800];
93:
94: static int asc_ring_bell(void *, int, int, int);
95: static void asc_stop_bell(void *);
96:
97: static int ascmatch(struct device *, void *, void *);
98: static void ascattach(struct device *, struct device *, void *);
99:
100: struct cfattach asc_ca = {
101: sizeof(struct asc_softc), ascmatch, ascattach
102: };
103:
104: struct cfdriver asc_cd = {
105: NULL, "asc", DV_DULL
106: };
107:
108: static int
109: ascmatch(parent, vcf, aux)
110: struct device *parent;
111: void *vcf;
112: void *aux;
113: {
114: struct obio_attach_args *oa = (struct obio_attach_args *)aux;
115: bus_addr_t addr;
116: bus_space_handle_t bsh;
117: int rval = 0;
118:
119: if (oa->oa_addr != (-1))
120: addr = (bus_addr_t)oa->oa_addr;
121: else if (current_mac_model->machineid == MACH_MACTV)
122: return 0;
123: else if (current_mac_model->machineid == MACH_MACIIFX)
124: addr = (bus_addr_t)MAC68K_IIFX_ASC_BASE;
125: else
126: addr = (bus_addr_t)MAC68K_ASC_BASE;
127:
128: if (bus_space_map(oa->oa_tag, addr, MAC68K_ASC_LEN, 0, &bsh))
129: return (0);
130:
131: if (mac68k_bus_space_probe(oa->oa_tag, bsh, 0, 1))
132: rval = 1;
133: else
134: rval = 0;
135:
136: bus_space_unmap(oa->oa_tag, bsh, MAC68K_ASC_LEN);
137:
138: return rval;
139: }
140:
141: static void
142: ascattach(parent, self, aux)
143: struct device *parent, *self;
144: void *aux;
145: {
146: struct asc_softc *sc = (struct asc_softc *)self;
147: struct obio_attach_args *oa = (struct obio_attach_args *)aux;
148: bus_addr_t addr;
149: int i;
150:
151: sc->sc_tag = oa->oa_tag;
152: if (oa->oa_addr != (-1))
153: addr = (bus_addr_t)oa->oa_addr;
154: else if (current_mac_model->machineid == MACH_MACIIFX)
155: addr = (bus_addr_t)MAC68K_IIFX_ASC_BASE;
156: else
157: addr = (bus_addr_t)MAC68K_ASC_BASE;
158: if (bus_space_map(sc->sc_tag, addr, MAC68K_ASC_LEN, 0,
159: &sc->sc_handle)) {
160: printf(": can't map memory space\n");
161: return;
162: }
163: sc->sc_open = 0;
164: sc->sc_ringing = 0;
165: timeout_set(&sc->sc_bell_tmo, asc_stop_bell, sc);
166:
167: for (i = 0; i < 256; i++) { /* up part of wave, four voices? */
168: asc_wave_tab[i] = i / 4;
169: asc_wave_tab[i + 512] = i / 4;
170: asc_wave_tab[i + 1024] = i / 4;
171: asc_wave_tab[i + 1536] = i / 4;
172: }
173: for (i = 0; i < 256; i++) { /* down part of wave, four voices? */
174: asc_wave_tab[i + 256] = 0x3f - (i / 4);
175: asc_wave_tab[i + 768] = 0x3f - (i / 4);
176: asc_wave_tab[i + 1280] = 0x3f - (i / 4);
177: asc_wave_tab[i + 1792] = 0x3f - (i / 4);
178: }
179:
180: printf(": Apple Sound Chip");
181: if (oa->oa_addr != (-1))
182: printf(" at %x", oa->oa_addr);
183: printf("\n");
184:
185: mac68k_set_bell_callback(asc_ring_bell, sc);
186: }
187:
188: int
189: ascopen(dev, flag, mode, p)
190: dev_t dev;
191: int flag;
192: int mode;
193: struct proc *p;
194: {
195: struct asc_softc *sc;
196: int unit;
197:
198: unit = ASCUNIT(dev);
199: if (unit >= asc_cd.cd_ndevs)
200: return (ENXIO);
201: sc = asc_cd.cd_devs[unit];
202: if (sc == NULL)
203: return (ENXIO);
204: if (sc->sc_open)
205: return (EBUSY);
206: sc->sc_open = 1;
207:
208: return (0);
209: }
210:
211: int
212: ascclose(dev, flag, mode, p)
213: dev_t dev;
214: int flag;
215: int mode;
216: struct proc *p;
217: {
218: struct asc_softc *sc;
219:
220: sc = asc_cd.cd_devs[ASCUNIT(dev)];
221: sc->sc_open = 0;
222:
223: return (0);
224: }
225:
226: int
227: ascread(dev, uio, ioflag)
228: dev_t dev;
229: struct uio *uio;
230: int ioflag;
231: {
232: return (ENXIO);
233: }
234:
235: int
236: ascwrite(dev, uio, ioflag)
237: dev_t dev;
238: struct uio *uio;
239: int ioflag;
240: {
241: return (ENXIO);
242: }
243:
244: int
245: ascioctl(dev, cmd, data, flag, p)
246: dev_t dev;
247: int cmd;
248: caddr_t data;
249: int flag;
250: struct proc *p;
251: {
252: struct asc_softc *sc;
253: int error;
254: int unit = ASCUNIT(dev);
255:
256: sc = asc_cd.cd_devs[unit];
257: error = 0;
258:
259: switch (cmd) {
260: default:
261: error = EINVAL;
262: break;
263: }
264: return (error);
265: }
266:
267: int
268: ascpoll(dev, events, p)
269: dev_t dev;
270: int events;
271: struct proc *p;
272: {
273: /* always fails => never blocks */
274: return (events & (POLLOUT | POLLWRNORM));
275: }
276:
277: paddr_t
278: ascmmap(dev, off, prot)
279: dev_t dev;
280: off_t off;
281: int prot;
282: {
283: int unit = ASCUNIT(dev);
284: struct asc_softc *sc;
285: paddr_t pa;
286:
287: sc = asc_cd.cd_devs[unit];
288: if (off >= 0 && off < MAC68K_ASC_LEN) {
289: (void)pmap_extract(pmap_kernel(),
290: (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle), &pa);
291: return atop(pa + off);
292: }
293:
294: return (-1);
295: }
296:
297: static int
298: asc_ring_bell(arg, freq, length, volume)
299: void *arg;
300: int freq, length, volume;
301: {
302: struct asc_softc *sc = (struct asc_softc *)arg;
303: unsigned long cfreq;
304: int i;
305:
306: if (!sc)
307: return (ENODEV);
308:
309: if (sc->sc_ringing == 0) {
310: bus_space_set_region_1(sc->sc_tag, sc->sc_handle,
311: 0, 0, 0x800);
312: bus_space_write_region_1(sc->sc_tag, sc->sc_handle,
313: 0, asc_wave_tab, 0x800);
314:
315: /* Fix this. Need to find exact ASC sampling freq */
316: cfreq = 65536 * freq / 466;
317:
318: /* printf("beep: from %d, %02x %02x %02x %02x\n",
319: * cur_beep.freq, (cfreq >> 24) & 0xff, (cfreq >> 16) & 0xff,
320: * (cfreq >> 8) & 0xff, (cfreq) & 0xff); */
321: for (i = 0; i < 8; i++) {
322: bus_space_write_1(sc->sc_tag, sc->sc_handle,
323: 0x814 + 8 * i, (cfreq >> 24) & 0xff);
324: bus_space_write_1(sc->sc_tag, sc->sc_handle,
325: 0x815 + 8 * i, (cfreq >> 16) & 0xff);
326: bus_space_write_1(sc->sc_tag, sc->sc_handle,
327: 0x816 + 8 * i, (cfreq >> 8) & 0xff);
328: bus_space_write_1(sc->sc_tag, sc->sc_handle,
329: 0x817 + 8 * i, (cfreq) & 0xff);
330: } /* frequency; should put cur_beep.freq in here
331: * somewhere. */
332:
333: bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x807, 3); /* 44 ? */
334: bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x806,
335: 255 * volume / 100);
336: bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x805, 0);
337: bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x80f, 0);
338: bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x802, 2); /* sampled */
339: bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 2); /* enable sampled */
340: sc->sc_ringing = 1;
341: timeout_add(&sc->sc_bell_tmo, length);
342: }
343:
344: return (0);
345: }
346:
347: static void
348: asc_stop_bell(arg)
349: void *arg;
350: {
351: struct asc_softc *sc = (struct asc_softc *)arg;
352:
353: if (!sc)
354: return;
355:
356: if (sc->sc_ringing > 1000 || sc->sc_ringing < 0)
357: panic("bell got out of sync?");
358:
359: if (--sc->sc_ringing == 0) /* disable ASC */
360: bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 0);
361: }
362:
363: int asckqfilter(dev_t, struct knote *);
364:
365: int
366: asckqfilter(dev, kn)
367: dev_t dev;
368: struct knote *kn;
369: {
370: return (1);
371: }
CVSweb