Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / sound / pci / emu10k1 / emumpu401.c
blobb6650f5c1621906e713e45fac27e816833aef2b0
1 /*
2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 * Routines for control of EMU10K1 MPU-401 in UART mode
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/time.h>
23 #include <linux/init.h>
24 #include <sound/core.h>
25 #include <sound/emu10k1.h>
27 #define EMU10K1_MIDI_MODE_INPUT (1<<0)
28 #define EMU10K1_MIDI_MODE_OUTPUT (1<<1)
30 static inline unsigned char mpu401_read(struct snd_emu10k1 *emu,
31 struct snd_emu10k1_midi *mpu, int idx)
33 if (emu->audigy)
34 return (unsigned char)snd_emu10k1_ptr_read(emu, mpu->port + idx, 0);
35 else
36 return inb(emu->port + mpu->port + idx);
39 static inline void mpu401_write(struct snd_emu10k1 *emu,
40 struct snd_emu10k1_midi *mpu, int data, int idx)
42 if (emu->audigy)
43 snd_emu10k1_ptr_write(emu, mpu->port + idx, 0, data);
44 else
45 outb(data, emu->port + mpu->port + idx);
48 #define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
49 #define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
50 #define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
51 #define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
53 #define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
54 #define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
56 #define MPU401_RESET 0xff
57 #define MPU401_ENTER_UART 0x3f
58 #define MPU401_ACK 0xfe
60 static void mpu401_clear_rx(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *mpu)
62 int timeout = 100000;
63 for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
64 mpu401_read_data(emu, mpu);
65 #ifdef CONFIG_SND_DEBUG
66 if (timeout <= 0)
67 dev_err(emu->card->dev,
68 "cmd: clear rx timeout (status = 0x%x)\n",
69 mpu401_read_stat(emu, mpu));
70 #endif
77 static void do_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, unsigned int status)
79 unsigned char byte;
81 if (midi->rmidi == NULL) {
82 snd_emu10k1_intr_disable(emu, midi->tx_enable | midi->rx_enable);
83 return;
86 spin_lock(&midi->input_lock);
87 if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
88 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
89 mpu401_clear_rx(emu, midi);
90 } else {
91 byte = mpu401_read_data(emu, midi);
92 if (midi->substream_input)
93 snd_rawmidi_receive(midi->substream_input, &byte, 1);
96 spin_unlock(&midi->input_lock);
98 spin_lock(&midi->output_lock);
99 if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
100 if (midi->substream_output &&
101 snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
102 mpu401_write_data(emu, midi, byte);
103 } else {
104 snd_emu10k1_intr_disable(emu, midi->tx_enable);
107 spin_unlock(&midi->output_lock);
110 static void snd_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, unsigned int status)
112 do_emu10k1_midi_interrupt(emu, &emu->midi, status);
115 static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int status)
117 do_emu10k1_midi_interrupt(emu, &emu->midi2, status);
120 static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)
122 unsigned long flags;
123 int timeout, ok;
125 spin_lock_irqsave(&midi->input_lock, flags);
126 mpu401_write_data(emu, midi, 0x00);
127 /* mpu401_clear_rx(emu, midi); */
129 mpu401_write_cmd(emu, midi, cmd);
130 if (ack) {
131 ok = 0;
132 timeout = 10000;
133 while (!ok && timeout-- > 0) {
134 if (mpu401_input_avail(emu, midi)) {
135 if (mpu401_read_data(emu, midi) == MPU401_ACK)
136 ok = 1;
139 if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
140 ok = 1;
141 } else {
142 ok = 1;
144 spin_unlock_irqrestore(&midi->input_lock, flags);
145 if (!ok) {
146 dev_err(emu->card->dev,
147 "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
148 cmd, emu->port,
149 mpu401_read_stat(emu, midi),
150 mpu401_read_data(emu, midi));
151 return 1;
153 return 0;
156 static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
158 struct snd_emu10k1 *emu;
159 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
160 unsigned long flags;
162 emu = midi->emu;
163 if (snd_BUG_ON(!emu))
164 return -ENXIO;
165 spin_lock_irqsave(&midi->open_lock, flags);
166 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
167 midi->substream_input = substream;
168 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
169 spin_unlock_irqrestore(&midi->open_lock, flags);
170 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
171 goto error_out;
172 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
173 goto error_out;
174 } else {
175 spin_unlock_irqrestore(&midi->open_lock, flags);
177 return 0;
179 error_out:
180 return -EIO;
183 static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
185 struct snd_emu10k1 *emu;
186 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
187 unsigned long flags;
189 emu = midi->emu;
190 if (snd_BUG_ON(!emu))
191 return -ENXIO;
192 spin_lock_irqsave(&midi->open_lock, flags);
193 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
194 midi->substream_output = substream;
195 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
196 spin_unlock_irqrestore(&midi->open_lock, flags);
197 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
198 goto error_out;
199 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
200 goto error_out;
201 } else {
202 spin_unlock_irqrestore(&midi->open_lock, flags);
204 return 0;
206 error_out:
207 return -EIO;
210 static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
212 struct snd_emu10k1 *emu;
213 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
214 unsigned long flags;
215 int err = 0;
217 emu = midi->emu;
218 if (snd_BUG_ON(!emu))
219 return -ENXIO;
220 spin_lock_irqsave(&midi->open_lock, flags);
221 snd_emu10k1_intr_disable(emu, midi->rx_enable);
222 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
223 midi->substream_input = NULL;
224 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
225 spin_unlock_irqrestore(&midi->open_lock, flags);
226 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
227 } else {
228 spin_unlock_irqrestore(&midi->open_lock, flags);
230 return err;
233 static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
235 struct snd_emu10k1 *emu;
236 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
237 unsigned long flags;
238 int err = 0;
240 emu = midi->emu;
241 if (snd_BUG_ON(!emu))
242 return -ENXIO;
243 spin_lock_irqsave(&midi->open_lock, flags);
244 snd_emu10k1_intr_disable(emu, midi->tx_enable);
245 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
246 midi->substream_output = NULL;
247 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
248 spin_unlock_irqrestore(&midi->open_lock, flags);
249 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
250 } else {
251 spin_unlock_irqrestore(&midi->open_lock, flags);
253 return err;
256 static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
258 struct snd_emu10k1 *emu;
259 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
260 emu = midi->emu;
261 if (snd_BUG_ON(!emu))
262 return;
264 if (up)
265 snd_emu10k1_intr_enable(emu, midi->rx_enable);
266 else
267 snd_emu10k1_intr_disable(emu, midi->rx_enable);
270 static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
272 struct snd_emu10k1 *emu;
273 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
274 unsigned long flags;
276 emu = midi->emu;
277 if (snd_BUG_ON(!emu))
278 return;
280 if (up) {
281 int max = 4;
282 unsigned char byte;
284 /* try to send some amount of bytes here before interrupts */
285 spin_lock_irqsave(&midi->output_lock, flags);
286 while (max > 0) {
287 if (mpu401_output_ready(emu, midi)) {
288 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
289 snd_rawmidi_transmit(substream, &byte, 1) != 1) {
290 /* no more data */
291 spin_unlock_irqrestore(&midi->output_lock, flags);
292 return;
294 mpu401_write_data(emu, midi, byte);
295 max--;
296 } else {
297 break;
300 spin_unlock_irqrestore(&midi->output_lock, flags);
301 snd_emu10k1_intr_enable(emu, midi->tx_enable);
302 } else {
303 snd_emu10k1_intr_disable(emu, midi->tx_enable);
311 static const struct snd_rawmidi_ops snd_emu10k1_midi_output =
313 .open = snd_emu10k1_midi_output_open,
314 .close = snd_emu10k1_midi_output_close,
315 .trigger = snd_emu10k1_midi_output_trigger,
318 static const struct snd_rawmidi_ops snd_emu10k1_midi_input =
320 .open = snd_emu10k1_midi_input_open,
321 .close = snd_emu10k1_midi_input_close,
322 .trigger = snd_emu10k1_midi_input_trigger,
325 static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi)
327 struct snd_emu10k1_midi *midi = rmidi->private_data;
328 midi->interrupt = NULL;
329 midi->rmidi = NULL;
332 static int emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, int device, char *name)
334 struct snd_rawmidi *rmidi;
335 int err;
337 if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
338 return err;
339 midi->emu = emu;
340 spin_lock_init(&midi->open_lock);
341 spin_lock_init(&midi->input_lock);
342 spin_lock_init(&midi->output_lock);
343 strcpy(rmidi->name, name);
344 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1_midi_output);
345 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1_midi_input);
346 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
347 SNDRV_RAWMIDI_INFO_INPUT |
348 SNDRV_RAWMIDI_INFO_DUPLEX;
349 rmidi->private_data = midi;
350 rmidi->private_free = snd_emu10k1_midi_free;
351 midi->rmidi = rmidi;
352 return 0;
355 int snd_emu10k1_midi(struct snd_emu10k1 *emu)
357 struct snd_emu10k1_midi *midi = &emu->midi;
358 int err;
360 if ((err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)")) < 0)
361 return err;
363 midi->tx_enable = INTE_MIDITXENABLE;
364 midi->rx_enable = INTE_MIDIRXENABLE;
365 midi->port = MUDATA;
366 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
367 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
368 midi->interrupt = snd_emu10k1_midi_interrupt;
369 return 0;
372 int snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
374 struct snd_emu10k1_midi *midi;
375 int err;
377 midi = &emu->midi;
378 if ((err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)")) < 0)
379 return err;
381 midi->tx_enable = INTE_MIDITXENABLE;
382 midi->rx_enable = INTE_MIDIRXENABLE;
383 midi->port = A_MUDATA1;
384 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
385 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
386 midi->interrupt = snd_emu10k1_midi_interrupt;
388 midi = &emu->midi2;
389 if ((err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2")) < 0)
390 return err;
392 midi->tx_enable = INTE_A_MIDITXENABLE2;
393 midi->rx_enable = INTE_A_MIDIRXENABLE2;
394 midi->port = A_MUDATA2;
395 midi->ipr_tx = IPR_A_MIDITRANSBUFEMPTY2;
396 midi->ipr_rx = IPR_A_MIDIRECVBUFEMPTY2;
397 midi->interrupt = snd_emu10k1_midi_interrupt2;
398 return 0;