aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers/mtpav.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/drivers/mtpav.c')
-rw-r--r--sound/drivers/mtpav.c306
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.");
93module_param(hwports, int, 0444); 95module_param(hwports, int, 0444);
94MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI."); 96MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
95 97
98static 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
128typedef struct mtpav_port { 132struct 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
137typedef struct mtpav { 141struct 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 */
161static 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
186static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev) 184static 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
201static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport) 199static 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
226static u8 snd_mtpav_getreg(mtpav_t *chip, u16 reg) 224static 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
244static void snd_mtpav_mputreg(mtpav_t *chip, u16 reg, u8 val) 242static 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
256static void snd_mtpav_wait_rfdhi(mtpav_t *chip) 251static 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
268static void snd_mtpav_send_byte(mtpav_t *chip, u8 byte) 263static 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 */
294static void snd_mtpav_output_port_write(mtpav_port_t *port, 289static 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
327static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream) 323static 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
342static void snd_mtpav_portscan(mtpav_t *chip) // put mtp into smart routing mode 339static 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
356static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream) 353static 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
374static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream) 371static 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
395static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up) 389static 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)
414static void snd_mtpav_output_timer(unsigned long data) 409static 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! */
434static void snd_mtpav_add_output_timer(mtpav_t *chip) 429static 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! */
444static void snd_mtpav_remove_output_timer(mtpav_t *chip) 436static 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
452static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream) 444static 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
467static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream) 460static 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
482static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up) 476static 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
509static void snd_mtpav_inmidi_process(mtpav_t *mcrd, u8 inbyte) 504static 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
522static void snd_mtpav_inmidi_h(mtpav_t * mcrd, u8 inbyte) 516static 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
543static void snd_mtpav_read_bytes(mtpav_t * mcrd) 535static 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
581static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs) 573static 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 */
595static int snd_mtpav_get_ISA(mtpav_t * mcard) 586static 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
614static snd_rawmidi_ops_t snd_mtpav_output = { 605static 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
620static snd_rawmidi_ops_t snd_mtpav_input = { 611static 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
631static void snd_mtpav_set_name(mtpav_t *chip, snd_rawmidi_substream_t *substream) 622static 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
645static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard) 637static 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
689static mtpav_t *new_mtpav(void) 678static 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{ 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 694static int __init snd_mtpav_probe(struct platform_device *dev)
727static 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/* 748static 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
782static void __exit alsa_card_mtpav_exit(void) 755#define SND_MTPAV_DRIVER "snd_mtpav"
756
757static 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
765static 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/* 780static void __exit alsa_card_mtpav_exit(void)
792 */ 781{
782 platform_device_unregister(device);
783 platform_driver_unregister(&snd_mtpav_driver);
784}
793 785
794module_init(alsa_card_mtpav_init) 786module_init(alsa_card_mtpav_init)
795module_exit(alsa_card_mtpav_exit) 787module_exit(alsa_card_mtpav_exit)