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