diff options
Diffstat (limited to 'sound/drivers/mtpav.c')
-rw-r--r-- | sound/drivers/mtpav.c | 306 |
1 files changed, 149 insertions, 157 deletions
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index e9d52c668edc..b7a0b42813e1 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include <sound/driver.h> | 53 | #include <sound/driver.h> |
54 | #include <linux/init.h> | 54 | #include <linux/init.h> |
55 | #include <linux/interrupt.h> | 55 | #include <linux/interrupt.h> |
56 | #include <linux/err.h> | ||
57 | #include <linux/platform_device.h> | ||
56 | #include <linux/slab.h> | 58 | #include <linux/slab.h> |
57 | #include <linux/ioport.h> | 59 | #include <linux/ioport.h> |
58 | #include <linux/moduleparam.h> | 60 | #include <linux/moduleparam.h> |
@@ -93,6 +95,8 @@ MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI."); | |||
93 | module_param(hwports, int, 0444); | 95 | module_param(hwports, int, 0444); |
94 | MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI."); | 96 | MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI."); |
95 | 97 | ||
98 | static struct platform_device *device; | ||
99 | |||
96 | /* | 100 | /* |
97 | * defines | 101 | * defines |
98 | */ | 102 | */ |
@@ -125,17 +129,17 @@ MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI."); | |||
125 | /* | 129 | /* |
126 | */ | 130 | */ |
127 | 131 | ||
128 | typedef struct mtpav_port { | 132 | struct mtpav_port { |
129 | u8 number; | 133 | u8 number; |
130 | u8 hwport; | 134 | u8 hwport; |
131 | u8 mode; | 135 | u8 mode; |
132 | u8 running_status; | 136 | u8 running_status; |
133 | snd_rawmidi_substream_t *input; | 137 | struct snd_rawmidi_substream *input; |
134 | snd_rawmidi_substream_t *output; | 138 | struct snd_rawmidi_substream *output; |
135 | } mtpav_port_t; | 139 | }; |
136 | 140 | ||
137 | typedef struct mtpav { | 141 | struct mtpav { |
138 | snd_card_t *card; | 142 | struct snd_card *card; |
139 | unsigned long port; | 143 | unsigned long port; |
140 | struct resource *res_port; | 144 | struct resource *res_port; |
141 | int irq; /* interrupt (for inputs) */ | 145 | int irq; /* interrupt (for inputs) */ |
@@ -143,24 +147,18 @@ typedef struct mtpav { | |||
143 | int share_irq; /* number of accesses to input interrupts */ | 147 | int share_irq; /* number of accesses to input interrupts */ |
144 | int istimer; /* number of accesses to timer interrupts */ | 148 | int istimer; /* number of accesses to timer interrupts */ |
145 | struct timer_list timer; /* timer interrupts for outputs */ | 149 | struct timer_list timer; /* timer interrupts for outputs */ |
146 | snd_rawmidi_t *rmidi; | 150 | struct snd_rawmidi *rmidi; |
147 | int num_ports; /* number of hw ports (1-8) */ | 151 | int num_ports; /* number of hw ports (1-8) */ |
148 | mtpav_port_t ports[NUMPORTS]; /* all ports including computer, adat and bc */ | 152 | struct mtpav_port ports[NUMPORTS]; /* all ports including computer, adat and bc */ |
149 | 153 | ||
150 | u32 inmidiport; /* selected input midi port */ | 154 | u32 inmidiport; /* selected input midi port */ |
151 | u32 inmidistate; /* during midi command 0xf5 */ | 155 | u32 inmidistate; /* during midi command 0xf5 */ |
152 | 156 | ||
153 | u32 outmidihwport; /* selected output midi hw port */ | 157 | u32 outmidihwport; /* selected output midi hw port */ |
154 | } mtpav_t; | 158 | }; |
155 | 159 | ||
156 | 160 | ||
157 | /* | 161 | /* |
158 | * global instance | ||
159 | * hey, we handle at most only one card.. | ||
160 | */ | ||
161 | static mtpav_t *mtp_card; | ||
162 | |||
163 | /* | ||
164 | * possible hardware ports (selected by 0xf5 port message) | 162 | * possible hardware ports (selected by 0xf5 port message) |
165 | * 0x00 all ports | 163 | * 0x00 all ports |
166 | * 0x01 .. 0x08 this MTP's ports 1..8 | 164 | * 0x01 .. 0x08 this MTP's ports 1..8 |
@@ -183,7 +181,7 @@ static mtpav_t *mtp_card; | |||
183 | #define MTPAV_PIDX_BROADCAST 2 | 181 | #define MTPAV_PIDX_BROADCAST 2 |
184 | 182 | ||
185 | 183 | ||
186 | static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev) | 184 | static int translate_subdevice_to_hwport(struct mtpav *chip, int subdev) |
187 | { | 185 | { |
188 | if (subdev < 0) | 186 | if (subdev < 0) |
189 | return 0x01; /* invalid - use port 0 as default */ | 187 | return 0x01; /* invalid - use port 0 as default */ |
@@ -198,7 +196,7 @@ static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev) | |||
198 | return 0; /* all ports */ | 196 | return 0; /* all ports */ |
199 | } | 197 | } |
200 | 198 | ||
201 | static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport) | 199 | static int translate_hwport_to_subdevice(struct mtpav *chip, int hwport) |
202 | { | 200 | { |
203 | int p; | 201 | int p; |
204 | if (hwport <= 0x00) /* all ports */ | 202 | if (hwport <= 0x00) /* all ports */ |
@@ -223,7 +221,7 @@ static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport) | |||
223 | /* | 221 | /* |
224 | */ | 222 | */ |
225 | 223 | ||
226 | static u8 snd_mtpav_getreg(mtpav_t *chip, u16 reg) | 224 | static u8 snd_mtpav_getreg(struct mtpav *chip, u16 reg) |
227 | { | 225 | { |
228 | u8 rval = 0; | 226 | u8 rval = 0; |
229 | 227 | ||
@@ -241,19 +239,16 @@ static u8 snd_mtpav_getreg(mtpav_t *chip, u16 reg) | |||
241 | /* | 239 | /* |
242 | */ | 240 | */ |
243 | 241 | ||
244 | static void snd_mtpav_mputreg(mtpav_t *chip, u16 reg, u8 val) | 242 | static inline void snd_mtpav_mputreg(struct mtpav *chip, u16 reg, u8 val) |
245 | { | 243 | { |
246 | if (reg == DREG) { | 244 | if (reg == DREG || reg == CREG) |
247 | outb(val, chip->port + DREG); | 245 | outb(val, chip->port + reg); |
248 | } else if (reg == CREG) { | ||
249 | outb(val, chip->port + CREG); | ||
250 | } | ||
251 | } | 246 | } |
252 | 247 | ||
253 | /* | 248 | /* |
254 | */ | 249 | */ |
255 | 250 | ||
256 | static void snd_mtpav_wait_rfdhi(mtpav_t *chip) | 251 | static void snd_mtpav_wait_rfdhi(struct mtpav *chip) |
257 | { | 252 | { |
258 | int counts = 10000; | 253 | int counts = 10000; |
259 | u8 sbyte; | 254 | u8 sbyte; |
@@ -265,7 +260,7 @@ static void snd_mtpav_wait_rfdhi(mtpav_t *chip) | |||
265 | } | 260 | } |
266 | } | 261 | } |
267 | 262 | ||
268 | static void snd_mtpav_send_byte(mtpav_t *chip, u8 byte) | 263 | static void snd_mtpav_send_byte(struct mtpav *chip, u8 byte) |
269 | { | 264 | { |
270 | u8 tcbyt; | 265 | u8 tcbyt; |
271 | u8 clrwrite; | 266 | u8 clrwrite; |
@@ -291,8 +286,9 @@ static void snd_mtpav_send_byte(mtpav_t *chip, u8 byte) | |||
291 | */ | 286 | */ |
292 | 287 | ||
293 | /* call this with spin lock held */ | 288 | /* call this with spin lock held */ |
294 | static void snd_mtpav_output_port_write(mtpav_port_t *port, | 289 | static void snd_mtpav_output_port_write(struct mtpav *mtp_card, |
295 | snd_rawmidi_substream_t *substream) | 290 | struct mtpav_port *portp, |
291 | struct snd_rawmidi_substream *substream) | ||
296 | { | 292 | { |
297 | u8 outbyte; | 293 | u8 outbyte; |
298 | 294 | ||
@@ -303,34 +299,35 @@ static void snd_mtpav_output_port_write(mtpav_port_t *port, | |||
303 | 299 | ||
304 | // send port change command if necessary | 300 | // send port change command if necessary |
305 | 301 | ||
306 | if (port->hwport != mtp_card->outmidihwport) { | 302 | if (portp->hwport != mtp_card->outmidihwport) { |
307 | mtp_card->outmidihwport = port->hwport; | 303 | mtp_card->outmidihwport = portp->hwport; |
308 | 304 | ||
309 | snd_mtpav_send_byte(mtp_card, 0xf5); | 305 | snd_mtpav_send_byte(mtp_card, 0xf5); |
310 | snd_mtpav_send_byte(mtp_card, port->hwport); | 306 | snd_mtpav_send_byte(mtp_card, portp->hwport); |
311 | //snd_printk("new outport: 0x%x\n", (unsigned int) port->hwport); | 307 | //snd_printk("new outport: 0x%x\n", (unsigned int) portp->hwport); |
312 | 308 | ||
313 | if (!(outbyte & 0x80) && port->running_status) | 309 | if (!(outbyte & 0x80) && portp->running_status) |
314 | snd_mtpav_send_byte(mtp_card, port->running_status); | 310 | snd_mtpav_send_byte(mtp_card, portp->running_status); |
315 | } | 311 | } |
316 | 312 | ||
317 | // send data | 313 | // send data |
318 | 314 | ||
319 | do { | 315 | do { |
320 | if (outbyte & 0x80) | 316 | if (outbyte & 0x80) |
321 | port->running_status = outbyte; | 317 | portp->running_status = outbyte; |
322 | 318 | ||
323 | snd_mtpav_send_byte(mtp_card, outbyte); | 319 | snd_mtpav_send_byte(mtp_card, outbyte); |
324 | } while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1); | 320 | } while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1); |
325 | } | 321 | } |
326 | 322 | ||
327 | static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream) | 323 | static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream) |
328 | { | 324 | { |
329 | mtpav_port_t *port = &mtp_card->ports[substream->number]; | 325 | struct mtpav *mtp_card = substream->rmidi->private_data; |
326 | struct mtpav_port *portp = &mtp_card->ports[substream->number]; | ||
330 | unsigned long flags; | 327 | unsigned long flags; |
331 | 328 | ||
332 | spin_lock_irqsave(&mtp_card->spinlock, flags); | 329 | spin_lock_irqsave(&mtp_card->spinlock, flags); |
333 | snd_mtpav_output_port_write(port, substream); | 330 | snd_mtpav_output_port_write(mtp_card, portp, substream); |
334 | spin_unlock_irqrestore(&mtp_card->spinlock, flags); | 331 | spin_unlock_irqrestore(&mtp_card->spinlock, flags); |
335 | } | 332 | } |
336 | 333 | ||
@@ -339,7 +336,7 @@ static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream) | |||
339 | * mtpav control | 336 | * mtpav control |
340 | */ | 337 | */ |
341 | 338 | ||
342 | static void snd_mtpav_portscan(mtpav_t *chip) // put mtp into smart routing mode | 339 | static void snd_mtpav_portscan(struct mtpav *chip) // put mtp into smart routing mode |
343 | { | 340 | { |
344 | u8 p; | 341 | u8 p; |
345 | 342 | ||
@@ -353,12 +350,12 @@ static void snd_mtpav_portscan(mtpav_t *chip) // put mtp into smart routing mode | |||
353 | /* | 350 | /* |
354 | */ | 351 | */ |
355 | 352 | ||
356 | static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream) | 353 | static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream) |
357 | { | 354 | { |
355 | struct mtpav *mtp_card = substream->rmidi->private_data; | ||
356 | struct mtpav_port *portp = &mtp_card->ports[substream->number]; | ||
358 | unsigned long flags; | 357 | unsigned long flags; |
359 | mtpav_port_t *portp = &mtp_card->ports[substream->number]; | ||
360 | 358 | ||
361 | //printk("mtpav port: %d opened\n", (int) substream->number); | ||
362 | spin_lock_irqsave(&mtp_card->spinlock, flags); | 359 | spin_lock_irqsave(&mtp_card->spinlock, flags); |
363 | portp->mode |= MTPAV_MODE_INPUT_OPENED; | 360 | portp->mode |= MTPAV_MODE_INPUT_OPENED; |
364 | portp->input = substream; | 361 | portp->input = substream; |
@@ -371,20 +368,17 @@ static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream) | |||
371 | /* | 368 | /* |
372 | */ | 369 | */ |
373 | 370 | ||
374 | static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream) | 371 | static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream) |
375 | { | 372 | { |
373 | struct mtpav *mtp_card = substream->rmidi->private_data; | ||
374 | struct mtpav_port *portp = &mtp_card->ports[substream->number]; | ||
376 | unsigned long flags; | 375 | unsigned long flags; |
377 | mtpav_port_t *portp = &mtp_card->ports[substream->number]; | ||
378 | |||
379 | //printk("mtpav port: %d closed\n", (int) portp); | ||
380 | 376 | ||
381 | spin_lock_irqsave(&mtp_card->spinlock, flags); | 377 | spin_lock_irqsave(&mtp_card->spinlock, flags); |
382 | 378 | portp->mode &= ~MTPAV_MODE_INPUT_OPENED; | |
383 | portp->mode &= (~MTPAV_MODE_INPUT_OPENED); | ||
384 | portp->input = NULL; | 379 | portp->input = NULL; |
385 | if (--mtp_card->share_irq == 0) | 380 | if (--mtp_card->share_irq == 0) |
386 | snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts | 381 | snd_mtpav_mputreg(mtp_card, CREG, 0); // disable pport interrupts |
387 | |||
388 | spin_unlock_irqrestore(&mtp_card->spinlock, flags); | 382 | spin_unlock_irqrestore(&mtp_card->spinlock, flags); |
389 | return 0; | 383 | return 0; |
390 | } | 384 | } |
@@ -392,10 +386,11 @@ static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream) | |||
392 | /* | 386 | /* |
393 | */ | 387 | */ |
394 | 388 | ||
395 | static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up) | 389 | static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int up) |
396 | { | 390 | { |
391 | struct mtpav *mtp_card = substream->rmidi->private_data; | ||
392 | struct mtpav_port *portp = &mtp_card->ports[substream->number]; | ||
397 | unsigned long flags; | 393 | unsigned long flags; |
398 | mtpav_port_t *portp = &mtp_card->ports[substream->number]; | ||
399 | 394 | ||
400 | spin_lock_irqsave(&mtp_card->spinlock, flags); | 395 | spin_lock_irqsave(&mtp_card->spinlock, flags); |
401 | if (up) | 396 | if (up) |
@@ -414,7 +409,7 @@ static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up) | |||
414 | static void snd_mtpav_output_timer(unsigned long data) | 409 | static void snd_mtpav_output_timer(unsigned long data) |
415 | { | 410 | { |
416 | unsigned long flags; | 411 | unsigned long flags; |
417 | mtpav_t *chip = (mtpav_t *)data; | 412 | struct mtpav *chip = (struct mtpav *)data; |
418 | int p; | 413 | int p; |
419 | 414 | ||
420 | spin_lock_irqsave(&chip->spinlock, flags); | 415 | spin_lock_irqsave(&chip->spinlock, flags); |
@@ -423,25 +418,22 @@ static void snd_mtpav_output_timer(unsigned long data) | |||
423 | add_timer(&chip->timer); | 418 | add_timer(&chip->timer); |
424 | /* process each port */ | 419 | /* process each port */ |
425 | for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) { | 420 | for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) { |
426 | mtpav_port_t *portp = &mtp_card->ports[p]; | 421 | struct mtpav_port *portp = &chip->ports[p]; |
427 | if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output) | 422 | if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output) |
428 | snd_mtpav_output_port_write(portp, portp->output); | 423 | snd_mtpav_output_port_write(chip, portp, portp->output); |
429 | } | 424 | } |
430 | spin_unlock_irqrestore(&chip->spinlock, flags); | 425 | spin_unlock_irqrestore(&chip->spinlock, flags); |
431 | } | 426 | } |
432 | 427 | ||
433 | /* spinlock held! */ | 428 | /* spinlock held! */ |
434 | static void snd_mtpav_add_output_timer(mtpav_t *chip) | 429 | static void snd_mtpav_add_output_timer(struct mtpav *chip) |
435 | { | 430 | { |
436 | init_timer(&chip->timer); | ||
437 | chip->timer.function = snd_mtpav_output_timer; | ||
438 | chip->timer.data = (unsigned long) mtp_card; | ||
439 | chip->timer.expires = 1 + jiffies; | 431 | chip->timer.expires = 1 + jiffies; |
440 | add_timer(&chip->timer); | 432 | add_timer(&chip->timer); |
441 | } | 433 | } |
442 | 434 | ||
443 | /* spinlock held! */ | 435 | /* spinlock held! */ |
444 | static void snd_mtpav_remove_output_timer(mtpav_t *chip) | 436 | static void snd_mtpav_remove_output_timer(struct mtpav *chip) |
445 | { | 437 | { |
446 | del_timer(&chip->timer); | 438 | del_timer(&chip->timer); |
447 | } | 439 | } |
@@ -449,10 +441,11 @@ static void snd_mtpav_remove_output_timer(mtpav_t *chip) | |||
449 | /* | 441 | /* |
450 | */ | 442 | */ |
451 | 443 | ||
452 | static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream) | 444 | static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream) |
453 | { | 445 | { |
446 | struct mtpav *mtp_card = substream->rmidi->private_data; | ||
447 | struct mtpav_port *portp = &mtp_card->ports[substream->number]; | ||
454 | unsigned long flags; | 448 | unsigned long flags; |
455 | mtpav_port_t *portp = &mtp_card->ports[substream->number]; | ||
456 | 449 | ||
457 | spin_lock_irqsave(&mtp_card->spinlock, flags); | 450 | spin_lock_irqsave(&mtp_card->spinlock, flags); |
458 | portp->mode |= MTPAV_MODE_OUTPUT_OPENED; | 451 | portp->mode |= MTPAV_MODE_OUTPUT_OPENED; |
@@ -464,13 +457,14 @@ static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream) | |||
464 | /* | 457 | /* |
465 | */ | 458 | */ |
466 | 459 | ||
467 | static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream) | 460 | static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream) |
468 | { | 461 | { |
462 | struct mtpav *mtp_card = substream->rmidi->private_data; | ||
463 | struct mtpav_port *portp = &mtp_card->ports[substream->number]; | ||
469 | unsigned long flags; | 464 | unsigned long flags; |
470 | mtpav_port_t *portp = &mtp_card->ports[substream->number]; | ||
471 | 465 | ||
472 | spin_lock_irqsave(&mtp_card->spinlock, flags); | 466 | spin_lock_irqsave(&mtp_card->spinlock, flags); |
473 | portp->mode &= (~MTPAV_MODE_OUTPUT_OPENED); | 467 | portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED; |
474 | portp->output = NULL; | 468 | portp->output = NULL; |
475 | spin_unlock_irqrestore(&mtp_card->spinlock, flags); | 469 | spin_unlock_irqrestore(&mtp_card->spinlock, flags); |
476 | return 0; | 470 | return 0; |
@@ -479,14 +473,15 @@ static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream) | |||
479 | /* | 473 | /* |
480 | */ | 474 | */ |
481 | 475 | ||
482 | static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up) | 476 | static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, int up) |
483 | { | 477 | { |
478 | struct mtpav *mtp_card = substream->rmidi->private_data; | ||
479 | struct mtpav_port *portp = &mtp_card->ports[substream->number]; | ||
484 | unsigned long flags; | 480 | unsigned long flags; |
485 | mtpav_port_t *portp = &mtp_card->ports[substream->number]; | ||
486 | 481 | ||
487 | spin_lock_irqsave(&mtp_card->spinlock, flags); | 482 | spin_lock_irqsave(&mtp_card->spinlock, flags); |
488 | if (up) { | 483 | if (up) { |
489 | if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) { | 484 | if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) { |
490 | if (mtp_card->istimer++ == 0) | 485 | if (mtp_card->istimer++ == 0) |
491 | snd_mtpav_add_output_timer(mtp_card); | 486 | snd_mtpav_add_output_timer(mtp_card); |
492 | portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED; | 487 | portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED; |
@@ -506,23 +501,20 @@ static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up | |||
506 | * midi interrupt for inputs | 501 | * midi interrupt for inputs |
507 | */ | 502 | */ |
508 | 503 | ||
509 | static void snd_mtpav_inmidi_process(mtpav_t *mcrd, u8 inbyte) | 504 | static void snd_mtpav_inmidi_process(struct mtpav *mcrd, u8 inbyte) |
510 | { | 505 | { |
511 | mtpav_port_t *portp; | 506 | struct mtpav_port *portp; |
512 | 507 | ||
513 | if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST) | 508 | if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST) |
514 | return; | 509 | return; |
515 | 510 | ||
516 | portp = &mcrd->ports[mcrd->inmidiport]; | 511 | portp = &mcrd->ports[mcrd->inmidiport]; |
517 | if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED) { | 512 | if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED) |
518 | snd_rawmidi_receive(portp->input, &inbyte, 1); | 513 | snd_rawmidi_receive(portp->input, &inbyte, 1); |
519 | } | ||
520 | } | 514 | } |
521 | 515 | ||
522 | static void snd_mtpav_inmidi_h(mtpav_t * mcrd, u8 inbyte) | 516 | static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte) |
523 | { | 517 | { |
524 | snd_assert(mcrd, return); | ||
525 | |||
526 | if (inbyte >= 0xf8) { | 518 | if (inbyte >= 0xf8) { |
527 | /* real-time midi code */ | 519 | /* real-time midi code */ |
528 | snd_mtpav_inmidi_process(mcrd, inbyte); | 520 | snd_mtpav_inmidi_process(mcrd, inbyte); |
@@ -540,7 +532,7 @@ static void snd_mtpav_inmidi_h(mtpav_t * mcrd, u8 inbyte) | |||
540 | } | 532 | } |
541 | } | 533 | } |
542 | 534 | ||
543 | static void snd_mtpav_read_bytes(mtpav_t * mcrd) | 535 | static void snd_mtpav_read_bytes(struct mtpav *mcrd) |
544 | { | 536 | { |
545 | u8 clrread, setread; | 537 | u8 clrread, setread; |
546 | u8 mtp_read_byte; | 538 | u8 mtp_read_byte; |
@@ -580,9 +572,8 @@ static void snd_mtpav_read_bytes(mtpav_t * mcrd) | |||
580 | 572 | ||
581 | static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs) | 573 | static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs) |
582 | { | 574 | { |
583 | mtpav_t *mcard = dev_id; | 575 | struct mtpav *mcard = dev_id; |
584 | 576 | ||
585 | //printk("irqh()\n"); | ||
586 | spin_lock(&mcard->spinlock); | 577 | spin_lock(&mcard->spinlock); |
587 | snd_mtpav_read_bytes(mcard); | 578 | snd_mtpav_read_bytes(mcard); |
588 | spin_unlock(&mcard->spinlock); | 579 | spin_unlock(&mcard->spinlock); |
@@ -592,14 +583,14 @@ static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs) | |||
592 | /* | 583 | /* |
593 | * get ISA resources | 584 | * get ISA resources |
594 | */ | 585 | */ |
595 | static int snd_mtpav_get_ISA(mtpav_t * mcard) | 586 | static int __init snd_mtpav_get_ISA(struct mtpav * mcard) |
596 | { | 587 | { |
597 | if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) { | 588 | if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) { |
598 | snd_printk("MTVAP port 0x%lx is busy\n", port); | 589 | snd_printk("MTVAP port 0x%lx is busy\n", port); |
599 | return -EBUSY; | 590 | return -EBUSY; |
600 | } | 591 | } |
601 | mcard->port = port; | 592 | mcard->port = port; |
602 | if (request_irq(irq, snd_mtpav_irqh, SA_INTERRUPT, "MOTU MTPAV", (void *)mcard)) { | 593 | if (request_irq(irq, snd_mtpav_irqh, SA_INTERRUPT, "MOTU MTPAV", mcard)) { |
603 | snd_printk("MTVAP IRQ %d busy\n", irq); | 594 | snd_printk("MTVAP IRQ %d busy\n", irq); |
604 | return -EBUSY; | 595 | return -EBUSY; |
605 | } | 596 | } |
@@ -611,13 +602,13 @@ static int snd_mtpav_get_ISA(mtpav_t * mcard) | |||
611 | /* | 602 | /* |
612 | */ | 603 | */ |
613 | 604 | ||
614 | static snd_rawmidi_ops_t snd_mtpav_output = { | 605 | static struct snd_rawmidi_ops snd_mtpav_output = { |
615 | .open = snd_mtpav_output_open, | 606 | .open = snd_mtpav_output_open, |
616 | .close = snd_mtpav_output_close, | 607 | .close = snd_mtpav_output_close, |
617 | .trigger = snd_mtpav_output_trigger, | 608 | .trigger = snd_mtpav_output_trigger, |
618 | }; | 609 | }; |
619 | 610 | ||
620 | static snd_rawmidi_ops_t snd_mtpav_input = { | 611 | static struct snd_rawmidi_ops snd_mtpav_input = { |
621 | .open = snd_mtpav_input_open, | 612 | .open = snd_mtpav_input_open, |
622 | .close = snd_mtpav_input_close, | 613 | .close = snd_mtpav_input_close, |
623 | .trigger = snd_mtpav_input_trigger, | 614 | .trigger = snd_mtpav_input_trigger, |
@@ -628,7 +619,8 @@ static snd_rawmidi_ops_t snd_mtpav_input = { | |||
628 | * get RAWMIDI resources | 619 | * get RAWMIDI resources |
629 | */ | 620 | */ |
630 | 621 | ||
631 | static void snd_mtpav_set_name(mtpav_t *chip, snd_rawmidi_substream_t *substream) | 622 | static void __init snd_mtpav_set_name(struct mtpav *chip, |
623 | struct snd_rawmidi_substream *substream) | ||
632 | { | 624 | { |
633 | if (substream->number >= 0 && substream->number < chip->num_ports) | 625 | if (substream->number >= 0 && substream->number < chip->num_ports) |
634 | sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1); | 626 | sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1); |
@@ -642,21 +634,18 @@ static void snd_mtpav_set_name(mtpav_t *chip, snd_rawmidi_substream_t *substream | |||
642 | strcpy(substream->name, "MTP broadcast"); | 634 | strcpy(substream->name, "MTP broadcast"); |
643 | } | 635 | } |
644 | 636 | ||
645 | static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard) | 637 | static int __init snd_mtpav_get_RAWMIDI(struct mtpav *mcard) |
646 | { | 638 | { |
647 | int rval = 0; | 639 | int rval; |
648 | snd_rawmidi_t *rawmidi; | 640 | struct snd_rawmidi *rawmidi; |
649 | snd_rawmidi_substream_t *substream; | 641 | struct snd_rawmidi_substream *substream; |
650 | struct list_head *list; | 642 | struct list_head *list; |
651 | 643 | ||
652 | //printk("entering snd_mtpav_get_RAWMIDI\n"); | ||
653 | |||
654 | if (hwports < 1) | 644 | if (hwports < 1) |
655 | mcard->num_ports = 1; | 645 | hwports = 1; |
656 | else if (hwports > 8) | 646 | else if (hwports > 8) |
657 | mcard->num_ports = 8; | 647 | hwports = 8; |
658 | else | 648 | mcard->num_ports = hwports; |
659 | mcard->num_ports = hwports; | ||
660 | 649 | ||
661 | if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0, | 650 | if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0, |
662 | mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1, | 651 | mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1, |
@@ -664,14 +653,15 @@ static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard) | |||
664 | &mcard->rmidi)) < 0) | 653 | &mcard->rmidi)) < 0) |
665 | return rval; | 654 | return rval; |
666 | rawmidi = mcard->rmidi; | 655 | rawmidi = mcard->rmidi; |
656 | rawmidi->private_data = mcard; | ||
667 | 657 | ||
668 | list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { | 658 | list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { |
669 | substream = list_entry(list, snd_rawmidi_substream_t, list); | 659 | substream = list_entry(list, struct snd_rawmidi_substream, list); |
670 | snd_mtpav_set_name(mcard, substream); | 660 | snd_mtpav_set_name(mcard, substream); |
671 | substream->ops = &snd_mtpav_input; | 661 | substream->ops = &snd_mtpav_input; |
672 | } | 662 | } |
673 | list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { | 663 | list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { |
674 | substream = list_entry(list, snd_rawmidi_substream_t, list); | 664 | substream = list_entry(list, struct snd_rawmidi_substream, list); |
675 | snd_mtpav_set_name(mcard, substream); | 665 | snd_mtpav_set_name(mcard, substream); |
676 | substream->ops = &snd_mtpav_output; | 666 | substream->ops = &snd_mtpav_output; |
677 | mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number); | 667 | mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number); |
@@ -679,36 +669,15 @@ static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard) | |||
679 | rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | | 669 | rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | |
680 | SNDRV_RAWMIDI_INFO_DUPLEX; | 670 | SNDRV_RAWMIDI_INFO_DUPLEX; |
681 | sprintf(rawmidi->name, "MTP AV MIDI"); | 671 | sprintf(rawmidi->name, "MTP AV MIDI"); |
682 | //printk("exiting snd_mtpav_get_RAWMIDI() \n"); | ||
683 | return 0; | 672 | return 0; |
684 | } | 673 | } |
685 | 674 | ||
686 | /* | 675 | /* |
687 | */ | 676 | */ |
688 | 677 | ||
689 | static mtpav_t *new_mtpav(void) | 678 | static void snd_mtpav_free(struct snd_card *card) |
690 | { | ||
691 | mtpav_t *ncrd = kzalloc(sizeof(*ncrd), GFP_KERNEL); | ||
692 | if (ncrd != NULL) { | ||
693 | spin_lock_init(&ncrd->spinlock); | ||
694 | |||
695 | init_timer(&ncrd->timer); | ||
696 | ncrd->card = NULL; | ||
697 | ncrd->irq = -1; | ||
698 | ncrd->share_irq = 0; | ||
699 | |||
700 | ncrd->inmidiport = 0xffffffff; | ||
701 | ncrd->inmidistate = 0; | ||
702 | ncrd->outmidihwport = 0xffffffff; | ||
703 | } | ||
704 | return ncrd; | ||
705 | } | ||
706 | |||
707 | /* | ||
708 | */ | ||
709 | |||
710 | static void free_mtpav(mtpav_t * crd) | ||
711 | { | 679 | { |
680 | struct mtpav *crd = card->private_data; | ||
712 | unsigned long flags; | 681 | unsigned long flags; |
713 | 682 | ||
714 | spin_lock_irqsave(&crd->spinlock, flags); | 683 | spin_lock_irqsave(&crd->spinlock, flags); |
@@ -718,78 +687,101 @@ static void free_mtpav(mtpav_t * crd) | |||
718 | if (crd->irq >= 0) | 687 | if (crd->irq >= 0) |
719 | free_irq(crd->irq, (void *)crd); | 688 | free_irq(crd->irq, (void *)crd); |
720 | release_and_free_resource(crd->res_port); | 689 | release_and_free_resource(crd->res_port); |
721 | kfree(crd); | ||
722 | } | 690 | } |
723 | 691 | ||
724 | /* | 692 | /* |
725 | */ | 693 | */ |
726 | 694 | static int __init snd_mtpav_probe(struct platform_device *dev) | |
727 | static int __init alsa_card_mtpav_init(void) | ||
728 | { | 695 | { |
729 | int err = 0; | 696 | struct snd_card *card; |
730 | char longname_buffer[80]; | 697 | int err; |
698 | struct mtpav *mtp_card; | ||
731 | 699 | ||
732 | mtp_card = new_mtpav(); | 700 | card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card)); |
733 | if (mtp_card == NULL) | 701 | if (! card) |
734 | return -ENOMEM; | 702 | return -ENOMEM; |
735 | 703 | ||
736 | mtp_card->card = snd_card_new(index, id, THIS_MODULE, 0); | 704 | mtp_card = card->private_data; |
737 | if (mtp_card->card == NULL) { | 705 | spin_lock_init(&mtp_card->spinlock); |
738 | free_mtpav(mtp_card); | 706 | init_timer(&mtp_card->timer); |
739 | return -ENOMEM; | 707 | mtp_card->card = card; |
740 | } | 708 | mtp_card->irq = -1; |
709 | mtp_card->share_irq = 0; | ||
710 | mtp_card->inmidiport = 0xffffffff; | ||
711 | mtp_card->inmidistate = 0; | ||
712 | mtp_card->outmidihwport = 0xffffffff; | ||
713 | init_timer(&mtp_card->timer); | ||
714 | mtp_card->timer.function = snd_mtpav_output_timer; | ||
715 | mtp_card->timer.data = (unsigned long) mtp_card; | ||
716 | |||
717 | card->private_free = snd_mtpav_free; | ||
741 | 718 | ||
742 | err = snd_mtpav_get_ISA(mtp_card); | 719 | err = snd_mtpav_get_ISA(mtp_card); |
743 | //printk("snd_mtpav_get_ISA returned: %d\n", err); | ||
744 | if (err < 0) | 720 | if (err < 0) |
745 | goto __error; | 721 | goto __error; |
746 | 722 | ||
747 | strcpy(mtp_card->card->driver, "MTPAV"); | 723 | strcpy(card->driver, "MTPAV"); |
748 | strcpy(mtp_card->card->shortname, "MTPAV on parallel port"); | 724 | strcpy(card->shortname, "MTPAV on parallel port"); |
749 | memset(longname_buffer, 0, sizeof(longname_buffer)); | 725 | snprintf(card->longname, sizeof(card->longname), |
750 | sprintf(longname_buffer, "MTPAV on parallel port at"); | 726 | "MTPAV on parallel port at 0x%lx", port); |
751 | 727 | ||
752 | err = snd_mtpav_get_RAWMIDI(mtp_card); | 728 | err = snd_mtpav_get_RAWMIDI(mtp_card); |
753 | //snd_printk("snd_mtapv_get_RAWMIDI returned: %d\n", err); | ||
754 | if (err < 0) | 729 | if (err < 0) |
755 | goto __error; | 730 | goto __error; |
756 | 731 | ||
757 | if ((err = snd_card_set_generic_dev(mtp_card->card)) < 0) | 732 | snd_mtpav_portscan(mtp_card); |
758 | goto __error; | ||
759 | |||
760 | err = snd_card_register(mtp_card->card); // don't snd_card_register until AFTER all cards reources done! | ||
761 | 733 | ||
762 | //printk("snd_card_register returned %d\n", err); | 734 | snd_card_set_dev(card, &dev->dev); |
735 | err = snd_card_register(mtp_card->card); | ||
763 | if (err < 0) | 736 | if (err < 0) |
764 | goto __error; | 737 | goto __error; |
765 | 738 | ||
766 | 739 | platform_set_drvdata(dev, card); | |
767 | snd_mtpav_portscan(mtp_card); | ||
768 | |||
769 | printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port); | 740 | printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port); |
770 | |||
771 | return 0; | 741 | return 0; |
772 | 742 | ||
773 | __error: | 743 | __error: |
774 | snd_card_free(mtp_card->card); | 744 | snd_card_free(card); |
775 | free_mtpav(mtp_card); | ||
776 | return err; | 745 | return err; |
777 | } | 746 | } |
778 | 747 | ||
779 | /* | 748 | static int snd_mtpav_remove(struct platform_device *devptr) |
780 | */ | 749 | { |
750 | snd_card_free(platform_get_drvdata(devptr)); | ||
751 | platform_set_drvdata(devptr, NULL); | ||
752 | return 0; | ||
753 | } | ||
781 | 754 | ||
782 | static void __exit alsa_card_mtpav_exit(void) | 755 | #define SND_MTPAV_DRIVER "snd_mtpav" |
756 | |||
757 | static struct platform_driver snd_mtpav_driver = { | ||
758 | .probe = snd_mtpav_probe, | ||
759 | .remove = snd_mtpav_remove, | ||
760 | .driver = { | ||
761 | .name = SND_MTPAV_DRIVER | ||
762 | }, | ||
763 | }; | ||
764 | |||
765 | static int __init alsa_card_mtpav_init(void) | ||
783 | { | 766 | { |
784 | if (mtp_card == NULL) | 767 | int err; |
785 | return; | 768 | |
786 | if (mtp_card->card) | 769 | if ((err = platform_driver_register(&snd_mtpav_driver)) < 0) |
787 | snd_card_free(mtp_card->card); | 770 | return err; |
788 | free_mtpav(mtp_card); | 771 | |
772 | device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0); | ||
773 | if (IS_ERR(device)) { | ||
774 | platform_driver_unregister(&snd_mtpav_driver); | ||
775 | return PTR_ERR(device); | ||
776 | } | ||
777 | return 0; | ||
789 | } | 778 | } |
790 | 779 | ||
791 | /* | 780 | static void __exit alsa_card_mtpav_exit(void) |
792 | */ | 781 | { |
782 | platform_device_unregister(device); | ||
783 | platform_driver_unregister(&snd_mtpav_driver); | ||
784 | } | ||
793 | 785 | ||
794 | module_init(alsa_card_mtpav_init) | 786 | module_init(alsa_card_mtpav_init) |
795 | module_exit(alsa_card_mtpav_exit) | 787 | module_exit(alsa_card_mtpav_exit) |