1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 3 * Routines for control of MPU-401 in UART mode 4 * 5 * MPU-401 supports UART mode which is not capable generate transmit 6 * interrupts thus output is done via polling. Also, if irq < 0, then 7 * input is done also via polling. Do not expect good performance. 8 * 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * 24 * 13-03-2003: 25 * Added support for different kind of hardware I/O. Build in choices 26 * are port and mmio. For other kind of I/O, set mpu->read and 27 * mpu->write to your own I/O functions. 28 * 29 */ 30 31 #include <sound/driver.h> 32 #include <asm/io.h> 33 #include <linux/delay.h> 34 #include <linux/init.h> 35 #include <linux/slab.h> 36 #include <linux/ioport.h> 37 #include <linux/interrupt.h> 38 #include <linux/errno.h> 39 #include <sound/core.h> 40 #include <sound/mpu401.h> 41 42 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); 43 MODULE_DESCRIPTION("Routines for control of MPU-401 in UART mode"); 44 MODULE_LICENSE("GPL"); 45 46 static void snd_mpu401_uart_input_read(mpu401_t * mpu); 47 static void snd_mpu401_uart_output_write(mpu401_t * mpu); 48 49 /* 50 51 */ 52 53 #define snd_mpu401_input_avail(mpu) (!(mpu->read(mpu, MPU401C(mpu)) & 0x80)) 54 #define snd_mpu401_output_ready(mpu) (!(mpu->read(mpu, MPU401C(mpu)) & 0x40)) 55 56 #define MPU401_RESET 0xff 57 #define MPU401_ENTER_UART 0x3f 58 #define MPU401_ACK 0xfe 59 60 /* Build in lowlevel io */ 61 static void mpu401_write_port(mpu401_t *mpu, unsigned char data, unsigned long addr) 62 { 63 outb(data, addr); 64 } 65 66 static unsigned char mpu401_read_port(mpu401_t *mpu, unsigned long addr) 67 { 68 return inb(addr); 69 } 70 71 static void mpu401_write_mmio(mpu401_t *mpu, unsigned char data, unsigned long addr) 72 { 73 writeb(data, (void __iomem *)addr); 74 } 75 76 static unsigned char mpu401_read_mmio(mpu401_t *mpu, unsigned long addr) 77 { 78 return readb((void __iomem *)addr); 79 } 80 /* */ 81 82 static void snd_mpu401_uart_clear_rx(mpu401_t *mpu) 83 { 84 int timeout = 100000; 85 for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--) 86 mpu->read(mpu, MPU401D(mpu)); 87 #ifdef CONFIG_SND_DEBUG 88 if (timeout <= 0) 89 snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 90 #endif 91 } 92 93 static void _snd_mpu401_uart_interrupt(mpu401_t *mpu) 94 { 95 spin_lock(&mpu->input_lock); 96 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 97 snd_mpu401_uart_input_read(mpu); 98 } else { 99 snd_mpu401_uart_clear_rx(mpu); 100 } 101 spin_unlock(&mpu->input_lock); 102 /* ok. for better Tx performance try do some output when input is done */ 103 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 104 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 105 spin_lock(&mpu->output_lock); 106 snd_mpu401_uart_output_write(mpu); 107 spin_unlock(&mpu->output_lock); 108 } 109 } 110 111 /** 112 * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler 113 * @irq: the irq number 114 * @dev_id: mpu401 instance 115 * @regs: the reigster 116 * 117 * Processes the interrupt for MPU401-UART i/o. 118 */ 119 irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs) 120 { 121 mpu401_t *mpu = dev_id; 122 123 if (mpu == NULL) 124 return IRQ_NONE; 125 _snd_mpu401_uart_interrupt(mpu); 126 return IRQ_HANDLED; 127 } 128 129 /* 130 * timer callback 131 * reprogram the timer and call the interrupt job 132 */ 133 static void snd_mpu401_uart_timer(unsigned long data) 134 { 135 mpu401_t *mpu = (mpu401_t *)data; 136 137 spin_lock(&mpu->timer_lock); 138 /*mpu->mode |= MPU401_MODE_TIMER;*/ 139 mpu->timer.expires = 1 + jiffies; 140 add_timer(&mpu->timer); 141 spin_unlock(&mpu->timer_lock); 142 if (mpu->rmidi) 143 _snd_mpu401_uart_interrupt(mpu); 144 } 145 146 /* 147 * initialize the timer callback if not programmed yet 148 */ 149 static void snd_mpu401_uart_add_timer (mpu401_t *mpu, int input) 150 { 151 unsigned long flags; 152 153 spin_lock_irqsave (&mpu->timer_lock, flags); 154 if (mpu->timer_invoked == 0) { 155 init_timer(&mpu->timer); 156 mpu->timer.data = (unsigned long)mpu; 157 mpu->timer.function = snd_mpu401_uart_timer; 158 mpu->timer.expires = 1 + jiffies; 159 add_timer(&mpu->timer); 160 } 161 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : MPU401_MODE_OUTPUT_TIMER; 162 spin_unlock_irqrestore (&mpu->timer_lock, flags); 163 } 164 165 /* 166 * remove the timer callback if still active 167 */ 168 static void snd_mpu401_uart_remove_timer (mpu401_t *mpu, int input) 169 { 170 unsigned long flags; 171 172 spin_lock_irqsave (&mpu->timer_lock, flags); 173 if (mpu->timer_invoked) { 174 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER : ~MPU401_MODE_OUTPUT_TIMER; 175 if (! mpu->timer_invoked) 176 del_timer(&mpu->timer); 177 } 178 spin_unlock_irqrestore (&mpu->timer_lock, flags); 179 } 180 181 /* 182 183 */ 184 185 static void snd_mpu401_uart_cmd(mpu401_t * mpu, unsigned char cmd, int ack) 186 { 187 unsigned long flags; 188 int timeout, ok; 189 190 spin_lock_irqsave(&mpu->input_lock, flags); 191 if (mpu->hardware != MPU401_HW_TRID4DWAVE) { 192 mpu->write(mpu, 0x00, MPU401D(mpu)); 193 /*snd_mpu401_uart_clear_rx(mpu);*/ 194 } 195 /* ok. standard MPU-401 initialization */ 196 if (mpu->hardware != MPU401_HW_SB) { 197 for (timeout = 1000; timeout > 0 && !snd_mpu401_output_ready(mpu); timeout--) 198 udelay(10); 199 #ifdef CONFIG_SND_DEBUG 200 if (!timeout) 201 snd_printk("cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 202 #endif 203 } 204 mpu->write(mpu, cmd, MPU401C(mpu)); 205 if (ack) { 206 ok = 0; 207 timeout = 10000; 208 while (!ok && timeout-- > 0) { 209 if (snd_mpu401_input_avail(mpu)) { 210 if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) 211 ok = 1; 212 } 213 } 214 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) 215 ok = 1; 216 } else { 217 ok = 1; 218 } 219 spin_unlock_irqrestore(&mpu->input_lock, flags); 220 if (! ok) 221 snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); 222 // snd_printk("cmd: 0x%x at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); 223 } 224 225 /* 226 * input/output open/close - protected by open_mutex in rawmidi.c 227 */ 228 static int snd_mpu401_uart_input_open(snd_rawmidi_substream_t * substream) 229 { 230 mpu401_t *mpu; 231 int err; 232 233 mpu = substream->rmidi->private_data; 234 if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) 235 return err; 236 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { 237 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); 238 snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); 239 } 240 mpu->substream_input = substream; 241 set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); 242 return 0; 243 } 244 245 static int snd_mpu401_uart_output_open(snd_rawmidi_substream_t * substream) 246 { 247 mpu401_t *mpu; 248 int err; 249 250 mpu = substream->rmidi->private_data; 251 if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) 252 return err; 253 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 254 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); 255 snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); 256 } 257 mpu->substream_output = substream; 258 set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 259 return 0; 260 } 261 262 static int snd_mpu401_uart_input_close(snd_rawmidi_substream_t * substream) 263 { 264 mpu401_t *mpu; 265 266 mpu = substream->rmidi->private_data; 267 clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); 268 mpu->substream_input = NULL; 269 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) 270 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 271 if (mpu->close_input) 272 mpu->close_input(mpu); 273 return 0; 274 } 275 276 static int snd_mpu401_uart_output_close(snd_rawmidi_substream_t * substream) 277 { 278 mpu401_t *mpu; 279 280 mpu = substream->rmidi->private_data; 281 clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 282 mpu->substream_output = NULL; 283 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 284 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 285 if (mpu->close_output) 286 mpu->close_output(mpu); 287 return 0; 288 } 289 290 /* 291 * trigger input callback 292 */ 293 static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up) 294 { 295 unsigned long flags; 296 mpu401_t *mpu; 297 int max = 64; 298 299 mpu = substream->rmidi->private_data; 300 if (up) { 301 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { 302 /* first time - flush FIFO */ 303 while (max-- > 0) 304 mpu->read(mpu, MPU401D(mpu)); 305 if (mpu->irq < 0) 306 snd_mpu401_uart_add_timer(mpu, 1); 307 } 308 309 /* read data in advance */ 310 spin_lock_irqsave(&mpu->input_lock, flags); 311 snd_mpu401_uart_input_read(mpu); 312 spin_unlock_irqrestore(&mpu->input_lock, flags); 313 } else { 314 if (mpu->irq < 0) 315 snd_mpu401_uart_remove_timer(mpu, 1); 316 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); 317 } 318 } 319 320 /* 321 * transfer input pending data 322 * call with input_lock spinlock held 323 */ 324 static void snd_mpu401_uart_input_read(mpu401_t * mpu) 325 { 326 int max = 128; 327 unsigned char byte; 328 329 while (max-- > 0) { 330 if (snd_mpu401_input_avail(mpu)) { 331 byte = mpu->read(mpu, MPU401D(mpu)); 332 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) 333 snd_rawmidi_receive(mpu->substream_input, &byte, 1); 334 } else { 335 break; /* input not available */ 336 } 337 } 338 } 339 340 /* 341 * Tx FIFO sizes: 342 * CS4237B - 16 bytes 343 * AudioDrive ES1688 - 12 bytes 344 * S3 SonicVibes - 8 bytes 345 * SoundBlaster AWE 64 - 2 bytes (ugly hardware) 346 */ 347 348 /* 349 * write output pending bytes 350 * call with output_lock spinlock held 351 */ 352 static void snd_mpu401_uart_output_write(mpu401_t * mpu) 353 { 354 unsigned char byte; 355 int max = 256, timeout; 356 357 do { 358 if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { 359 for (timeout = 100; timeout > 0; timeout--) { 360 if (snd_mpu401_output_ready(mpu)) { 361 mpu->write(mpu, byte, MPU401D(mpu)); 362 snd_rawmidi_transmit_ack(mpu->substream_output, 1); 363 break; 364 } 365 } 366 if (timeout == 0) 367 break; /* Tx FIFO full - try again later */ 368 } else { 369 snd_mpu401_uart_remove_timer (mpu, 0); 370 break; /* no other data - leave the tx loop */ 371 } 372 } while (--max > 0); 373 } 374 375 /* 376 * output trigger callback 377 */ 378 static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, int up) 379 { 380 unsigned long flags; 381 mpu401_t *mpu; 382 383 mpu = substream->rmidi->private_data; 384 if (up) { 385 set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 386 387 /* try to add the timer at each output trigger, 388 * since the output timer might have been removed in 389 * snd_mpu401_uart_output_write(). 390 */ 391 snd_mpu401_uart_add_timer(mpu, 0); 392 393 /* output pending data */ 394 spin_lock_irqsave(&mpu->output_lock, flags); 395 snd_mpu401_uart_output_write(mpu); 396 spin_unlock_irqrestore(&mpu->output_lock, flags); 397 } else { 398 snd_mpu401_uart_remove_timer(mpu, 0); 399 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 400 } 401 } 402 403 /* 404 405 */ 406 407 static snd_rawmidi_ops_t snd_mpu401_uart_output = 408 { 409 .open = snd_mpu401_uart_output_open, 410 .close = snd_mpu401_uart_output_close, 411 .trigger = snd_mpu401_uart_output_trigger, 412 }; 413 414 static snd_rawmidi_ops_t snd_mpu401_uart_input = 415 { 416 .open = snd_mpu401_uart_input_open, 417 .close = snd_mpu401_uart_input_close, 418 .trigger = snd_mpu401_uart_input_trigger, 419 }; 420 421 static void snd_mpu401_uart_free(snd_rawmidi_t *rmidi) 422 { 423 mpu401_t *mpu = rmidi->private_data; 424 if (mpu->irq_flags && mpu->irq >= 0) 425 free_irq(mpu->irq, (void *) mpu); 426 if (mpu->res) { 427 release_resource(mpu->res); 428 kfree_nocheck(mpu->res); 429 } 430 kfree(mpu); 431 } 432 433 /** 434 * snd_mpu401_uart_new - create an MPU401-UART instance 435 * @card: the card instance 436 * @device: the device index, zero-based 437 * @hardware: the hardware type, MPU401_HW_XXXX 438 * @port: the base address of MPU401 port 439 * @integrated: non-zero if the port was already reserved by the chip 440 * @irq: the irq number, -1 if no interrupt for mpu 441 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved. 442 * @rrawmidi: the pointer to store the new rawmidi instance 443 * 444 * Creates a new MPU-401 instance. 445 * 446 * Note that the rawmidi instance is returned on the rrawmidi argument, 447 * not the mpu401 instance itself. To access to the mpu401 instance, 448 * cast from rawmidi->private_data (with mpu401_t magic-cast). 449 * 450 * Returns zero if successful, or a negative error code. 451 */ 452 int snd_mpu401_uart_new(snd_card_t * card, int device, 453 unsigned short hardware, 454 unsigned long port, int integrated, 455 int irq, int irq_flags, 456 snd_rawmidi_t ** rrawmidi) 457 { 458 mpu401_t *mpu; 459 snd_rawmidi_t *rmidi; 460 int err; 461 462 if (rrawmidi) 463 *rrawmidi = NULL; 464 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0) 465 return err; 466 mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL); 467 if (mpu == NULL) { 468 snd_device_free(card, rmidi); 469 return -ENOMEM; 470 } 471 rmidi->private_data = mpu; 472 rmidi->private_free = snd_mpu401_uart_free; 473 spin_lock_init(&mpu->input_lock); 474 spin_lock_init(&mpu->output_lock); 475 spin_lock_init(&mpu->timer_lock); 476 mpu->hardware = hardware; 477 if (!integrated) { 478 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 479 if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) { 480 snd_printk(KERN_ERR "mpu401_uart: unable to grab port 0x%lx size %d\n", port, res_size); 481 snd_device_free(card, rmidi); 482 return -EBUSY; 483 } 484 } 485 switch (hardware) { 486 case MPU401_HW_AUREAL: 487 mpu->write = mpu401_write_mmio; 488 mpu->read = mpu401_read_mmio; 489 break; 490 default: 491 mpu->write = mpu401_write_port; 492 mpu->read = mpu401_read_port; 493 break; 494 } 495 mpu->port = port; 496 if (hardware == MPU401_HW_PC98II) 497 mpu->cport = port + 2; 498 else 499 mpu->cport = port + 1; 500 if (irq >= 0 && irq_flags) { 501 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) { 502 snd_printk(KERN_ERR "mpu401_uart: unable to grab IRQ %d\n", irq); 503 snd_device_free(card, rmidi); 504 return -EBUSY; 505 } 506 } 507 mpu->irq = irq; 508 mpu->irq_flags = irq_flags; 509 if (card->shortname[0]) 510 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", card->shortname); 511 else 512 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 513 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); 514 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); 515 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 516 SNDRV_RAWMIDI_INFO_INPUT | 517 SNDRV_RAWMIDI_INFO_DUPLEX; 518 mpu->rmidi = rmidi; 519 if (rrawmidi) 520 *rrawmidi = rmidi; 521 return 0; 522 } 523 524 EXPORT_SYMBOL(snd_mpu401_uart_interrupt); 525 EXPORT_SYMBOL(snd_mpu401_uart_new); 526 527 /* 528 * INIT part 529 */ 530 531 static int __init alsa_mpu401_uart_init(void) 532 { 533 return 0; 534 } 535 536 static void __exit alsa_mpu401_uart_exit(void) 537 { 538 } 539 540 module_init(alsa_mpu401_uart_init) 541 module_exit(alsa_mpu401_uart_exit) 542