aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c108
1 files changed, 66 insertions, 42 deletions
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index b49a45cbf67a..cd64d3eb9ec8 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -58,22 +58,26 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu);
58#define MPU401_ACK 0xfe 58#define MPU401_ACK 0xfe
59 59
60/* Build in lowlevel io */ 60/* Build in lowlevel io */
61static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 61static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data,
62 unsigned long addr)
62{ 63{
63 outb(data, addr); 64 outb(data, addr);
64} 65}
65 66
66static unsigned char mpu401_read_port(struct snd_mpu401 *mpu, unsigned long addr) 67static unsigned char mpu401_read_port(struct snd_mpu401 *mpu,
68 unsigned long addr)
67{ 69{
68 return inb(addr); 70 return inb(addr);
69} 71}
70 72
71static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 73static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data,
74 unsigned long addr)
72{ 75{
73 writeb(data, (void __iomem *)addr); 76 writeb(data, (void __iomem *)addr);
74} 77}
75 78
76static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu, unsigned long addr) 79static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu,
80 unsigned long addr)
77{ 81{
78 return readb((void __iomem *)addr); 82 return readb((void __iomem *)addr);
79} 83}
@@ -86,20 +90,22 @@ static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
86 mpu->read(mpu, MPU401D(mpu)); 90 mpu->read(mpu, MPU401D(mpu));
87#ifdef CONFIG_SND_DEBUG 91#ifdef CONFIG_SND_DEBUG
88 if (timeout <= 0) 92 if (timeout <= 0)
89 snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 93 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n",
94 mpu->read(mpu, MPU401C(mpu)));
90#endif 95#endif
91} 96}
92 97
93static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) 98static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
94{ 99{
95 spin_lock(&mpu->input_lock); 100 spin_lock(&mpu->input_lock);
96 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 101 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
97 snd_mpu401_uart_input_read(mpu); 102 snd_mpu401_uart_input_read(mpu);
98 } else { 103 else
99 snd_mpu401_uart_clear_rx(mpu); 104 snd_mpu401_uart_clear_rx(mpu);
100 }
101 spin_unlock(&mpu->input_lock); 105 spin_unlock(&mpu->input_lock);
102 /* ok. for better Tx performance try do some output when input is done */ 106 /* ok. for better Tx performance try do some output when
107 * input is done
108 */
103 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 109 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
104 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 110 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
105 spin_lock(&mpu->output_lock); 111 spin_lock(&mpu->output_lock);
@@ -116,7 +122,8 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
116 * 122 *
117 * Processes the interrupt for MPU401-UART i/o. 123 * Processes the interrupt for MPU401-UART i/o.
118 */ 124 */
119irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs) 125irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
126 struct pt_regs *regs)
120{ 127{
121 struct snd_mpu401 *mpu = dev_id; 128 struct snd_mpu401 *mpu = dev_id;
122 129
@@ -126,6 +133,8 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg
126 return IRQ_HANDLED; 133 return IRQ_HANDLED;
127} 134}
128 135
136EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
137
129/* 138/*
130 * timer callback 139 * timer callback
131 * reprogram the timer and call the interrupt job 140 * reprogram the timer and call the interrupt job
@@ -159,7 +168,8 @@ static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
159 mpu->timer.expires = 1 + jiffies; 168 mpu->timer.expires = 1 + jiffies;
160 add_timer(&mpu->timer); 169 add_timer(&mpu->timer);
161 } 170 }
162 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER : MPU401_MODE_OUTPUT_TIMER; 171 mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :
172 MPU401_MODE_OUTPUT_TIMER;
163 spin_unlock_irqrestore (&mpu->timer_lock, flags); 173 spin_unlock_irqrestore (&mpu->timer_lock, flags);
164} 174}
165 175
@@ -172,7 +182,8 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
172 182
173 spin_lock_irqsave (&mpu->timer_lock, flags); 183 spin_lock_irqsave (&mpu->timer_lock, flags);
174 if (mpu->timer_invoked) { 184 if (mpu->timer_invoked) {
175 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER : ~MPU401_MODE_OUTPUT_TIMER; 185 mpu->timer_invoked &= input ? ~MPU401_MODE_INPUT_TIMER :
186 ~MPU401_MODE_OUTPUT_TIMER;
176 if (! mpu->timer_invoked) 187 if (! mpu->timer_invoked)
177 del_timer(&mpu->timer); 188 del_timer(&mpu->timer);
178 } 189 }
@@ -180,11 +191,12 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
180} 191}
181 192
182/* 193/*
183 194 * send a UART command
195 * return zero if successful, non-zero for some errors
184 */ 196 */
185 197
186static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, 198static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
187 int ack) 199 int ack)
188{ 200{
189 unsigned long flags; 201 unsigned long flags;
190 int timeout, ok; 202 int timeout, ok;
@@ -196,11 +208,13 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
196 } 208 }
197 /* ok. standard MPU-401 initialization */ 209 /* ok. standard MPU-401 initialization */
198 if (mpu->hardware != MPU401_HW_SB) { 210 if (mpu->hardware != MPU401_HW_SB) {
199 for (timeout = 1000; timeout > 0 && !snd_mpu401_output_ready(mpu); timeout--) 211 for (timeout = 1000; timeout > 0 &&
212 !snd_mpu401_output_ready(mpu); timeout--)
200 udelay(10); 213 udelay(10);
201#ifdef CONFIG_SND_DEBUG 214#ifdef CONFIG_SND_DEBUG
202 if (!timeout) 215 if (!timeout)
203 snd_printk("cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 216 snd_printk(KERN_ERR "cmd: tx timeout (status = 0x%x)\n",
217 mpu->read(mpu, MPU401C(mpu)));
204#endif 218#endif
205 } 219 }
206 mpu->write(mpu, cmd, MPU401C(mpu)); 220 mpu->write(mpu, cmd, MPU401C(mpu));
@@ -215,12 +229,14 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
215 } 229 }
216 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK) 230 if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
217 ok = 1; 231 ok = 1;
218 } else { 232 } else
219 ok = 1; 233 ok = 1;
220 }
221 spin_unlock_irqrestore(&mpu->input_lock, flags); 234 spin_unlock_irqrestore(&mpu->input_lock, flags);
222 if (!ok) { 235 if (!ok) {
223 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))); 236 snd_printk(KERN_ERR "cmd: 0x%x failed at 0x%lx "
237 "(status = 0x%x, data = 0x%x)\n", cmd, mpu->port,
238 mpu->read(mpu, MPU401C(mpu)),
239 mpu->read(mpu, MPU401D(mpu)));
224 return 1; 240 return 1;
225 } 241 }
226 return 0; 242 return 0;
@@ -314,7 +330,8 @@ static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
314/* 330/*
315 * trigger input callback 331 * trigger input callback
316 */ 332 */
317static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) 333static void
334snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
318{ 335{
319 unsigned long flags; 336 unsigned long flags;
320 struct snd_mpu401 *mpu; 337 struct snd_mpu401 *mpu;
@@ -322,7 +339,8 @@ static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substrea
322 339
323 mpu = substream->rmidi->private_data; 340 mpu = substream->rmidi->private_data;
324 if (up) { 341 if (up) {
325 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { 342 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER,
343 &mpu->mode)) {
326 /* first time - flush FIFO */ 344 /* first time - flush FIFO */
327 while (max-- > 0) 345 while (max-- > 0)
328 mpu->read(mpu, MPU401D(mpu)); 346 mpu->read(mpu, MPU401D(mpu));
@@ -352,13 +370,11 @@ static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu)
352 unsigned char byte; 370 unsigned char byte;
353 371
354 while (max-- > 0) { 372 while (max-- > 0) {
355 if (snd_mpu401_input_avail(mpu)) { 373 if (! snd_mpu401_input_avail(mpu))
356 byte = mpu->read(mpu, MPU401D(mpu));
357 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
358 snd_rawmidi_receive(mpu->substream_input, &byte, 1);
359 } else {
360 break; /* input not available */ 374 break; /* input not available */
361 } 375 byte = mpu->read(mpu, MPU401D(mpu));
376 if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
377 snd_rawmidi_receive(mpu->substream_input, &byte, 1);
362 } 378 }
363} 379}
364 380
@@ -380,16 +396,16 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
380 int max = 256, timeout; 396 int max = 256, timeout;
381 397
382 do { 398 do {
383 if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { 399 if (snd_rawmidi_transmit_peek(mpu->substream_output,
400 &byte, 1) == 1) {
384 for (timeout = 100; timeout > 0; timeout--) { 401 for (timeout = 100; timeout > 0; timeout--) {
385 if (snd_mpu401_output_ready(mpu)) { 402 if (snd_mpu401_output_ready(mpu))
386 mpu->write(mpu, byte, MPU401D(mpu));
387 snd_rawmidi_transmit_ack(mpu->substream_output, 1);
388 break; 403 break;
389 }
390 } 404 }
391 if (timeout == 0) 405 if (timeout == 0)
392 break; /* Tx FIFO full - try again later */ 406 break; /* Tx FIFO full - try again later */
407 mpu->write(mpu, byte, MPU401D(mpu));
408 snd_rawmidi_transmit_ack(mpu->substream_output, 1);
393 } else { 409 } else {
394 snd_mpu401_uart_remove_timer (mpu, 0); 410 snd_mpu401_uart_remove_timer (mpu, 0);
395 break; /* no other data - leave the tx loop */ 411 break; /* no other data - leave the tx loop */
@@ -400,7 +416,8 @@ static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
400/* 416/*
401 * output trigger callback 417 * output trigger callback
402 */ 418 */
403static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up) 419static void
420snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
404{ 421{
405 unsigned long flags; 422 unsigned long flags;
406 struct snd_mpu401 *mpu; 423 struct snd_mpu401 *mpu;
@@ -499,8 +516,11 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
499 mpu->hardware = hardware; 516 mpu->hardware = hardware;
500 if (!integrated) { 517 if (!integrated) {
501 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 518 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
502 if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) { 519 mpu->res = request_region(port, res_size, "MPU401 UART");
503 snd_printk(KERN_ERR "mpu401_uart: unable to grab port 0x%lx size %d\n", port, res_size); 520 if (mpu->res == NULL) {
521 snd_printk(KERN_ERR "mpu401_uart: "
522 "unable to grab port 0x%lx size %d\n",
523 port, res_size);
504 snd_device_free(card, rmidi); 524 snd_device_free(card, rmidi);
505 return -EBUSY; 525 return -EBUSY;
506 } 526 }
@@ -521,8 +541,10 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
521 else 541 else
522 mpu->cport = port + 1; 542 mpu->cport = port + 1;
523 if (irq >= 0 && irq_flags) { 543 if (irq >= 0 && irq_flags) {
524 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) { 544 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags,
525 snd_printk(KERN_ERR "mpu401_uart: unable to grab IRQ %d\n", irq); 545 "MPU401 UART", (void *) mpu)) {
546 snd_printk(KERN_ERR "mpu401_uart: "
547 "unable to grab IRQ %d\n", irq);
526 snd_device_free(card, rmidi); 548 snd_device_free(card, rmidi);
527 return -EBUSY; 549 return -EBUSY;
528 } 550 }
@@ -530,11 +552,14 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
530 mpu->irq = irq; 552 mpu->irq = irq;
531 mpu->irq_flags = irq_flags; 553 mpu->irq_flags = irq_flags;
532 if (card->shortname[0]) 554 if (card->shortname[0])
533 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", card->shortname); 555 snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
556 card->shortname);
534 else 557 else
535 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 558 sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device);
536 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); 559 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
537 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); 560 &snd_mpu401_uart_output);
561 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
562 &snd_mpu401_uart_input);
538 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 563 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
539 SNDRV_RAWMIDI_INFO_INPUT | 564 SNDRV_RAWMIDI_INFO_INPUT |
540 SNDRV_RAWMIDI_INFO_DUPLEX; 565 SNDRV_RAWMIDI_INFO_DUPLEX;
@@ -544,7 +569,6 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
544 return 0; 569 return 0;
545} 570}
546 571
547EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
548EXPORT_SYMBOL(snd_mpu401_uart_new); 572EXPORT_SYMBOL(snd_mpu401_uart_new);
549 573
550/* 574/*