This source file includes following definitions.
- mpu_find
- mpu_waitready
- mpu_reset
- mpu_open
- mpu_close
- mpu_readinput
- mpu_output
- mpu_getinfo
- mpu_intr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/errno.h>
43 #include <sys/ioctl.h>
44 #include <sys/syslog.h>
45 #include <sys/device.h>
46 #include <sys/proc.h>
47 #include <sys/buf.h>
48
49 #include <machine/cpu.h>
50 #include <machine/intr.h>
51 #include <machine/bus.h>
52
53 #include <dev/midi_if.h>
54
55 #include <dev/isa/isavar.h>
56 #include <dev/isa/isadmavar.h>
57
58 #include <dev/ic/mpuvar.h>
59
60 #ifndef splaudio
61 #define splaudio() splbio()
62 #endif
63
64 #ifdef AUDIO_DEBUG
65 #define DPRINTF(x) if (mpu401debug) printf x
66 #define DPRINTFN(n,x) if (mpu401debug >= (n)) printf x
67 int mpu401debug = 0;
68 #else
69 #define DPRINTF(x)
70 #define DPRINTFN(n,x)
71 #endif
72
73 #define MPU_GETSTATUS(iot, ioh) (bus_space_read_1(iot, ioh, MPU_STATUS))
74
75 int mpu_reset(struct mpu_softc *);
76 static __inline int mpu_waitready(struct mpu_softc *);
77 void mpu_readinput(struct mpu_softc *);
78
79 struct cfdriver mpu_cd = {
80 NULL, "mpu", DV_DULL
81 };
82
83 struct midi_hw_if mpu_midi_hw_if = {
84 mpu_open,
85 mpu_close,
86 mpu_output,
87 0,
88 mpu_getinfo,
89 0,
90 };
91
92 int
93 mpu_find(v)
94 void *v;
95 {
96 struct mpu_softc *sc = v;
97
98 if (MPU_GETSTATUS(sc->iot, sc->ioh) == 0xff) {
99 DPRINTF(("mpu_find: No status\n"));
100 goto bad;
101 }
102 sc->open = 0;
103 sc->intr = 0;
104 if (mpu_reset(sc) == 0)
105 return 1;
106 bad:
107 return 0;
108 }
109
110 static __inline int
111 mpu_waitready(sc)
112 struct mpu_softc *sc;
113 {
114 int i;
115
116 for(i = 0; i < MPU_MAXWAIT; i++) {
117 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_OUTPUT_BUSY))
118 return 0;
119 delay(10);
120 }
121 return 1;
122 }
123
124 int
125 mpu_reset(sc)
126 struct mpu_softc *sc;
127 {
128 bus_space_tag_t iot = sc->iot;
129 bus_space_handle_t ioh = sc->ioh;
130 int i;
131 int s;
132
133 if (mpu_waitready(sc)) {
134 DPRINTF(("mpu_reset: not ready\n"));
135 return EIO;
136 }
137 s = splaudio();
138 bus_space_write_1(iot, ioh, MPU_COMMAND, MPU_RESET);
139 for(i = 0; i < 2*MPU_MAXWAIT; i++) {
140 if (!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY) &&
141 bus_space_read_1(iot, ioh, MPU_DATA) == MPU_ACK) {
142 splx(s);
143 return 0;
144 }
145 }
146 splx(s);
147 DPRINTF(("mpu_reset: No ACK\n"));
148 return EIO;
149 }
150
151 int
152 mpu_open(v, flags, iintr, ointr, arg)
153 void *v;
154 int flags;
155 void (*iintr)(void *, int);
156 void (*ointr)(void *);
157 void *arg;
158 {
159 struct mpu_softc *sc = v;
160
161 DPRINTF(("mpu_open: sc=%p\n", sc));
162
163 if (sc->open)
164 return EBUSY;
165 if (mpu_reset(sc) != 0)
166 return EIO;
167
168 bus_space_write_1(sc->iot, sc->ioh, MPU_COMMAND, MPU_UART_MODE);
169 sc->open = 1;
170 sc->intr = iintr;
171 sc->arg = arg;
172 return 0;
173 }
174
175 void
176 mpu_close(v)
177 void *v;
178 {
179 struct mpu_softc *sc = v;
180
181 DPRINTF(("mpu_close: sc=%p\n", sc));
182
183 sc->open = 0;
184 sc->intr = 0;
185 mpu_reset(sc);
186 }
187
188 void
189 mpu_readinput(sc)
190 struct mpu_softc *sc;
191 {
192 bus_space_tag_t iot = sc->iot;
193 bus_space_handle_t ioh = sc->ioh;
194 int data;
195
196 while(!(MPU_GETSTATUS(iot, ioh) & MPU_INPUT_EMPTY)) {
197 data = bus_space_read_1(iot, ioh, MPU_DATA);
198 DPRINTFN(3, ("mpu_rea: sc=%p 0x%02x\n", sc, data));
199 if (sc->intr)
200 sc->intr(sc->arg, data);
201 }
202 }
203
204 int
205 mpu_output(v, d)
206 void *v;
207 int d;
208 {
209 struct mpu_softc *sc = v;
210 int s;
211
212 DPRINTFN(3, ("mpu_output: sc=%p 0x%02x\n", sc, d));
213 if (!(MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY)) {
214 s = splaudio();
215 mpu_readinput(sc);
216 splx(s);
217 }
218 if (mpu_waitready(sc)) {
219 DPRINTF(("mpu_output: not ready\n"));
220 return EIO;
221 }
222 bus_space_write_1(sc->iot, sc->ioh, MPU_DATA, d);
223 return 0;
224 }
225
226 void
227 mpu_getinfo(addr, mi)
228 void *addr;
229 struct midi_info *mi;
230 {
231 mi->name = "MPU-401 MIDI UART";
232 mi->props = 0;
233 }
234
235 int
236 mpu_intr(v)
237 void *v;
238 {
239 struct mpu_softc *sc = v;
240
241 if (MPU_GETSTATUS(sc->iot, sc->ioh) & MPU_INPUT_EMPTY) {
242 DPRINTF(("mpu_intr: no data\n"));
243 return 0;
244 }
245 mpu_readinput(sc);
246 return 1;
247 }