1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@perex.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. Without interrupt, 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 <asm/io.h> 32 #include <linux/delay.h> 33 #include <linux/init.h> 34 #include <linux/slab.h> 35 #include <linux/ioport.h> 36 #include <linux/module.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@perex.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(struct snd_mpu401 * mpu); 47 static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu); 48 49 /* 50 51 */ 52 53 #define snd_mpu401_input_avail(mpu) \ 54 (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_RX_EMPTY)) 55 #define snd_mpu401_output_ready(mpu) \ 56 (!(mpu->read(mpu, MPU401C(mpu)) & MPU401_TX_FULL)) 57 58 /* Build in lowlevel io */ 59 static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data, 60 unsigned long addr) 61 { 62 outb(data, addr); 63 } 64 65 static unsigned char mpu401_read_port(struct snd_mpu401 *mpu, 66 unsigned long addr) 67 { 68 return inb(addr); 69 } 70 71 static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data, 72 unsigned long addr) 73 { 74 writeb(data, (void __iomem *)addr); 75 } 76 77 static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu, 78 unsigned long addr) 79 { 80 return readb((void __iomem *)addr); 81 } 82 /* */ 83 84 static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu) 85 { 86 int timeout = 100000; 87 for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--) 88 mpu->read(mpu, MPU401D(mpu)); 89 #ifdef CONFIG_SND_DEBUG 90 if (timeout <= 0) 91 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", 92 mpu->read(mpu, MPU401C(mpu))); 93 #endif 94 } 95 96 static void uart_interrupt_tx(struct snd_mpu401 *mpu) 97 { 98 unsigned long flags; 99 100 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 101 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 102 spin_lock_irqsave(&mpu->output_lock, flags); 103 snd_mpu401_uart_output_write(mpu); 104 spin_unlock_irqrestore(&mpu->output_lock, flags); 105 } 106 } 107 108 static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) 109 { 110 unsigned long flags; 111 112 if (mpu->info_flags & MPU401_INFO_INPUT) { 113 spin_lock_irqsave(&mpu->input_lock, flags); 114 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 115 snd_mpu401_uart_input_read(mpu); 116 else 117 snd_mpu401_uart_clear_rx(mpu); 118 spin_unlock_irqrestore(&mpu->input_lock, flags); 119 } 120 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 121 /* ok. for better Tx performance try do some output 122 when input is done */ 123 uart_interrupt_tx(mpu); 124 } 125 126 /** 127 * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler 128 * @irq: the irq number 129 * @dev_id: mpu401 instance 130 * 131 * Processes the interrupt for MPU401-UART i/o. 132 * 133 * Return: %IRQ_HANDLED if the interrupt was handled. %IRQ_NONE otherwise. 134 */ 135 irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id) 136 { 137 struct snd_mpu401 *mpu = dev_id; 138 139 if (mpu == NULL) 140 return IRQ_NONE; 141 _snd_mpu401_uart_interrupt(mpu); 142 return IRQ_HANDLED; 143 } 144 145 EXPORT_SYMBOL(snd_mpu401_uart_interrupt); 146 147 /** 148 * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler 149 * @irq: the irq number 150 * @dev_id: mpu401 instance 151 * 152 * Processes the interrupt for MPU401-UART output. 153 * 154 * Return: %IRQ_HANDLED if the interrupt was handled. %IRQ_NONE otherwise. 155 */ 156 irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id) 157 { 158 struct snd_mpu401 *mpu = dev_id; 159 160 if (mpu == NULL) 161 return IRQ_NONE; 162 uart_interrupt_tx(mpu); 163 return IRQ_HANDLED; 164 } 165 166 EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx); 167 168 /* 169 * timer callback 170 * reprogram the timer and call the interrupt job 171 */ 172 static void snd_mpu401_uart_timer(unsigned long data) 173 { 174 struct snd_mpu401 *mpu = (struct snd_mpu401 *)data; 175 unsigned long flags; 176 177 spin_lock_irqsave(&mpu->timer_lock, flags); 178 /*mpu->mode |= MPU401_MODE_TIMER;*/ 179 mpu->timer.expires = 1 + jiffies; 180 add_timer(&mpu->timer); 181 spin_unlock_irqrestore(&mpu->timer_lock, flags); 182 if (mpu->rmidi) 183 _snd_mpu401_uart_interrupt(mpu); 184 } 185 186 /* 187 * initialize the timer callback if not programmed yet 188 */ 189 static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input) 190 { 191 unsigned long flags; 192 193 spin_lock_irqsave (&mpu->timer_lock, flags); 194 if (mpu->timer_invoked == 0) { 195 init_timer(&mpu->timer); 196 mpu->timer.data = (unsigned long)mpu; 197 mpu->timer.function = snd_mpu401_uart_timer; 198 mpu->timer.expires = 1 + jiffies; 199 add_timer(&mpu->timer); 200 } 201 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : 202 MPU401_MODE_OUTPUT_TIMER; 203 spin_unlock_irqrestore (&mpu->timer_lock, flags); 204 } 205 206 /* 207 * remove the timer callback if still active 208 */ 209 static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input) 210 { 211 unsigned long flags; 212 213 spin_lock_irqsave (&mpu->timer_lock, flags); 214 if (mpu->timer_invoked) { 215 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER : 216 ~MPU401_MODE_OUTPUT_TIMER; 217 if (! mpu->timer_invoked) 218 del_timer(&mpu->timer); 219 } 220 spin_unlock_irqrestore (&mpu->timer_lock, flags); 221 } 222 223 /* 224 * send a UART command 225 * return zero if successful, non-zero for some errors 226 */ 227 228 static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, 229 int ack) 230 { 231 unsigned long flags; 232 int timeout, ok; 233 234 spin_lock_irqsave(&mpu->input_lock, flags); 235 if (mpu->hardware != MPU401_HW_TRID4DWAVE) { 236 mpu->write(mpu, 0x00, MPU401D(mpu)); 237 /*snd_mpu401_uart_clear_rx(mpu);*/ 238 } 239 /* ok. standard MPU-401 initialization */ 240 if (mpu->hardware != MPU401_HW_SB) { 241 for (timeout = 1000; timeout > 0 && 242 !snd_mpu401_output_ready(mpu); timeout--) 243 udelay(10); 244 #ifdef CONFIG_SND_DEBUG 245 if (!timeout) 246 snd_printk(KERN_ERR "cmd: tx timeout (status = 0x%x)\n", 247 mpu->read(mpu, MPU401C(mpu))); 248 #endif 249 } 250 mpu->write(mpu, cmd, MPU401C(mpu)); 251 if (ack && !(mpu->info_flags & MPU401_INFO_NO_ACK)) { 252 ok = 0; 253 timeout = 10000; 254 while (!ok && timeout-- > 0) { 255 if (snd_mpu401_input_avail(mpu)) { 256 if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) 257 ok = 1; 258 } 259 } 260 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) 261 ok = 1; 262 } else 263 ok = 1; 264 spin_unlock_irqrestore(&mpu->input_lock, flags); 265 if (!ok) { 266 snd_printk(KERN_ERR "cmd: 0x%x failed at 0x%lx " 267 "(status = 0x%x, data = 0x%x)\n", cmd, mpu->port, 268 mpu->read(mpu, MPU401C(mpu)), 269 mpu->read(mpu, MPU401D(mpu))); 270 return 1; 271 } 272 return 0; 273 } 274 275 static int snd_mpu401_do_reset(struct snd_mpu401 *mpu) 276 { 277 if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) 278 return -EIO; 279 if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 0)) 280 return -EIO; 281 return 0; 282 } 283 284 /* 285 * input/output open/close - protected by open_mutex in rawmidi.c 286 */ 287 static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream) 288 { 289 struct snd_mpu401 *mpu; 290 int err; 291 292 mpu = substream->rmidi->private_data; 293 if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) 294 return err; 295 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { 296 if (snd_mpu401_do_reset(mpu) < 0) 297 goto error_out; 298 } 299 mpu->substream_input = substream; 300 set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); 301 return 0; 302 303 error_out: 304 if (mpu->open_input && mpu->close_input) 305 mpu->close_input(mpu); 306 return -EIO; 307 } 308 309 static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) 310 { 311 struct snd_mpu401 *mpu; 312 int err; 313 314 mpu = substream->rmidi->private_data; 315 if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) 316 return err; 317 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 318 if (snd_mpu401_do_reset(mpu) < 0) 319 goto error_out; 320 } 321 mpu->substream_output = substream; 322 set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 323 return 0; 324 325 error_out: 326 if (mpu->open_output && mpu->close_output) 327 mpu->close_output(mpu); 328 return -EIO; 329 } 330 331 static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream) 332 { 333 struct snd_mpu401 *mpu; 334 int err = 0; 335 336 mpu = substream->rmidi->private_data; 337 clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); 338 mpu->substream_input = NULL; 339 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) 340 err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 341 if (mpu->close_input) 342 mpu->close_input(mpu); 343 if (err) 344 return -EIO; 345 return 0; 346 } 347 348 static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream) 349 { 350 struct snd_mpu401 *mpu; 351 int err = 0; 352 353 mpu = substream->rmidi->private_data; 354 clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 355 mpu->substream_output = NULL; 356 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 357 err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 358 if (mpu->close_output) 359 mpu->close_output(mpu); 360 if (err) 361 return -EIO; 362 return 0; 363 } 364 365 /* 366 * trigger input callback 367 */ 368 static void 369 snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) 370 { 371 unsigned long flags; 372 struct snd_mpu401 *mpu; 373 int max = 64; 374 375 mpu = substream->rmidi->private_data; 376 if (up) { 377 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, 378 &mpu->mode)) { 379 /* first time - flush FIFO */ 380 while (max-- > 0) 381 mpu->read(mpu, MPU401D(mpu)); 382 if (mpu->info_flags & MPU401_INFO_USE_TIMER) 383 snd_mpu401_uart_add_timer(mpu, 1); 384 } 385 386 /* read data in advance */ 387 spin_lock_irqsave(&mpu->input_lock, flags); 388 snd_mpu401_uart_input_read(mpu); 389 spin_unlock_irqrestore(&mpu->input_lock, flags); 390 } else { 391 if (mpu->info_flags & MPU401_INFO_USE_TIMER) 392 snd_mpu401_uart_remove_timer(mpu, 1); 393 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); 394 } 395 396 } 397 398 /* 399 * transfer input pending data 400 * call with input_lock spinlock held 401 */ 402 static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu) 403 { 404 int max = 128; 405 unsigned char byte; 406 407 while (max-- > 0) { 408 if (! snd_mpu401_input_avail(mpu)) 409 break; /* input not available */ 410 byte = mpu->read(mpu, MPU401D(mpu)); 411 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) 412 snd_rawmidi_receive(mpu->substream_input, &byte, 1); 413 } 414 } 415 416 /* 417 * Tx FIFO sizes: 418 * CS4237B - 16 bytes 419 * AudioDrive ES1688 - 12 bytes 420 * S3 SonicVibes - 8 bytes 421 * SoundBlaster AWE 64 - 2 bytes (ugly hardware) 422 */ 423 424 /* 425 * write output pending bytes 426 * call with output_lock spinlock held 427 */ 428 static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu) 429 { 430 unsigned char byte; 431 int max = 256; 432 433 do { 434 if (snd_rawmidi_transmit_peek(mpu->substream_output, 435 &byte, 1) == 1) { 436 /* 437 * Try twice because there is hardware that insists on 438 * setting the output busy bit after each write. 439 */ 440 if (!snd_mpu401_output_ready(mpu) && 441 !snd_mpu401_output_ready(mpu)) 442 break; /* Tx FIFO full - try again later */ 443 mpu->write(mpu, byte, MPU401D(mpu)); 444 snd_rawmidi_transmit_ack(mpu->substream_output, 1); 445 } else { 446 snd_mpu401_uart_remove_timer (mpu, 0); 447 break; /* no other data - leave the tx loop */ 448 } 449 } while (--max > 0); 450 } 451 452 /* 453 * output trigger callback 454 */ 455 static void 456 snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up) 457 { 458 unsigned long flags; 459 struct snd_mpu401 *mpu; 460 461 mpu = substream->rmidi->private_data; 462 if (up) { 463 set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 464 465 /* try to add the timer at each output trigger, 466 * since the output timer might have been removed in 467 * snd_mpu401_uart_output_write(). 468 */ 469 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 470 snd_mpu401_uart_add_timer(mpu, 0); 471 472 /* output pending data */ 473 spin_lock_irqsave(&mpu->output_lock, flags); 474 snd_mpu401_uart_output_write(mpu); 475 spin_unlock_irqrestore(&mpu->output_lock, flags); 476 } else { 477 if (! (mpu->info_flags & MPU401_INFO_TX_IRQ)) 478 snd_mpu401_uart_remove_timer(mpu, 0); 479 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 480 } 481 } 482 483 /* 484 485 */ 486 487 static struct snd_rawmidi_ops snd_mpu401_uart_output = 488 { 489 .open = snd_mpu401_uart_output_open, 490 .close = snd_mpu401_uart_output_close, 491 .trigger = snd_mpu401_uart_output_trigger, 492 }; 493 494 static struct snd_rawmidi_ops snd_mpu401_uart_input = 495 { 496 .open = snd_mpu401_uart_input_open, 497 .close = snd_mpu401_uart_input_close, 498 .trigger = snd_mpu401_uart_input_trigger, 499 }; 500 501 static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi) 502 { 503 struct snd_mpu401 *mpu = rmidi->private_data; 504 if (mpu->irq >= 0) 505 free_irq(mpu->irq, (void *) mpu); 506 release_and_free_resource(mpu->res); 507 kfree(mpu); 508 } 509 510 /** 511 * snd_mpu401_uart_new - create an MPU401-UART instance 512 * @card: the card instance 513 * @device: the device index, zero-based 514 * @hardware: the hardware type, MPU401_HW_XXXX 515 * @port: the base address of MPU401 port 516 * @info_flags: bitflags MPU401_INFO_XXX 517 * @irq: the ISA irq number, -1 if not to be allocated 518 * @rrawmidi: the pointer to store the new rawmidi instance 519 * 520 * Creates a new MPU-401 instance. 521 * 522 * Note that the rawmidi instance is returned on the rrawmidi argument, 523 * not the mpu401 instance itself. To access to the mpu401 instance, 524 * cast from rawmidi->private_data (with struct snd_mpu401 magic-cast). 525 * 526 * Return: Zero if successful, or a negative error code. 527 */ 528 int snd_mpu401_uart_new(struct snd_card *card, int device, 529 unsigned short hardware, 530 unsigned long port, 531 unsigned int info_flags, 532 int irq, 533 struct snd_rawmidi ** rrawmidi) 534 { 535 struct snd_mpu401 *mpu; 536 struct snd_rawmidi *rmidi; 537 int in_enable, out_enable; 538 int err; 539 540 if (rrawmidi) 541 *rrawmidi = NULL; 542 if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT))) 543 info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT; 544 in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0; 545 out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0; 546 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 547 out_enable, in_enable, &rmidi)) < 0) 548 return err; 549 mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); 550 if (mpu == NULL) { 551 snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n"); 552 snd_device_free(card, rmidi); 553 return -ENOMEM; 554 } 555 rmidi->private_data = mpu; 556 rmidi->private_free = snd_mpu401_uart_free; 557 spin_lock_init(&mpu->input_lock); 558 spin_lock_init(&mpu->output_lock); 559 spin_lock_init(&mpu->timer_lock); 560 mpu->hardware = hardware; 561 mpu->irq = -1; 562 if (! (info_flags & MPU401_INFO_INTEGRATED)) { 563 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 564 mpu->res = request_region(port, res_size, "MPU401 UART"); 565 if (mpu->res == NULL) { 566 snd_printk(KERN_ERR "mpu401_uart: " 567 "unable to grab port 0x%lx size %d\n", 568 port, res_size); 569 snd_device_free(card, rmidi); 570 return -EBUSY; 571 } 572 } 573 if (info_flags & MPU401_INFO_MMIO) { 574 mpu->write = mpu401_write_mmio; 575 mpu->read = mpu401_read_mmio; 576 } else { 577 mpu->write = mpu401_write_port; 578 mpu->read = mpu401_read_port; 579 } 580 mpu->port = port; 581 if (hardware == MPU401_HW_PC98II) 582 mpu->cport = port + 2; 583 else 584 mpu->cport = port + 1; 585 if (irq >= 0) { 586 if (request_irq(irq, snd_mpu401_uart_interrupt, 0, 587 "MPU401 UART", (void *) mpu)) { 588 snd_printk(KERN_ERR "mpu401_uart: " 589 "unable to grab IRQ %d\n", irq); 590 snd_device_free(card, rmidi); 591 return -EBUSY; 592 } 593 } 594 if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK)) 595 info_flags |= MPU401_INFO_USE_TIMER; 596 mpu->info_flags = info_flags; 597 mpu->irq = irq; 598 if (card->shortname[0]) 599 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", 600 card->shortname); 601 else 602 sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device); 603 if (out_enable) { 604 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 605 &snd_mpu401_uart_output); 606 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; 607 } 608 if (in_enable) { 609 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 610 &snd_mpu401_uart_input); 611 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; 612 if (out_enable) 613 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; 614 } 615 mpu->rmidi = rmidi; 616 if (rrawmidi) 617 *rrawmidi = rmidi; 618 return 0; 619 } 620 621 EXPORT_SYMBOL(snd_mpu401_uart_new); 622 623 /* 624 * INIT part 625 */ 626 627 static int __init alsa_mpu401_uart_init(void) 628 { 629 return 0; 630 } 631 632 static void __exit alsa_mpu401_uart_exit(void) 633 { 634 } 635 636 module_init(alsa_mpu401_uart_init) 637 module_exit(alsa_mpu401_uart_exit) 638