Ignore:
Timestamp:
Mar 24, 2008, 2:43:42 AM (17 years ago)
Author:
Paul Smedley
Message:

Update source to ALSA 1.0.16 level

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GPL/branches/uniaud-2.0/alsa-kernel/drivers/mtpav.c

    r32 r305  
    22 *      MOTU Midi Timepiece ALSA Main routines
    33 *      Copyright by Michael T. Mayers (c) Jan 09, 2000
    4  *      mail: tweakoz@pacbell.net
     4 *      mail: michael@tweakoz.com
    55 *      Thanks to John Galbraith
    66 *
     
    1717 *      You should have received a copy of the GNU General Public License
    1818 *      along with this program; if not, write to the Free Software
    19  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     19 *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    2020 *
    2121 *
     
    4545 *      - Recoded & debugged
    4646 *      - Added timer interrupt for midi outputs
    47  *      - snd_hwports is between 1 and 8, which specifies the number of hardware ports.
     47 *      - hwports is between 1 and 8, which specifies the number of hardware ports.
    4848 *        The three global ports, computer, adat and broadcast ports, are created
    4949 *        always after h/w and remote ports.
     
    5151 */
    5252
    53 #define SNDRV_MAIN_OBJECT_FILE
    54 #include <sound/driver.h>
    55 #define SNDRV_GET_ID
     53#include <linux/init.h>
     54#include <linux/interrupt.h>
     55#include <linux/err.h>
     56#include <linux/platform_device.h>
     57#include <linux/slab.h>
     58#include <linux/ioport.h>
     59#include <linux/moduleparam.h>
     60#include <sound/core.h>
    5661#include <sound/initval.h>
    5762#include <sound/rawmidi.h>
     63#include <linux/delay.h>
     64
     65#include <asm/io.h>
    5866
    5967/*
    6068 *      globals
    6169 */
    62 EXPORT_NO_SYMBOLS;
     70MODULE_AUTHOR("Michael T. Mayers");
    6371MODULE_DESCRIPTION("MOTU MidiTimePiece AV multiport MIDI");
    64 MODULE_CLASSES("{sound}");
    65 MODULE_DEVICES("{{MOTU,MidiTimePiece AV multiport MIDI}}");
     72MODULE_LICENSE("GPL");
     73MODULE_SUPPORTED_DEVICE("{{MOTU,MidiTimePiece AV multiport MIDI}}");
    6674
    6775// io resources
     
    7078#define MTPAV_MAX_PORTS         8
    7179
    72 static int snd_index = SNDRV_DEFAULT_IDX1;
    73 static char *snd_id = SNDRV_DEFAULT_STR1;
    74 static long snd_port = MTPAV_IOBASE;    /* 0x378, 0x278 */
    75 static int snd_irq = MTPAV_IRQ;         /* 7, 5 */
    76 static int snd_hwports = MTPAV_MAX_PORTS;       /* use hardware ports 1-8 */
    77 
    78 MODULE_PARM(snd_index, "i");
    79 MODULE_PARM_DESC(snd_index, "Index value for MotuMTPAV MIDI.");
    80 MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);
    81 MODULE_PARM(snd_id, "s");
    82 MODULE_PARM_DESC(snd_id, "ID string for MotuMTPAV MIDI.");
    83 MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);
    84 MODULE_PARM(snd_port, "l");
    85 MODULE_PARM_DESC(snd_port, "Parallel port # for MotuMTPAV MIDI.");
    86 MODULE_PARM_SYNTAX(snd_port, "allows:{{0x378},{0x278}},dialog:list");
    87 MODULE_PARM(snd_irq, "i");
    88 MODULE_PARM_DESC(snd_irq, "Parallel IRQ # for MotuMTPAV MIDI.");
    89 MODULE_PARM_SYNTAX(snd_irq,  "allows:{{7},{5}},dialog:list");
    90 MODULE_PARM(snd_hwports, "i");
    91 MODULE_PARM_DESC(snd_hwports, "Hardware ports # for MotuMTPAV MIDI.");
    92 MODULE_PARM_SYNTAX(snd_hwports, "allows:{{1,8}},dialog:list");
     80static int index = SNDRV_DEFAULT_IDX1;
     81static char *id = SNDRV_DEFAULT_STR1;
     82static long port = MTPAV_IOBASE;        /* 0x378, 0x278 */
     83static int irq = MTPAV_IRQ;             /* 7, 5 */
     84static int hwports = MTPAV_MAX_PORTS;   /* use hardware ports 1-8 */
     85
     86module_param(index, int, 0444);
     87MODULE_PARM_DESC(index, "Index value for MotuMTPAV MIDI.");
     88module_param(id, charp, 0444);
     89MODULE_PARM_DESC(id, "ID string for MotuMTPAV MIDI.");
     90module_param(port, long, 0444);
     91MODULE_PARM_DESC(port, "Parallel port # for MotuMTPAV MIDI.");
     92module_param(irq, int, 0444);
     93MODULE_PARM_DESC(irq, "Parallel IRQ # for MotuMTPAV MIDI.");
     94module_param(hwports, int, 0444);
     95MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
     96
     97static struct platform_device *device;
    9398
    9499/*
    95100 *      defines
    96101 */
    97 //#define USE_FAKE_MTP //       dont actually read/write to MTP device (for debugging without an actual unit) (does not work yet)
     102//#define USE_FAKE_MTP //       don't actually read/write to MTP device (for debugging without an actual unit) (does not work yet)
    98103
    99104// parallel port usage masks
     
    124129 */
    125130
    126 typedef struct mtpav_port {
     131struct mtpav_port {
    127132        u8 number;
    128133        u8 hwport;
    129134        u8 mode;
    130         snd_rawmidi_substream_t *input;
    131         snd_rawmidi_substream_t *output;
    132 } mtpav_port_t;
    133 
    134 typedef struct mtpav {
    135         snd_card_t *card;
     135        u8 running_status;
     136        struct snd_rawmidi_substream *input;
     137        struct snd_rawmidi_substream *output;
     138};
     139
     140struct mtpav {
     141        struct snd_card *card;
    136142        unsigned long port;
    137143        struct resource *res_port;
     
    141147        int istimer;                    /* number of accesses to timer interrupts */
    142148        struct timer_list timer;        /* timer interrupts for outputs */
    143         snd_rawmidi_t *rmidi;
     149        struct snd_rawmidi *rmidi;
    144150        int num_ports;          /* number of hw ports (1-8) */
    145         mtpav_port_t ports[NUMPORTS];   /* all ports including computer, adat and bc */
     151        struct mtpav_port ports[NUMPORTS];      /* all ports including computer, adat and bc */
    146152
    147153        u32 inmidiport;         /* selected input midi port */
     
    149155
    150156        u32 outmidihwport;      /* selected output midi hw port */
    151 } mtpav_t;
    152 
    153 
    154 /*
    155  * global instance
    156  * hey, we handle at most only one card..
    157  */
    158 static mtpav_t *mtp_card;
     157};
     158
    159159
    160160/*
     
    181181
    182182
    183 static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev)
     183static int translate_subdevice_to_hwport(struct mtpav *chip, int subdev)
    184184{
    185185        if (subdev < 0)
     
    196196}
    197197
    198 static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport)
    199 {
    200         int port;
     198static int translate_hwport_to_subdevice(struct mtpav *chip, int hwport)
     199{
     200        int p;
    201201        if (hwport <= 0x00) /* all ports */
    202202                return chip->num_ports + MTPAV_PIDX_BROADCAST;
    203203        else if (hwport <= 0x08) { /* single port */
    204                 port = hwport - 1;
    205                 if (port >= chip->num_ports)
    206                         port = 0;
    207                 return port;
     204                p = hwport - 1;
     205                if (p >= chip->num_ports)
     206                        p = 0;
     207                return p;
    208208        } else if (hwport <= 0x10) { /* remote port */
    209                 port = hwport - 0x09 + chip->num_ports;
    210                 if (port >= chip->num_ports * 2)
    211                         port = chip->num_ports;
    212                 return port;
     209                p = hwport - 0x09 + chip->num_ports;
     210                if (p >= chip->num_ports * 2)
     211                        p = chip->num_ports;
     212                return p;
    213213        } else if (hwport == 0x11)  /* computer port */
    214214                return chip->num_ports + MTPAV_PIDX_COMPUTER;
     
    221221 */
    222222
    223 static u8 snd_mtpav_getreg(mtpav_t *chip, u16 reg)
     223static u8 snd_mtpav_getreg(struct mtpav *chip, u16 reg)
    224224{
    225225        u8 rval = 0;
     
    239239 */
    240240
    241 static void snd_mtpav_mputreg(mtpav_t *chip, u16 reg, u8 val)
    242 {
    243         if (reg == DREG) {
    244                 outb(val, chip->port + DREG);
    245         } else if (reg == CREG) {
    246                 outb(val, chip->port + CREG);
    247         }
    248 }
    249 
    250 /*
    251  */
    252 
    253 static void snd_mtpav_wait_rfdhi(mtpav_t *chip)
     241static inline void snd_mtpav_mputreg(struct mtpav *chip, u16 reg, u8 val)
     242{
     243        if (reg == DREG || reg == CREG)
     244                outb(val, chip->port + reg);
     245}
     246
     247/*
     248 */
     249
     250static void snd_mtpav_wait_rfdhi(struct mtpav *chip)
    254251{
    255252        int counts = 10000;
     
    263260}
    264261
    265 static void snd_mtpav_send_byte(mtpav_t *chip, u8 byte)
     262static void snd_mtpav_send_byte(struct mtpav *chip, u8 byte)
    266263{
    267264        u8 tcbyt;
     
    289286
    290287/* call this with spin lock held */
    291 static void snd_mtpav_output_port_write(mtpav_port_t *port,
    292                                         snd_rawmidi_substream_t *substream)
     288static void snd_mtpav_output_port_write(struct mtpav *mtp_card,
     289                                        struct mtpav_port *portp,
     290                                        struct snd_rawmidi_substream *substream)
    293291{
    294292        u8 outbyte;
    295293
     294        // Get the outbyte first, so we can emulate running status if
     295        // necessary
     296        if (snd_rawmidi_transmit(substream, &outbyte, 1) != 1)
     297                return;
     298
    296299        // send port change command if necessary
    297300
    298         if (port->hwport != mtp_card->outmidihwport) {
    299                 mtp_card->outmidihwport = port->hwport;
     301        if (portp->hwport != mtp_card->outmidihwport) {
     302                mtp_card->outmidihwport = portp->hwport;
    300303
    301304                snd_mtpav_send_byte(mtp_card, 0xf5);
    302                 snd_mtpav_send_byte(mtp_card, port->hwport);
    303                 //snd_printk("new outport: 0x%x\n", (unsigned int) port->hwport);
    304 
     305                snd_mtpav_send_byte(mtp_card, portp->hwport);
     306                //snd_printk("new outport: 0x%x\n", (unsigned int) portp->hwport);
     307
     308                if (!(outbyte & 0x80) && portp->running_status)
     309                        snd_mtpav_send_byte(mtp_card, portp->running_status);
    305310        }
    306311
    307312        // send data
    308313
    309         while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1)
     314        do {
     315                if (outbyte & 0x80)
     316                        portp->running_status = outbyte;
     317               
    310318                snd_mtpav_send_byte(mtp_card, outbyte);
    311 }
    312 
    313 static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream)
    314 {
    315         mtpav_port_t *port = &mtp_card->ports[substream->number];
     319        } while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1);
     320}
     321
     322static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream)
     323{
     324        struct mtpav *mtp_card = substream->rmidi->private_data;
     325        struct mtpav_port *portp = &mtp_card->ports[substream->number];
    316326        unsigned long flags;
    317327
    318328        spin_lock_irqsave(&mtp_card->spinlock, flags);
    319         snd_mtpav_output_port_write(port, substream);
     329        snd_mtpav_output_port_write(mtp_card, portp, substream);
    320330        spin_unlock_irqrestore(&mtp_card->spinlock, flags);
    321331}
     
    326336 */
    327337
    328 static void snd_mtpav_portscan(mtpav_t *chip)   // put mtp into smart routing mode
    329 {
    330         u8 port;
    331 
    332         for (port = 0; port < 8; port++) {
     338static void snd_mtpav_portscan(struct mtpav *chip)      // put mtp into smart routing mode
     339{
     340        u8 p;
     341
     342        for (p = 0; p < 8; p++) {
    333343                snd_mtpav_send_byte(chip, 0xf5);
    334                 snd_mtpav_send_byte(chip, port);
     344                snd_mtpav_send_byte(chip, p);
    335345                snd_mtpav_send_byte(chip, 0xfe);
    336346        }
     
    340350 */
    341351
    342 static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream)
    343 {
    344         unsigned long flags;
    345         mtpav_port_t *port = &mtp_card->ports[substream->number];
    346 
    347         //printk("mtpav port: %d opened\n", (int) substream->number);
     352static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream)
     353{
     354        struct mtpav *mtp_card = substream->rmidi->private_data;
     355        struct mtpav_port *portp = &mtp_card->ports[substream->number];
     356        unsigned long flags;
     357
    348358        spin_lock_irqsave(&mtp_card->spinlock, flags);
    349         port->mode |= MTPAV_MODE_INPUT_OPENED;
    350         port->input = substream;
     359        portp->mode |= MTPAV_MODE_INPUT_OPENED;
     360        portp->input = substream;
    351361        if (mtp_card->share_irq++ == 0)
    352362                snd_mtpav_mputreg(mtp_card, CREG, (SIGC_INTEN | SIGC_WRITE));   // enable pport interrupts
     
    358368 */
    359369
    360 static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream)
    361 {
    362         unsigned long flags;
    363         mtpav_port_t *port = &mtp_card->ports[substream->number];
    364 
    365         //printk("mtpav port: %d closed\n", (int) port);
     370static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream)
     371{
     372        struct mtpav *mtp_card = substream->rmidi->private_data;
     373        struct mtpav_port *portp = &mtp_card->ports[substream->number];
     374        unsigned long flags;
    366375
    367376        spin_lock_irqsave(&mtp_card->spinlock, flags);
    368 
    369         port->mode &= (~MTPAV_MODE_INPUT_OPENED);
    370         port->input = NULL;
     377        portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
     378        portp->input = NULL;
    371379        if (--mtp_card->share_irq == 0)
    372380                snd_mtpav_mputreg(mtp_card, CREG, 0);   // disable pport interrupts
    373 
    374381        spin_unlock_irqrestore(&mtp_card->spinlock, flags);
    375382        return 0;
     
    379386 */
    380387
    381 static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up)
    382 {
    383         unsigned long flags;
    384         mtpav_port_t *port = &mtp_card->ports[substream->number];
     388static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int up)
     389{
     390        struct mtpav *mtp_card = substream->rmidi->private_data;
     391        struct mtpav_port *portp = &mtp_card->ports[substream->number];
     392        unsigned long flags;
    385393
    386394        spin_lock_irqsave(&mtp_card->spinlock, flags);
    387395        if (up)
    388                 port->mode |= MTPAV_MODE_INPUT_TRIGGERED;
     396                portp->mode |= MTPAV_MODE_INPUT_TRIGGERED;
    389397        else
    390                 port->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
     398                portp->mode &= ~MTPAV_MODE_INPUT_TRIGGERED;
    391399        spin_unlock_irqrestore(&mtp_card->spinlock, flags);
    392400
     
    400408static void snd_mtpav_output_timer(unsigned long data)
    401409{
    402         mtpav_t *chip = snd_magic_cast(mtpav_t, (void *)data, return);
     410        unsigned long flags;
     411        struct mtpav *chip = (struct mtpav *)data;
    403412        int p;
    404413
    405         spin_lock(&chip->spinlock);
     414        spin_lock_irqsave(&chip->spinlock, flags);
    406415        /* reprogram timer */
    407416        chip->timer.expires = 1 + jiffies;
     
    409418        /* process each port */
    410419        for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
    411                 mtpav_port_t *port = &mtp_card->ports[p];
    412                 if ((port->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && port->output)
    413                         snd_mtpav_output_port_write(port, port->output);
    414         }
    415         spin_unlock(&chip->spinlock);
    416 }
    417 
    418 static void snd_mtpav_add_output_timer(mtpav_t *chip)
    419 {
    420         unsigned long flags;
    421 
    422         spin_lock_irqsave(&chip->spinlock, flags);
    423         chip->timer.function = snd_mtpav_output_timer;
    424         chip->timer.data = (unsigned long) mtp_card;
     420                struct mtpav_port *portp = &chip->ports[p];
     421                if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
     422                        snd_mtpav_output_port_write(chip, portp, portp->output);
     423        }
     424        spin_unlock_irqrestore(&chip->spinlock, flags);
     425}
     426
     427/* spinlock held! */
     428static void snd_mtpav_add_output_timer(struct mtpav *chip)
     429{
    425430        chip->timer.expires = 1 + jiffies;
    426431        add_timer(&chip->timer);
    427         spin_unlock_irqrestore(&chip->spinlock, flags);
    428 }
    429 
    430 static void snd_mtpav_remove_output_timer(mtpav_t *chip)
    431 {
    432         unsigned long flags;
    433 
    434         spin_lock_irqsave(&chip->spinlock, flags);
     432}
     433
     434/* spinlock held! */
     435static void snd_mtpav_remove_output_timer(struct mtpav *chip)
     436{
    435437        del_timer(&chip->timer);
    436         spin_unlock_irqrestore(&chip->spinlock, flags);
    437 }
    438 
    439 /*
    440  */
    441 
    442 static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream)
    443 {
    444         unsigned long flags;
    445         mtpav_port_t *port = &mtp_card->ports[substream->number];
     438}
     439
     440/*
     441 */
     442
     443static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream)
     444{
     445        struct mtpav *mtp_card = substream->rmidi->private_data;
     446        struct mtpav_port *portp = &mtp_card->ports[substream->number];
     447        unsigned long flags;
    446448
    447449        spin_lock_irqsave(&mtp_card->spinlock, flags);
    448         port->mode |= MTPAV_MODE_OUTPUT_OPENED;
    449         port->output = substream;
     450        portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
     451        portp->output = substream;
    450452        spin_unlock_irqrestore(&mtp_card->spinlock, flags);
    451453        return 0;
     
    455457 */
    456458
    457 static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream)
    458 {
    459         unsigned long flags;
    460         mtpav_port_t *port = &mtp_card->ports[substream->number];
     459static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream)
     460{
     461        struct mtpav *mtp_card = substream->rmidi->private_data;
     462        struct mtpav_port *portp = &mtp_card->ports[substream->number];
     463        unsigned long flags;
    461464
    462465        spin_lock_irqsave(&mtp_card->spinlock, flags);
    463         port->mode &= (~MTPAV_MODE_OUTPUT_OPENED);
    464         port->output = NULL;
     466        portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
     467        portp->output = NULL;
    465468        spin_unlock_irqrestore(&mtp_card->spinlock, flags);
    466469        return 0;
     
    470473 */
    471474
    472 static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up)
    473 {
    474         unsigned long flags;
    475         mtpav_port_t *port = &mtp_card->ports[substream->number];
     475static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, int up)
     476{
     477        struct mtpav *mtp_card = substream->rmidi->private_data;
     478        struct mtpav_port *portp = &mtp_card->ports[substream->number];
     479        unsigned long flags;
    476480
    477481        spin_lock_irqsave(&mtp_card->spinlock, flags);
    478482        if (up) {
    479                 if (! (port->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
     483                if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
    480484                        if (mtp_card->istimer++ == 0)
    481485                                snd_mtpav_add_output_timer(mtp_card);
    482                         port->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
     486                        portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
    483487                }
    484488        } else {
    485                 port->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
     489                portp->mode &= ~MTPAV_MODE_OUTPUT_TRIGGERED;
    486490                if (--mtp_card->istimer == 0)
    487491                        snd_mtpav_remove_output_timer(mtp_card);
     
    497501 */
    498502
    499 static void snd_mtpav_inmidi_process(mtpav_t *mcrd, u8 inbyte)
    500 {
    501         mtpav_port_t *port;
    502 
    503         if (mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
     503static void snd_mtpav_inmidi_process(struct mtpav *mcrd, u8 inbyte)
     504{
     505        struct mtpav_port *portp;
     506
     507        if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
    504508                return;
    505509
    506         port = &mcrd->ports[mcrd->inmidiport];
    507         if (port->mode & MTPAV_MODE_INPUT_TRIGGERED)
    508                 snd_rawmidi_receive(port->input, &inbyte, 1);
    509 }
    510 
    511 static void snd_mtpav_inmidi_h(mtpav_t * mcrd, u8 inbyte)
    512 {
    513 #ifndef TARGET_OS2
    514         snd_assert(mcrd, return);
    515 #endif
     510        portp = &mcrd->ports[mcrd->inmidiport];
     511        if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED)
     512                snd_rawmidi_receive(portp->input, &inbyte, 1);
     513}
     514
     515static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
     516{
    516517        if (inbyte >= 0xf8) {
    517518                /* real-time midi code */
     
    531532}
    532533
    533 static void snd_mtpav_read_bytes(mtpav_t * mcrd)
     534static void snd_mtpav_read_bytes(struct mtpav *mcrd)
    534535{
    535536        u8 clrread, setread;
     
    569570}
    570571
    571 static void snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs)
    572 {
    573         mtpav_t *mcard = snd_magic_cast(mtpav_t, dev_id, return);
    574 
    575         //printk("irqh()\n");
     572static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
     573{
     574        struct mtpav *mcard = dev_id;
     575
    576576        spin_lock(&mcard->spinlock);
    577577        snd_mtpav_read_bytes(mcard);
    578578        spin_unlock(&mcard->spinlock);
     579        return IRQ_HANDLED;
    579580}
    580581
     
    582583 * get ISA resources
    583584 */
    584 static int snd_mtpav_get_ISA(mtpav_t * mcard)
    585 {
    586         if ((mcard->res_port = request_region(snd_port, 3, "MotuMTPAV MIDI")) == NULL) {
    587                 snd_printk("MTVAP port 0x%lx is busy\n", snd_port);
     585static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard)
     586{
     587        if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
     588                snd_printk("MTVAP port 0x%lx is busy\n", port);
    588589                return -EBUSY;
    589590        }
    590         mcard->port = snd_port;
    591         if (request_irq(snd_irq, snd_mtpav_irqh, SA_INTERRUPT, "MOTU MTPAV", (void *)mcard)) {
    592                 snd_printk("MTVAP IRQ %d busy\n", snd_irq);
     591        mcard->port = port;
     592        if (request_irq(irq, snd_mtpav_irqh, IRQF_DISABLED, "MOTU MTPAV", mcard)) {
     593                snd_printk("MTVAP IRQ %d busy\n", irq);
    593594                return -EBUSY;
    594595        }
    595         mcard->irq = snd_irq;
     596        mcard->irq = irq;
    596597        return 0;
    597598}
     
    601602 */
    602603
    603 #ifdef TARGET_OS2
    604 static snd_rawmidi_ops_t snd_mtpav_output = {
    605         snd_mtpav_output_open,
    606         snd_mtpav_output_close,
    607         snd_mtpav_output_trigger,
    608         0
     604static struct snd_rawmidi_ops snd_mtpav_output = {
     605        .open =         snd_mtpav_output_open,
     606        .close =        snd_mtpav_output_close,
     607        .trigger =      snd_mtpav_output_trigger,
    609608};
    610609
    611 static snd_rawmidi_ops_t snd_mtpav_input = {
    612         snd_mtpav_input_open,
    613         snd_mtpav_input_close,
    614         snd_mtpav_input_trigger,
    615         0
     610static struct snd_rawmidi_ops snd_mtpav_input = {
     611        .open =         snd_mtpav_input_open,
     612        .close =        snd_mtpav_input_close,
     613        .trigger =      snd_mtpav_input_trigger,
    616614};
    617 #else
    618 static snd_rawmidi_ops_t snd_mtpav_output = {
    619         open:           snd_mtpav_output_open,
    620         close:          snd_mtpav_output_close,
    621         trigger:        snd_mtpav_output_trigger,
    622 };
    623 
    624 static snd_rawmidi_ops_t snd_mtpav_input = {
    625         open:           snd_mtpav_input_open,
    626         close:          snd_mtpav_input_close,
    627         trigger:        snd_mtpav_input_trigger,
    628 };
    629 #endif
     615
    630616
    631617/*
     
    633619 */
    634620
    635 static void snd_mtpav_set_name(mtpav_t *chip, snd_rawmidi_substream_t *substream)
     621static void __devinit snd_mtpav_set_name(struct mtpav *chip,
     622                                      struct snd_rawmidi_substream *substream)
    636623{
    637624        if (substream->number >= 0 && substream->number < chip->num_ports)
     
    647634}
    648635
    649 static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard)
    650 {
    651         int rval = 0;
    652         snd_rawmidi_t *rawmidi;
    653         snd_rawmidi_substream_t *substream;
     636static int __devinit snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
     637{
     638        int rval;
     639        struct snd_rawmidi *rawmidi;
     640        struct snd_rawmidi_substream *substream;
    654641        struct list_head *list;
    655642
    656         //printk("entering snd_mtpav_get_RAWMIDI\n");
    657 
    658         if (snd_hwports < 1)
    659                 mcard->num_ports = 1;
    660         else if (snd_hwports > 8)
    661                 mcard->num_ports = 8;
    662         else
    663                 mcard->num_ports = snd_hwports;
     643        if (hwports < 1)
     644                hwports = 1;
     645        else if (hwports > 8)
     646                hwports = 8;
     647        mcard->num_ports = hwports;
    664648
    665649        if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
     
    669653                return rval;
    670654        rawmidi = mcard->rmidi;
     655        rawmidi->private_data = mcard;
    671656
    672657        list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
    673                 substream = list_entry(list, snd_rawmidi_substream_t, list);
     658                substream = list_entry(list, struct snd_rawmidi_substream, list);
    674659                snd_mtpav_set_name(mcard, substream);
    675660                substream->ops = &snd_mtpav_input;
    676661        }
    677662        list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
    678                 substream = list_entry(list, snd_rawmidi_substream_t, list);
     663                substream = list_entry(list, struct snd_rawmidi_substream, list);
    679664                snd_mtpav_set_name(mcard, substream);
    680665                substream->ops = &snd_mtpav_output;
     
    684669                               SNDRV_RAWMIDI_INFO_DUPLEX;
    685670        sprintf(rawmidi->name, "MTP AV MIDI");
    686         //printk("exiting snd_mtpav_get_RAWMIDI() \n");
    687671        return 0;
    688672}
     
    691675 */
    692676
    693 static mtpav_t *new_mtpav(void)
    694 {
    695         mtpav_t *ncrd = (mtpav_t *) snd_kcalloc(sizeof(mtpav_t), GFP_KERNEL);
    696         if (ncrd != NULL) {
    697                 spin_lock_init(&ncrd->spinlock);
    698 
    699                 ncrd->card = NULL;
    700                 ncrd->irq = -1;
    701                 ncrd->share_irq = 0;
    702 
    703                 ncrd->inmidiport = 0xffffffff;
    704                 ncrd->inmidistate = 0;
    705                 ncrd->outmidihwport = 0xffffffff;
    706         }
    707         return ncrd;
    708 }
    709 
    710 /*
    711  */
    712 
    713 static void free_mtpav(mtpav_t * crd)
    714 {
     677static void snd_mtpav_free(struct snd_card *card)
     678{
     679        struct mtpav *crd = card->private_data;
    715680        unsigned long flags;
    716681
     
    721686        if (crd->irq >= 0)
    722687                free_irq(crd->irq, (void *)crd);
    723         if (crd->res_port)
    724                 release_resource(crd->res_port);
    725         if (crd != NULL)
    726                 kfree(crd);
    727 }
    728 
    729 /*
    730  */
    731 
    732 static int __init alsa_card_mtpav_init(void)
    733 {
    734         int err = 0;
    735         char longname_buffer[80];
    736 
    737         mtp_card = new_mtpav();
    738         if (mtp_card == NULL)
     688        release_and_free_resource(crd->res_port);
     689}
     690
     691/*
     692 */
     693static int __devinit snd_mtpav_probe(struct platform_device *dev)
     694{
     695        struct snd_card *card;
     696        int err;
     697        struct mtpav *mtp_card;
     698
     699        card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card));
     700        if (! card)
    739701                return -ENOMEM;
    740702
    741         mtp_card->card = snd_card_new(snd_index, snd_id, THIS_MODULE, 0);
    742         if (mtp_card->card == NULL) {
    743                 free_mtpav(mtp_card);
    744                 return -ENOMEM;
    745         }
     703        mtp_card = card->private_data;
     704        spin_lock_init(&mtp_card->spinlock);
     705        init_timer(&mtp_card->timer);
     706        mtp_card->card = card;
     707        mtp_card->irq = -1;
     708        mtp_card->share_irq = 0;
     709        mtp_card->inmidiport = 0xffffffff;
     710        mtp_card->inmidistate = 0;
     711        mtp_card->outmidihwport = 0xffffffff;
     712        init_timer(&mtp_card->timer);
     713        mtp_card->timer.function = snd_mtpav_output_timer;
     714        mtp_card->timer.data = (unsigned long) mtp_card;
     715
     716        card->private_free = snd_mtpav_free;
    746717
    747718        err = snd_mtpav_get_ISA(mtp_card);
    748         //printk("snd_mtpav_get_ISA returned: %d\n", err);
    749719        if (err < 0)
    750720                goto __error;
    751721
    752         strcpy(mtp_card->card->driver, "MTPAV");
    753         strcpy(mtp_card->card->shortname, "MTPAV on parallel port");
    754         memset(longname_buffer, 0, sizeof(longname_buffer));
    755         sprintf(longname_buffer, "MTPAV on parallel port at");
     722        strcpy(card->driver, "MTPAV");
     723        strcpy(card->shortname, "MTPAV on parallel port");
     724        snprintf(card->longname, sizeof(card->longname),
     725                 "MTPAV on parallel port at 0x%lx", port);
    756726
    757727        err = snd_mtpav_get_RAWMIDI(mtp_card);
    758         //snd_printk("snd_mtapv_get_RAWMIDI returned: %d\n", err);
    759728        if (err < 0)
    760729                goto __error;
    761730
    762         err = snd_card_register(mtp_card->card);        // dont snd_card_register until AFTER all cards reources done!
    763 
    764         //printk("snd_card_register returned %d\n", err);
     731        snd_mtpav_portscan(mtp_card);
     732
     733        snd_card_set_dev(card, &dev->dev);
     734        err = snd_card_register(mtp_card->card);
    765735        if (err < 0)
    766736                goto __error;
    767737
    768 
    769         snd_mtpav_portscan(mtp_card);
    770 
    771         snd_printk("Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", snd_irq, snd_port);
    772 
     738        platform_set_drvdata(dev, card);
     739        printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
    773740        return 0;
    774741
    775       __error:
    776         snd_card_free(mtp_card->card);
    777         free_mtpav(mtp_card);
     742 __error:
     743        snd_card_free(card);
    778744        return err;
    779745}
    780746
    781 /*
    782  */
     747static int __devexit snd_mtpav_remove(struct platform_device *devptr)
     748{
     749        snd_card_free(platform_get_drvdata(devptr));
     750        platform_set_drvdata(devptr, NULL);
     751        return 0;
     752}
     753
     754#define SND_MTPAV_DRIVER        "snd_mtpav"
     755
     756static struct platform_driver snd_mtpav_driver = {
     757        .probe          = snd_mtpav_probe,
     758        .remove         = __devexit_p(snd_mtpav_remove),
     759        .driver         = {
     760                .name   = SND_MTPAV_DRIVER
     761        },
     762};
     763
     764static int __init alsa_card_mtpav_init(void)
     765{
     766        int err;
     767
     768        if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
     769                return err;
     770
     771        device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
     772        if (!IS_ERR(device)) {
     773                if (platform_get_drvdata(device))
     774                        return 0;
     775                platform_device_unregister(device);
     776                err = -ENODEV;
     777        } else
     778                err = PTR_ERR(device);
     779        platform_driver_unregister(&snd_mtpav_driver);
     780        return err;
     781}
    783782
    784783static void __exit alsa_card_mtpav_exit(void)
    785784{
    786         if (mtp_card == NULL)
    787                 return;
    788         if (mtp_card->card)
    789                 snd_card_free(mtp_card->card);
    790         free_mtpav(mtp_card);
    791 }
    792 
    793 /*
    794  */
     785        platform_device_unregister(device);
     786        platform_driver_unregister(&snd_mtpav_driver);
     787}
    795788
    796789module_init(alsa_card_mtpav_init)
    797790module_exit(alsa_card_mtpav_exit)
    798 
    799 #ifndef MODULE
    800 
    801 /* format is: snd-card-mtpav=snd_enable,snd_index,snd_id,
    802                              snd_port,snd_irq,snd_hwports */
    803 
    804 static int __init alsa_card_mtpav_setup(char *str)
    805 {
    806         int __attribute__ ((__unused__)) enable = 1;
    807 
    808         (void)(get_option(&str,&enable) == 2 &&
    809                get_option(&str,&snd_index) == 2 &&
    810                get_id(&str,&snd_id) == 2 &&
    811                get_option(&str,(int *)&snd_port) == 2 &&
    812                get_option(&str,&snd_irq) == 2 &&
    813                get_option(&str,&snd_hwports) == 2);
    814         return 1;
    815 }
    816 
    817 __setup("snd-card-mtpav=", alsa_card_mtpav_setup);
    818 
    819 #endif /* ifndef MODULE */
Note: See TracChangeset for help on using the changeset viewer.