1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 4 * Routines for control of EMU10K1 MPU-401 in UART mode 5 */ 6 7 #include <linux/time.h> 8 #include <linux/init.h> 9 #include <sound/core.h> 10 #include <sound/emu10k1.h> 11 12 #define EMU10K1_MIDI_MODE_INPUT (1<<0) 13 #define EMU10K1_MIDI_MODE_OUTPUT (1<<1) 14 15 static inline unsigned char mpu401_read(struct snd_emu10k1 *emu, 16 struct snd_emu10k1_midi *mpu, int idx) 17 { 18 if (emu->audigy) 19 return (unsigned char)snd_emu10k1_ptr_read(emu, mpu->port + idx, 0); 20 else 21 return inb(emu->port + mpu->port + idx); 22 } 23 24 static inline void mpu401_write(struct snd_emu10k1 *emu, 25 struct snd_emu10k1_midi *mpu, int data, int idx) 26 { 27 if (emu->audigy) 28 snd_emu10k1_ptr_write(emu, mpu->port + idx, 0, data); 29 else 30 outb(data, emu->port + mpu->port + idx); 31 } 32 33 #define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0) 34 #define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1) 35 #define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0) 36 #define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1) 37 38 #define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80)) 39 #define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40)) 40 41 #define MPU401_RESET 0xff 42 #define MPU401_ENTER_UART 0x3f 43 #define MPU401_ACK 0xfe 44 45 static void mpu401_clear_rx(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *mpu) 46 { 47 int timeout = 100000; 48 for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--) 49 mpu401_read_data(emu, mpu); 50 #ifdef CONFIG_SND_DEBUG 51 if (timeout <= 0) 52 dev_err(emu->card->dev, 53 "cmd: clear rx timeout (status = 0x%x)\n", 54 mpu401_read_stat(emu, mpu)); 55 #endif 56 } 57 58 /* 59 60 */ 61 62 static void do_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, unsigned int status) 63 { 64 unsigned char byte; 65 66 if (midi->rmidi == NULL) { 67 snd_emu10k1_intr_disable(emu, midi->tx_enable | midi->rx_enable); 68 return; 69 } 70 71 scoped_guard(spinlock, &midi->input_lock) { 72 if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) { 73 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) { 74 mpu401_clear_rx(emu, midi); 75 } else { 76 byte = mpu401_read_data(emu, midi); 77 if (midi->substream_input) 78 snd_rawmidi_receive(midi->substream_input, &byte, 1); 79 } 80 } 81 } 82 83 scoped_guard(spinlock, &midi->output_lock) { 84 if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) { 85 if (midi->substream_output && 86 snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) { 87 mpu401_write_data(emu, midi, byte); 88 } else { 89 snd_emu10k1_intr_disable(emu, midi->tx_enable); 90 } 91 } 92 } 93 } 94 95 static void snd_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, unsigned int status) 96 { 97 do_emu10k1_midi_interrupt(emu, &emu->midi, status); 98 } 99 100 static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int status) 101 { 102 do_emu10k1_midi_interrupt(emu, &emu->midi2, status); 103 } 104 105 static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack) 106 { 107 int timeout, ok; 108 109 scoped_guard(spinlock_irq, &midi->input_lock) { 110 mpu401_write_data(emu, midi, 0x00); 111 /* mpu401_clear_rx(emu, midi); */ 112 113 mpu401_write_cmd(emu, midi, cmd); 114 if (ack) { 115 ok = 0; 116 timeout = 10000; 117 while (!ok && timeout-- > 0) { 118 if (mpu401_input_avail(emu, midi)) { 119 if (mpu401_read_data(emu, midi) == MPU401_ACK) 120 ok = 1; 121 } 122 } 123 if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK) 124 ok = 1; 125 } else { 126 ok = 1; 127 } 128 } 129 if (!ok) { 130 dev_err(emu->card->dev, 131 "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n", 132 cmd, emu->port, 133 mpu401_read_stat(emu, midi), 134 mpu401_read_data(emu, midi)); 135 return 1; 136 } 137 return 0; 138 } 139 140 static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream) 141 { 142 struct snd_emu10k1 *emu; 143 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; 144 145 emu = midi->emu; 146 if (snd_BUG_ON(!emu)) 147 return -ENXIO; 148 scoped_guard(spinlock_irq, &midi->open_lock) { 149 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT; 150 midi->substream_input = substream; 151 if (midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) 152 return 0; 153 } 154 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1)) 155 return -EIO; 156 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1)) 157 return -EIO; 158 return 0; 159 } 160 161 static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream) 162 { 163 struct snd_emu10k1 *emu; 164 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; 165 166 emu = midi->emu; 167 if (snd_BUG_ON(!emu)) 168 return -ENXIO; 169 scoped_guard(spinlock_irq, &midi->open_lock) { 170 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT; 171 midi->substream_output = substream; 172 if (midi->midi_mode & EMU10K1_MIDI_MODE_INPUT) 173 return 0; 174 } 175 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1)) 176 return -EIO; 177 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1)) 178 return -EIO; 179 return 0; 180 } 181 182 static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) 183 { 184 struct snd_emu10k1 *emu; 185 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; 186 187 emu = midi->emu; 188 if (snd_BUG_ON(!emu)) 189 return -ENXIO; 190 scoped_guard(spinlock_irq, &midi->open_lock) { 191 snd_emu10k1_intr_disable(emu, midi->rx_enable); 192 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT; 193 midi->substream_input = NULL; 194 if (midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) 195 return 0; 196 } 197 return snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); 198 } 199 200 static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream) 201 { 202 struct snd_emu10k1 *emu; 203 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; 204 205 emu = midi->emu; 206 if (snd_BUG_ON(!emu)) 207 return -ENXIO; 208 scoped_guard(spinlock_irq, &midi->open_lock) { 209 snd_emu10k1_intr_disable(emu, midi->tx_enable); 210 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT; 211 midi->substream_output = NULL; 212 if (midi->midi_mode & EMU10K1_MIDI_MODE_INPUT) 213 return 0; 214 } 215 return snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0); 216 } 217 218 static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) 219 { 220 struct snd_emu10k1 *emu; 221 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; 222 emu = midi->emu; 223 if (snd_BUG_ON(!emu)) 224 return; 225 226 if (up) 227 snd_emu10k1_intr_enable(emu, midi->rx_enable); 228 else 229 snd_emu10k1_intr_disable(emu, midi->rx_enable); 230 } 231 232 static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) 233 { 234 struct snd_emu10k1 *emu; 235 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; 236 237 emu = midi->emu; 238 if (snd_BUG_ON(!emu)) 239 return; 240 241 if (up) { 242 int max = 4; 243 unsigned char byte; 244 245 /* try to send some amount of bytes here before interrupts */ 246 scoped_guard(spinlock_irq, &midi->output_lock) { 247 while (max > 0) { 248 if (mpu401_output_ready(emu, midi)) { 249 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) || 250 snd_rawmidi_transmit(substream, &byte, 1) != 1) { 251 /* no more data */ 252 return; 253 } 254 mpu401_write_data(emu, midi, byte); 255 max--; 256 } else { 257 break; 258 } 259 } 260 } 261 snd_emu10k1_intr_enable(emu, midi->tx_enable); 262 } else { 263 snd_emu10k1_intr_disable(emu, midi->tx_enable); 264 } 265 } 266 267 /* 268 269 */ 270 271 static const struct snd_rawmidi_ops snd_emu10k1_midi_output = 272 { 273 .open = snd_emu10k1_midi_output_open, 274 .close = snd_emu10k1_midi_output_close, 275 .trigger = snd_emu10k1_midi_output_trigger, 276 }; 277 278 static const struct snd_rawmidi_ops snd_emu10k1_midi_input = 279 { 280 .open = snd_emu10k1_midi_input_open, 281 .close = snd_emu10k1_midi_input_close, 282 .trigger = snd_emu10k1_midi_input_trigger, 283 }; 284 285 static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi) 286 { 287 struct snd_emu10k1_midi *midi = rmidi->private_data; 288 midi->interrupt = NULL; 289 midi->rmidi = NULL; 290 } 291 292 static int emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, int device, char *name) 293 { 294 struct snd_rawmidi *rmidi; 295 int err; 296 297 err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi); 298 if (err < 0) 299 return err; 300 midi->emu = emu; 301 spin_lock_init(&midi->open_lock); 302 spin_lock_init(&midi->input_lock); 303 spin_lock_init(&midi->output_lock); 304 strscpy(rmidi->name, name); 305 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1_midi_output); 306 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1_midi_input); 307 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 308 SNDRV_RAWMIDI_INFO_INPUT | 309 SNDRV_RAWMIDI_INFO_DUPLEX; 310 rmidi->private_data = midi; 311 rmidi->private_free = snd_emu10k1_midi_free; 312 midi->rmidi = rmidi; 313 return 0; 314 } 315 316 int snd_emu10k1_midi(struct snd_emu10k1 *emu) 317 { 318 struct snd_emu10k1_midi *midi = &emu->midi; 319 int err; 320 321 err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)"); 322 if (err < 0) 323 return err; 324 325 midi->tx_enable = INTE_MIDITXENABLE; 326 midi->rx_enable = INTE_MIDIRXENABLE; 327 midi->port = MUDATA; 328 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY; 329 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY; 330 midi->interrupt = snd_emu10k1_midi_interrupt; 331 return 0; 332 } 333 334 int snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu) 335 { 336 struct snd_emu10k1_midi *midi; 337 int err; 338 339 midi = &emu->midi; 340 err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)"); 341 if (err < 0) 342 return err; 343 344 midi->tx_enable = INTE_MIDITXENABLE; 345 midi->rx_enable = INTE_MIDIRXENABLE; 346 midi->port = A_MUDATA1; 347 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY; 348 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY; 349 midi->interrupt = snd_emu10k1_midi_interrupt; 350 351 midi = &emu->midi2; 352 err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2"); 353 if (err < 0) 354 return err; 355 356 midi->tx_enable = INTE_A_MIDITXENABLE2; 357 midi->rx_enable = INTE_A_MIDIRXENABLE2; 358 midi->port = A_MUDATA2; 359 midi->ipr_tx = IPR_A_MIDITRANSBUFEMPTY2; 360 midi->ipr_rx = IPR_A_MIDIRECVBUFEMPTY2; 361 midi->interrupt = snd_emu10k1_midi_interrupt2; 362 return 0; 363 } 364