0001
0002
0003
0004
0005
0006
0007 #include <linux/time.h>
0008 #include <linux/init.h>
0009 #include <sound/core.h>
0010 #include <sound/emu10k1.h>
0011
0012 #define EMU10K1_MIDI_MODE_INPUT (1<<0)
0013 #define EMU10K1_MIDI_MODE_OUTPUT (1<<1)
0014
0015 static inline unsigned char mpu401_read(struct snd_emu10k1 *emu,
0016 struct snd_emu10k1_midi *mpu, int idx)
0017 {
0018 if (emu->audigy)
0019 return (unsigned char)snd_emu10k1_ptr_read(emu, mpu->port + idx, 0);
0020 else
0021 return inb(emu->port + mpu->port + idx);
0022 }
0023
0024 static inline void mpu401_write(struct snd_emu10k1 *emu,
0025 struct snd_emu10k1_midi *mpu, int data, int idx)
0026 {
0027 if (emu->audigy)
0028 snd_emu10k1_ptr_write(emu, mpu->port + idx, 0, data);
0029 else
0030 outb(data, emu->port + mpu->port + idx);
0031 }
0032
0033 #define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
0034 #define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
0035 #define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
0036 #define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
0037
0038 #define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
0039 #define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
0040
0041 #define MPU401_RESET 0xff
0042 #define MPU401_ENTER_UART 0x3f
0043 #define MPU401_ACK 0xfe
0044
0045 static void mpu401_clear_rx(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *mpu)
0046 {
0047 int timeout = 100000;
0048 for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
0049 mpu401_read_data(emu, mpu);
0050 #ifdef CONFIG_SND_DEBUG
0051 if (timeout <= 0)
0052 dev_err(emu->card->dev,
0053 "cmd: clear rx timeout (status = 0x%x)\n",
0054 mpu401_read_stat(emu, mpu));
0055 #endif
0056 }
0057
0058
0059
0060
0061
0062 static void do_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, unsigned int status)
0063 {
0064 unsigned char byte;
0065
0066 if (midi->rmidi == NULL) {
0067 snd_emu10k1_intr_disable(emu, midi->tx_enable | midi->rx_enable);
0068 return;
0069 }
0070
0071 spin_lock(&midi->input_lock);
0072 if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
0073 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
0074 mpu401_clear_rx(emu, midi);
0075 } else {
0076 byte = mpu401_read_data(emu, midi);
0077 if (midi->substream_input)
0078 snd_rawmidi_receive(midi->substream_input, &byte, 1);
0079 }
0080 }
0081 spin_unlock(&midi->input_lock);
0082
0083 spin_lock(&midi->output_lock);
0084 if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
0085 if (midi->substream_output &&
0086 snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
0087 mpu401_write_data(emu, midi, byte);
0088 } else {
0089 snd_emu10k1_intr_disable(emu, midi->tx_enable);
0090 }
0091 }
0092 spin_unlock(&midi->output_lock);
0093 }
0094
0095 static void snd_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, unsigned int status)
0096 {
0097 do_emu10k1_midi_interrupt(emu, &emu->midi, status);
0098 }
0099
0100 static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int status)
0101 {
0102 do_emu10k1_midi_interrupt(emu, &emu->midi2, status);
0103 }
0104
0105 static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)
0106 {
0107 unsigned long flags;
0108 int timeout, ok;
0109
0110 spin_lock_irqsave(&midi->input_lock, flags);
0111 mpu401_write_data(emu, midi, 0x00);
0112
0113
0114 mpu401_write_cmd(emu, midi, cmd);
0115 if (ack) {
0116 ok = 0;
0117 timeout = 10000;
0118 while (!ok && timeout-- > 0) {
0119 if (mpu401_input_avail(emu, midi)) {
0120 if (mpu401_read_data(emu, midi) == MPU401_ACK)
0121 ok = 1;
0122 }
0123 }
0124 if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
0125 ok = 1;
0126 } else {
0127 ok = 1;
0128 }
0129 spin_unlock_irqrestore(&midi->input_lock, flags);
0130 if (!ok) {
0131 dev_err(emu->card->dev,
0132 "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
0133 cmd, emu->port,
0134 mpu401_read_stat(emu, midi),
0135 mpu401_read_data(emu, midi));
0136 return 1;
0137 }
0138 return 0;
0139 }
0140
0141 static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
0142 {
0143 struct snd_emu10k1 *emu;
0144 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
0145 unsigned long flags;
0146
0147 emu = midi->emu;
0148 if (snd_BUG_ON(!emu))
0149 return -ENXIO;
0150 spin_lock_irqsave(&midi->open_lock, flags);
0151 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
0152 midi->substream_input = substream;
0153 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
0154 spin_unlock_irqrestore(&midi->open_lock, flags);
0155 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
0156 goto error_out;
0157 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
0158 goto error_out;
0159 } else {
0160 spin_unlock_irqrestore(&midi->open_lock, flags);
0161 }
0162 return 0;
0163
0164 error_out:
0165 return -EIO;
0166 }
0167
0168 static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
0169 {
0170 struct snd_emu10k1 *emu;
0171 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
0172 unsigned long flags;
0173
0174 emu = midi->emu;
0175 if (snd_BUG_ON(!emu))
0176 return -ENXIO;
0177 spin_lock_irqsave(&midi->open_lock, flags);
0178 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
0179 midi->substream_output = substream;
0180 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
0181 spin_unlock_irqrestore(&midi->open_lock, flags);
0182 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
0183 goto error_out;
0184 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
0185 goto error_out;
0186 } else {
0187 spin_unlock_irqrestore(&midi->open_lock, flags);
0188 }
0189 return 0;
0190
0191 error_out:
0192 return -EIO;
0193 }
0194
0195 static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
0196 {
0197 struct snd_emu10k1 *emu;
0198 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
0199 unsigned long flags;
0200 int err = 0;
0201
0202 emu = midi->emu;
0203 if (snd_BUG_ON(!emu))
0204 return -ENXIO;
0205 spin_lock_irqsave(&midi->open_lock, flags);
0206 snd_emu10k1_intr_disable(emu, midi->rx_enable);
0207 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
0208 midi->substream_input = NULL;
0209 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
0210 spin_unlock_irqrestore(&midi->open_lock, flags);
0211 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
0212 } else {
0213 spin_unlock_irqrestore(&midi->open_lock, flags);
0214 }
0215 return err;
0216 }
0217
0218 static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
0219 {
0220 struct snd_emu10k1 *emu;
0221 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
0222 unsigned long flags;
0223 int err = 0;
0224
0225 emu = midi->emu;
0226 if (snd_BUG_ON(!emu))
0227 return -ENXIO;
0228 spin_lock_irqsave(&midi->open_lock, flags);
0229 snd_emu10k1_intr_disable(emu, midi->tx_enable);
0230 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
0231 midi->substream_output = NULL;
0232 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
0233 spin_unlock_irqrestore(&midi->open_lock, flags);
0234 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
0235 } else {
0236 spin_unlock_irqrestore(&midi->open_lock, flags);
0237 }
0238 return err;
0239 }
0240
0241 static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
0242 {
0243 struct snd_emu10k1 *emu;
0244 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
0245 emu = midi->emu;
0246 if (snd_BUG_ON(!emu))
0247 return;
0248
0249 if (up)
0250 snd_emu10k1_intr_enable(emu, midi->rx_enable);
0251 else
0252 snd_emu10k1_intr_disable(emu, midi->rx_enable);
0253 }
0254
0255 static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
0256 {
0257 struct snd_emu10k1 *emu;
0258 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
0259 unsigned long flags;
0260
0261 emu = midi->emu;
0262 if (snd_BUG_ON(!emu))
0263 return;
0264
0265 if (up) {
0266 int max = 4;
0267 unsigned char byte;
0268
0269
0270 spin_lock_irqsave(&midi->output_lock, flags);
0271 while (max > 0) {
0272 if (mpu401_output_ready(emu, midi)) {
0273 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
0274 snd_rawmidi_transmit(substream, &byte, 1) != 1) {
0275
0276 spin_unlock_irqrestore(&midi->output_lock, flags);
0277 return;
0278 }
0279 mpu401_write_data(emu, midi, byte);
0280 max--;
0281 } else {
0282 break;
0283 }
0284 }
0285 spin_unlock_irqrestore(&midi->output_lock, flags);
0286 snd_emu10k1_intr_enable(emu, midi->tx_enable);
0287 } else {
0288 snd_emu10k1_intr_disable(emu, midi->tx_enable);
0289 }
0290 }
0291
0292
0293
0294
0295
0296 static const struct snd_rawmidi_ops snd_emu10k1_midi_output =
0297 {
0298 .open = snd_emu10k1_midi_output_open,
0299 .close = snd_emu10k1_midi_output_close,
0300 .trigger = snd_emu10k1_midi_output_trigger,
0301 };
0302
0303 static const struct snd_rawmidi_ops snd_emu10k1_midi_input =
0304 {
0305 .open = snd_emu10k1_midi_input_open,
0306 .close = snd_emu10k1_midi_input_close,
0307 .trigger = snd_emu10k1_midi_input_trigger,
0308 };
0309
0310 static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi)
0311 {
0312 struct snd_emu10k1_midi *midi = rmidi->private_data;
0313 midi->interrupt = NULL;
0314 midi->rmidi = NULL;
0315 }
0316
0317 static int emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, int device, char *name)
0318 {
0319 struct snd_rawmidi *rmidi;
0320 int err;
0321
0322 err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi);
0323 if (err < 0)
0324 return err;
0325 midi->emu = emu;
0326 spin_lock_init(&midi->open_lock);
0327 spin_lock_init(&midi->input_lock);
0328 spin_lock_init(&midi->output_lock);
0329 strcpy(rmidi->name, name);
0330 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1_midi_output);
0331 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1_midi_input);
0332 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
0333 SNDRV_RAWMIDI_INFO_INPUT |
0334 SNDRV_RAWMIDI_INFO_DUPLEX;
0335 rmidi->private_data = midi;
0336 rmidi->private_free = snd_emu10k1_midi_free;
0337 midi->rmidi = rmidi;
0338 return 0;
0339 }
0340
0341 int snd_emu10k1_midi(struct snd_emu10k1 *emu)
0342 {
0343 struct snd_emu10k1_midi *midi = &emu->midi;
0344 int err;
0345
0346 err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)");
0347 if (err < 0)
0348 return err;
0349
0350 midi->tx_enable = INTE_MIDITXENABLE;
0351 midi->rx_enable = INTE_MIDIRXENABLE;
0352 midi->port = MUDATA;
0353 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
0354 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
0355 midi->interrupt = snd_emu10k1_midi_interrupt;
0356 return 0;
0357 }
0358
0359 int snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
0360 {
0361 struct snd_emu10k1_midi *midi;
0362 int err;
0363
0364 midi = &emu->midi;
0365 err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)");
0366 if (err < 0)
0367 return err;
0368
0369 midi->tx_enable = INTE_MIDITXENABLE;
0370 midi->rx_enable = INTE_MIDIRXENABLE;
0371 midi->port = A_MUDATA1;
0372 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
0373 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
0374 midi->interrupt = snd_emu10k1_midi_interrupt;
0375
0376 midi = &emu->midi2;
0377 err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2");
0378 if (err < 0)
0379 return err;
0380
0381 midi->tx_enable = INTE_A_MIDITXENABLE2;
0382 midi->rx_enable = INTE_A_MIDIRXENABLE2;
0383 midi->port = A_MUDATA2;
0384 midi->ipr_tx = IPR_A_MIDITRANSBUFEMPTY2;
0385 midi->ipr_rx = IPR_A_MIDIRECVBUFEMPTY2;
0386 midi->interrupt = snd_emu10k1_midi_interrupt2;
0387 return 0;
0388 }