Changeset 34 for GPL/trunk/alsa-kernel/drivers/mpu401
- Timestamp:
- Dec 11, 2005, 5:57:39 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/alsa-kernel/drivers/mpu401/mpu401_uart.c
r33 r34 29 29 */ 30 30 31 #define SNDRV_MAIN_OBJECT_FILE32 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> 33 40 #include <sound/mpu401.h> 34 41 … … 37 44 MODULE_LICENSE("GPL"); 38 45 39 static void snd_mpu401_uart_input_read( mpu401_t* mpu);40 static void snd_mpu401_uart_output_write( mpu401_t* mpu);41 42 /* 43 44 */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 */ 45 52 46 53 #define snd_mpu401_input_avail(mpu) (!(mpu->read(mpu, MPU401C(mpu)) & 0x80)) … … 52 59 53 60 /* Build in lowlevel io */ 54 static void mpu401_write_port( mpu401_t*mpu, unsigned char data, unsigned long addr)55 { 56 57 } 58 59 static unsigned char mpu401_read_port( mpu401_t*mpu, unsigned long addr)60 { 61 62 } 63 64 static void mpu401_write_mmio( mpu401_t*mpu, unsigned char data, unsigned long addr)65 { 66 writeb(data, (unsigned long*)addr);67 } 68 69 static unsigned char mpu401_read_mmio( mpu401_t*mpu, unsigned long addr)70 { 71 return readb((unsigned long*)addr);61 static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 62 { 63 outb(data, addr); 64 } 65 66 static unsigned char mpu401_read_port(struct snd_mpu401 *mpu, unsigned long addr) 67 { 68 return inb(addr); 69 } 70 71 static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr) 72 { 73 writeb(data, (void __iomem *)addr); 74 } 75 76 static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu, unsigned long addr) 77 { 78 return readb((void __iomem *)addr); 72 79 } 73 80 /* */ 74 81 75 static void snd_mpu401_uart_clear_rx( mpu401_t*mpu)76 { 77 78 79 82 static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu) 83 { 84 int timeout = 100000; 85 for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--) 86 mpu->read(mpu, MPU401D(mpu)); 80 87 #ifdef CONFIG_SND_DEBUG 81 82 88 if (timeout <= 0) 89 snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 83 90 #endif 84 91 } 85 92 86 static void _snd_mpu401_uart_interrupt(mpu401_t *mpu) 87 { 88 spin_lock(&mpu->input_lock); 89 if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { 90 atomic_dec(&mpu->rx_loop); 91 snd_mpu401_uart_input_read(mpu); 92 atomic_inc(&mpu->rx_loop); 93 } else { 94 snd_mpu401_uart_clear_rx(mpu); 95 } 96 spin_unlock(&mpu->input_lock); 97 /* ok. for better Tx performance try do some output when input is done */ 98 if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && 99 test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { 100 if (spin_trylock(&mpu->output_lock)) { 101 atomic_dec(&mpu->tx_loop); 102 snd_mpu401_uart_output_write(mpu); 103 atomic_inc(&mpu->tx_loop); 104 spin_unlock(&mpu->output_lock); 105 } 106 } 107 93 static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *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 } 108 109 } 109 110 … … 118 119 irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs) 119 120 { 120 mpu401_t*mpu = dev_id;121 122 123 124 125 121 struct snd_mpu401 *mpu = dev_id; 122 123 if (mpu == NULL) 124 return IRQ_NONE; 125 _snd_mpu401_uart_interrupt(mpu); 126 return IRQ_HANDLED; 126 127 } 127 128 … … 132 133 static void snd_mpu401_uart_timer(unsigned long data) 133 134 { 134 mpu401_t *mpu = (mpu401_t*)data;135 136 137 138 139 140 141 142 135 struct snd_mpu401 *mpu = (struct snd_mpu401 *)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); 143 144 } 144 145 … … 146 147 * initialize the timer callback if not programmed yet 147 148 */ 148 static void snd_mpu401_uart_add_timer ( mpu401_t*mpu, int input)149 { 150 151 152 153 154 155 156 157 158 159 } 160 161 149 static void snd_mpu401_uart_add_timer (struct snd_mpu401 *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); 162 163 } 163 164 … … 165 166 * remove the timer callback if still active 166 167 */ 167 static void snd_mpu401_uart_remove_timer ( mpu401_t*mpu, int input)168 { 169 170 171 172 173 174 175 176 177 178 } 179 180 /* 181 182 */183 184 static void snd_mpu401_uart_cmd( mpu401_t* mpu, unsigned char cmd, int ack)185 { 186 187 188 189 190 191 192 193 194 195 196 197 168 static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *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(struct snd_mpu401 * 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); 198 199 #ifdef CONFIG_SND_DEBUG 199 200 200 if (!timeout) 201 snd_printk("cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu))); 201 202 #endif 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 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))); 222 223 } 223 224 … … 225 226 * input/output open/close - protected by open_mutex in rawmidi.c 226 227 */ 227 static int snd_mpu401_uart_input_open(snd_rawmidi_substream_t * substream) 228 { 229 mpu401_t *mpu; 230 int err; 231 232 mpu = substream->rmidi->private_data; 233 if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) 234 return err; 235 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { 236 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); 237 snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); 238 } 239 mpu->substream_input = substream; 240 atomic_set(&mpu->rx_loop, 1); 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 atomic_set(&mpu->tx_loop, 1); 259 set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 260 return 0; 261 } 262 263 static int snd_mpu401_uart_input_close(snd_rawmidi_substream_t * substream) 264 { 265 mpu401_t *mpu; 266 267 mpu = substream->rmidi->private_data; 268 clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); 269 mpu->substream_input = NULL; 270 if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) 271 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 272 if (mpu->close_input) 273 mpu->close_input(mpu); 274 return 0; 275 } 276 277 static int snd_mpu401_uart_output_close(snd_rawmidi_substream_t * substream) 278 { 279 mpu401_t *mpu; 280 281 mpu = substream->rmidi->private_data; 282 clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); 283 mpu->substream_output = NULL; 284 if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) 285 snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); 286 if (mpu->close_output) 287 mpu->close_output(mpu); 288 return 0; 228 static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream) 229 { 230 struct snd_mpu401 *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(struct snd_rawmidi_substream *substream) 246 { 247 struct snd_mpu401 *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(struct snd_rawmidi_substream *substream) 263 { 264 struct snd_mpu401 *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(struct snd_rawmidi_substream *substream) 277 { 278 struct snd_mpu401 *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; 289 288 } 290 289 … … 292 291 * trigger input callback 293 292 */ 294 static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up) 295 { 296 u32 flags; 297 mpu401_t *mpu; 298 int max = 64; 299 300 mpu = substream->rmidi->private_data; 301 if (up) { 302 if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { 303 /* first time - flush FIFO */ 304 while (max-- > 0) 305 mpu->read(mpu, MPU401D(mpu)); 306 if (mpu->irq < 0) 307 snd_mpu401_uart_add_timer(mpu, 1); 308 } 309 310 /* read data in advance */ 311 /* prevent double enter via rawmidi->event callback */ 312 if (atomic_dec_and_test(&mpu->rx_loop)) { 313 // local_irq_save(flags); 314 printk("uart inp. trigger\n"); 315 save_flags(&flags); 316 cli(); 317 if (spin_trylock(&mpu->input_lock)) { 318 snd_mpu401_uart_input_read(mpu); 319 spin_unlock(&mpu->input_lock); 320 } 321 restore_flags(flags); 322 } 323 atomic_inc(&mpu->rx_loop); 324 } else { 325 if (mpu->irq < 0) 326 snd_mpu401_uart_remove_timer(mpu, 1); 327 clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); 328 } 293 static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) 294 { 295 unsigned long flags; 296 struct snd_mpu401 *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 } 329 318 } 330 319 … … 333 322 * call with input_lock spinlock held 334 323 */ 335 static void snd_mpu401_uart_input_read(mpu401_t * mpu) 336 { 337 int max = 128; 338 unsigned char byte; 339 340 while (max-- > 0) { 341 if (snd_mpu401_input_avail(mpu)) { 342 byte = mpu->read(mpu, MPU401D(mpu)); 343 printk("mpu uart: %x\n",byte); 344 //vladest if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) 345 snd_rawmidi_receive(mpu->substream_input, &byte, 1); 346 } else { 347 break; /* input not available */ 348 } 349 } 324 static void snd_mpu401_uart_input_read(struct snd_mpu401 * 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 } 350 338 } 351 339 … … 362 350 * call with output_lock spinlock held 363 351 */ 364 static void snd_mpu401_uart_output_write(mpu401_t * mpu) 365 { 366 unsigned char byte; 367 int max = 256, timeout; 368 369 do { 370 if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { 371 for (timeout = 100; timeout > 0; timeout--) { 372 if (snd_mpu401_output_ready(mpu)) { 373 mpu->write(mpu, byte, MPU401D(mpu)); 374 snd_rawmidi_transmit_ack(mpu->substream_output, 1); 375 break; 376 } 377 } 378 if (timeout == 0) 379 break; /* Tx FIFO full - try again later */ 380 } else { 381 snd_mpu401_uart_remove_timer (mpu, 0); 382 break; /* no other data - leave the tx loop */ 352 static void snd_mpu401_uart_output_write(struct snd_mpu401 * 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(struct snd_rawmidi_substream *substream, int up) 379 { 380 unsigned long flags; 381 struct snd_mpu401 *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 struct snd_rawmidi_ops 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 struct snd_rawmidi_ops 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(struct snd_rawmidi *rmidi) 422 { 423 struct snd_mpu401 *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); 383 429 } 384 } while (--max > 0); 385 } 386 387 /* 388 * output trigger callback 389 */ 390 static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, int up) 391 { 392 u32 flags; 393 mpu401_t *mpu; 394 395 mpu = substream->rmidi->private_data; 396 if (up) { 397 set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 398 399 /* try to add the timer at each output trigger, 400 * since the output timer might have been removed in 401 * snd_mpu401_uart_output_write(). 402 */ 403 snd_mpu401_uart_add_timer(mpu, 0); 404 405 /* output pending data */ 406 /* prevent double enter via rawmidi->event callback */ 407 if (atomic_dec_and_test(&mpu->tx_loop)) { 408 save_flags(&flags); 409 cli(); 410 if (spin_trylock(&mpu->output_lock)) { 411 snd_mpu401_uart_output_write(mpu); 412 spin_unlock(&mpu->output_lock); 413 } 414 restore_flags(flags); 415 } 416 atomic_inc(&mpu->tx_loop); 417 } else { 418 snd_mpu401_uart_remove_timer(mpu, 0); 419 clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); 420 } 421 } 422 423 /* 424 425 */ 426 427 #ifdef TARGET_OS2 428 static snd_rawmidi_ops_t snd_mpu401_uart_output = 429 { 430 snd_mpu401_uart_output_open, 431 snd_mpu401_uart_output_close, 432 snd_mpu401_uart_output_trigger,0 433 }; 434 435 static snd_rawmidi_ops_t snd_mpu401_uart_input = 436 { 437 snd_mpu401_uart_input_open, 438 snd_mpu401_uart_input_close, 439 snd_mpu401_uart_input_trigger,0 440 }; 441 #else 442 static snd_rawmidi_ops_t snd_mpu401_uart_output = 443 { 444 open: snd_mpu401_uart_output_open, 445 close: snd_mpu401_uart_output_close, 446 trigger: snd_mpu401_uart_output_trigger, 447 }; 448 449 static snd_rawmidi_ops_t snd_mpu401_uart_input = 450 { 451 open: snd_mpu401_uart_input_open, 452 close: snd_mpu401_uart_input_close, 453 trigger: snd_mpu401_uart_input_trigger, 454 }; 455 #endif 456 457 static void snd_mpu401_uart_free(snd_rawmidi_t *rmidi) 458 { 459 mpu401_t *mpu = rmidi->private_data; 460 if (mpu->irq_flags && mpu->irq >= 0) 461 free_irq(mpu->irq, (void *) mpu); 462 if (mpu->res) { 463 release_resource(mpu->res); 464 kfree_nocheck(mpu->res); 465 } 466 kfree(mpu); 430 kfree(mpu); 467 431 } 468 432 … … 482 446 * Note that the rawmidi instance is returned on the rrawmidi argument, 483 447 * not the mpu401 instance itself. To access to the mpu401 instance, 484 * cast from rawmidi->private_data (with mpu401_tmagic-cast).448 * cast from rawmidi->private_data (with struct snd_mpu401 magic-cast). 485 449 * 486 450 * Returns zero if successful, or a negative error code. 487 451 */ 488 int snd_mpu401_uart_new(s nd_card_t *card, int device,489 490 491 492 snd_rawmidi_t** rrawmidi)493 { 494 mpu401_t*mpu;495 snd_rawmidi_t*rmidi;496 497 498 printk("snd_mpu401_uart_new on irq: %i, port: %i\n",irq,port); 499 if (rrawmidi) 500 *rrawmidi = NULL; 501 if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0) 502 return err;503 mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL); 504 if (mpu == NULL) { 505 506 507 508 509 510 511 512 513 514 515 516 517 snd_device_free(card, rmidi);518 return -EBUSY;519 } 520 521 switch (hardware) { 522 case MPU401_HW_AUREAL: 523 mpu->write = mpu401_write_mmio; 524 mpu->read = mpu401_read_mmio;525 break;526 default: 527 mpu->write = mpu401_write_port; 528 mpu->read = mpu401_read_port;529 break;530 } 531 mpu->port = port; 532 if (hardware == MPU401_HW_PC98II) 533 mpu->cport = port + 2; 534 else 535 mpu->cport = port + 1; 536 if (irq >= 0 && irq_flags) { 537 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) {538 snd_printk("unable to grab IRQ %d\n", irq); 539 snd_device_free(card, rmidi);540 return -EBUSY;541 } 542 543 mpu->irq = irq; 544 mpu->irq_flags = irq_flags;545 if (card->shortname[0]) 546 sprintf(rmidi->name, "%s MPU-401", card->shortname); 547 else 548 sprintf(rmidi->name, "MPU-401 (UART) %d-%d", card->number, device); 549 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output);550 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input);551 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 552 SNDRV_RAWMIDI_INFO_INPUT |553 SNDRV_RAWMIDI_INFO_DUPLEX; 554 mpu->rmidi = rmidi;555 if (rrawmidi) 556 *rrawmidi = rmidi; 557 printk("Created MPU\n");558 452 int snd_mpu401_uart_new(struct snd_card *card, int device, 453 unsigned short hardware, 454 unsigned long port, int integrated, 455 int irq, int irq_flags, 456 struct snd_rawmidi ** rrawmidi) 457 { 458 struct snd_mpu401 *mpu; 459 struct snd_rawmidi *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 = (struct snd_mpu401 *)kzalloc(sizeof(*mpu), GFP_KERNEL); 467 if (mpu == NULL) { 468 snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n"); 469 snd_device_free(card, rmidi); 470 return -ENOMEM; 471 } 472 rmidi->private_data = mpu; 473 rmidi->private_free = snd_mpu401_uart_free; 474 spin_lock_init(&mpu->input_lock); 475 spin_lock_init(&mpu->output_lock); 476 spin_lock_init(&mpu->timer_lock); 477 mpu->hardware = hardware; 478 if (!integrated) { 479 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 480 if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) { 481 snd_printk(KERN_ERR "mpu401_uart: unable to grab port 0x%lx size %d\n", port, res_size); 482 snd_device_free(card, rmidi); 483 return -EBUSY; 484 } 485 } 486 switch (hardware) { 487 case MPU401_HW_AUREAL: 488 mpu->write = mpu401_write_mmio; 489 mpu->read = mpu401_read_mmio; 490 break; 491 default: 492 mpu->write = mpu401_write_port; 493 mpu->read = mpu401_read_port; 494 break; 495 } 496 mpu->port = port; 497 if (hardware == MPU401_HW_PC98II) 498 mpu->cport = port + 2; 499 else 500 mpu->cport = port + 1; 501 if (irq >= 0 && irq_flags) { 502 if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) { 503 snd_printk(KERN_ERR "mpu401_uart: unable to grab IRQ %d\n", irq); 504 snd_device_free(card, rmidi); 505 return -EBUSY; 506 } 507 } 508 mpu->irq = irq; 509 mpu->irq_flags = irq_flags; 510 if (card->shortname[0]) 511 sprintf(rmidi->name, "%s MIDI", card->shortname); 512 else 513 sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device); 514 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); 515 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); 516 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | 517 SNDRV_RAWMIDI_INFO_INPUT | 518 SNDRV_RAWMIDI_INFO_DUPLEX; 519 mpu->rmidi = rmidi; 520 if (rrawmidi) 521 *rrawmidi = rmidi; 522 return 0; 559 523 } 560 524 … … 568 532 static int __init alsa_mpu401_uart_init(void) 569 533 { 570 534 return 0; 571 535 } 572 536
Note:
See TracChangeset
for help on using the changeset viewer.