Ignore:
Timestamp:
Dec 11, 2005, 5:57:39 PM (20 years ago)
Author:
vladest
Message:

Latest update from ALSA. some intial > 15 interrupts support

Location:
GPL/trunk/alsa-kernel/drivers/opl3
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • GPL/trunk/alsa-kernel/drivers/opl3/opl3_lib.c

    r33 r34  
    33 *                   Hannu Savolainen 1993-1996,
    44 *                   Rob Hooft
    5  *
     5 *                   
    66 *  Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)
    77 *
     
    2424 */
    2525
    26 #define SNDRV_MAIN_OBJECT_FILE
    2726#include <sound/opl3.h>
     27#include <asm/io.h>
     28#include <linux/delay.h>
     29#include <linux/init.h>
     30#include <linux/slab.h>
     31#include <linux/ioport.h>
    2832#include <sound/minors.h>
    2933
     
    3438extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
    3539
    36 void snd_opl2_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
    37 {
    38     unsigned long flags;
    39     unsigned long port;
    40 
    41     /*
    42      * The original 2-OP synth requires a quite long delay
    43      * after writing to a register.
    44      */
    45 
    46     port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
    47 
    48     spin_lock_irqsave(&opl3->reg_lock, flags);
    49 
    50     outb((unsigned char) cmd, port);
    51     udelay(10);
    52 
    53     outb((unsigned char) val, port + 1);
    54     udelay(30);
    55 
    56     spin_unlock_irqrestore(&opl3->reg_lock, flags);
    57 }
    58 
    59 void snd_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
    60 {
    61     unsigned long flags;
    62     unsigned long port;
    63 
    64     /*
    65      * The OPL-3 survives with just two INBs
    66      * after writing to a register.
    67      */
    68 
    69     port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
    70 
    71     spin_lock_irqsave(&opl3->reg_lock, flags);
    72 
    73     outb((unsigned char) cmd, port);
    74     inb(opl3->l_port);
    75     inb(opl3->l_port);
    76 
    77     outb((unsigned char) val, port + 1);
    78     inb(opl3->l_port);
    79     inb(opl3->l_port);
    80 
    81     spin_unlock_irqrestore(&opl3->reg_lock, flags);
    82 }
    83 
    84 
    85 static int snd_opl3_detect(opl3_t * opl3)
    86 {
    87     /*
    88      * This function returns 1 if the FM chip is present at the given I/O port
    89      * The detection algorithm plays with the timer built in the FM chip and
    90      * looks for a change in the status register.
    91      *
    92      * Note! The timers of the FM chip are not connected to AdLib (and compatible)
    93      * boards.
    94      *
    95      * Note2! The chip is initialized if detected.
    96      */
    97 
    98     unsigned char stat1, stat2, signature;
    99 
    100     /* Reset timers 1 and 2 */
    101     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
    102     /* Reset the IRQ of the FM chip */
    103     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
    104     signature = stat1 = inb(opl3->l_port);      /* Status register */
    105     if ((stat1 & 0xe0) != 0x00) {       /* Should be 0x00 */
    106         snd_printd("OPL3: stat1 = 0x%x\n", stat1);
    107         return -ENODEV;
    108     }
    109     /* Set timer1 to 0xff */
    110     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 0xff);
    111     /* Unmask and start timer 1 */
    112     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER2_MASK | OPL3_TIMER1_START);
    113     /* Now we have to delay at least 80us */
    114     udelay(200);
    115     /* Read status after timers have expired */
    116     stat2 = inb(opl3->l_port);
    117     /* Stop the timers */
    118     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
    119     /* Reset the IRQ of the FM chip */
    120     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
    121     if ((stat2 & 0xe0) != 0xc0) {       /* There is no YM3812 */
    122         snd_printd("OPL3: stat2 = 0x%x\n", stat2);
    123         return -ENODEV;
    124     }
    125 
    126     /* If the toplevel code knows exactly the type of chip, don't try
    127      to detect it. */
    128     if (opl3->hardware != OPL3_HW_AUTO)
    129         return 0;
    130 
    131     /* There is a FM chip on this address. Detect the type (OPL2 to OPL4) */
    132     if (signature == 0x06) {    /* OPL2 */
    133         opl3->hardware = OPL3_HW_OPL2;
    134     } else {
    135         /*
    136          * If we had an OPL4 chip, opl3->hardware would have been set
    137          * by the OPL4 driver; so we can assume OPL3 here.
    138          */
    139         snd_assert(opl3->r_port != 0, return -ENODEV);
    140         opl3->hardware = OPL3_HW_OPL3;
    141     }
    142     return 0;
     40static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
     41{
     42        unsigned long flags;
     43        unsigned long port;
     44
     45        /*
     46         * The original 2-OP synth requires a quite long delay
     47         * after writing to a register.
     48         */
     49
     50        port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
     51
     52        spin_lock_irqsave(&opl3->reg_lock, flags);
     53
     54        outb((unsigned char) cmd, port);
     55        udelay(10);
     56
     57        outb((unsigned char) val, port + 1);
     58        udelay(30);
     59
     60        spin_unlock_irqrestore(&opl3->reg_lock, flags);
     61}
     62
     63static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
     64{
     65        unsigned long flags;
     66        unsigned long port;
     67
     68        /*
     69         * The OPL-3 survives with just two INBs
     70         * after writing to a register.
     71         */
     72
     73        port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
     74
     75        spin_lock_irqsave(&opl3->reg_lock, flags);
     76
     77        outb((unsigned char) cmd, port);
     78        inb(opl3->l_port);
     79        inb(opl3->l_port);
     80
     81        outb((unsigned char) val, port + 1);
     82        inb(opl3->l_port);
     83        inb(opl3->l_port);
     84
     85        spin_unlock_irqrestore(&opl3->reg_lock, flags);
     86}
     87
     88static int snd_opl3_detect(struct snd_opl3 * opl3)
     89{
     90        /*
     91         * This function returns 1 if the FM chip is present at the given I/O port
     92         * The detection algorithm plays with the timer built in the FM chip and
     93         * looks for a change in the status register.
     94         *
     95         * Note! The timers of the FM chip are not connected to AdLib (and compatible)
     96         * boards.
     97         *
     98         * Note2! The chip is initialized if detected.
     99         */
     100
     101        unsigned char stat1, stat2, signature;
     102
     103        /* Reset timers 1 and 2 */
     104        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
     105        /* Reset the IRQ of the FM chip */
     106        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
     107        signature = stat1 = inb(opl3->l_port);  /* Status register */
     108        if ((stat1 & 0xe0) != 0x00) {   /* Should be 0x00 */
     109                snd_printd("OPL3: stat1 = 0x%x\n", stat1);
     110                return -ENODEV;
     111        }
     112        /* Set timer1 to 0xff */
     113        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 0xff);
     114        /* Unmask and start timer 1 */
     115        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER2_MASK | OPL3_TIMER1_START);
     116        /* Now we have to delay at least 80us */
     117        udelay(200);
     118        /* Read status after timers have expired */
     119        stat2 = inb(opl3->l_port);
     120        /* Stop the timers */
     121        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
     122        /* Reset the IRQ of the FM chip */
     123        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
     124        if ((stat2 & 0xe0) != 0xc0) {   /* There is no YM3812 */
     125                snd_printd("OPL3: stat2 = 0x%x\n", stat2);
     126                return -ENODEV;
     127        }
     128
     129        /* If the toplevel code knows exactly the type of chip, don't try
     130           to detect it. */
     131        if (opl3->hardware != OPL3_HW_AUTO)
     132                return 0;
     133
     134        /* There is a FM chip on this address. Detect the type (OPL2 to OPL4) */
     135        if (signature == 0x06) {        /* OPL2 */
     136                opl3->hardware = OPL3_HW_OPL2;
     137        } else {
     138                /*
     139                 * If we had an OPL4 chip, opl3->hardware would have been set
     140                 * by the OPL4 driver; so we can assume OPL3 here.
     141                 */
     142                snd_assert(opl3->r_port != 0, return -ENODEV);
     143                opl3->hardware = OPL3_HW_OPL3;
     144        }
     145        return 0;
    143146}
    144147
     
    151154 */
    152155
    153 static int snd_opl3_timer1_start(snd_timer_t * timer)
    154 {
    155     unsigned long flags;
    156     unsigned char tmp;
    157     unsigned int ticks;
    158     opl3_t *opl3;
    159 
    160     opl3 = snd_timer_chip(timer);
    161     spin_lock_irqsave(&opl3->timer_lock, flags);
    162     ticks = timer->sticks;
    163     tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
    164     opl3->timer_enable = tmp;
    165     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks);      /* timer 1 count */
    166     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);       /* enable timer 1 IRQ */
    167     spin_unlock_irqrestore(&opl3->timer_lock, flags);
    168     return 0;
    169 }
    170 
    171 static int snd_opl3_timer1_stop(snd_timer_t * timer)
    172 {
    173     unsigned long flags;
    174     unsigned char tmp;
    175     opl3_t *opl3;
    176 
    177     opl3 = snd_timer_chip(timer);
    178     spin_lock_irqsave(&opl3->timer_lock, flags);
    179     tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
    180     opl3->timer_enable = tmp;
    181     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);       /* disable timer #1 */
    182     spin_unlock_irqrestore(&opl3->timer_lock, flags);
    183     return 0;
     156static int snd_opl3_timer1_start(struct snd_timer * timer)
     157{
     158        unsigned long flags;
     159        unsigned char tmp;
     160        unsigned int ticks;
     161        struct snd_opl3 *opl3;
     162
     163        opl3 = snd_timer_chip(timer);
     164        spin_lock_irqsave(&opl3->timer_lock, flags);
     165        ticks = timer->sticks;
     166        tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
     167        opl3->timer_enable = tmp;
     168        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks);  /* timer 1 count */
     169        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* enable timer 1 IRQ */
     170        spin_unlock_irqrestore(&opl3->timer_lock, flags);
     171        return 0;
     172}
     173
     174static int snd_opl3_timer1_stop(struct snd_timer * timer)
     175{
     176        unsigned long flags;
     177        unsigned char tmp;
     178        struct snd_opl3 *opl3;
     179
     180        opl3 = snd_timer_chip(timer);
     181        spin_lock_irqsave(&opl3->timer_lock, flags);
     182        tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
     183        opl3->timer_enable = tmp;
     184        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* disable timer #1 */
     185        spin_unlock_irqrestore(&opl3->timer_lock, flags);
     186        return 0;
    184187}
    185188
     
    188191 */
    189192
    190 static int snd_opl3_timer2_start(snd_timer_t * timer)
    191 {
    192     unsigned long flags;
    193     unsigned char tmp;
    194     unsigned int ticks;
    195     opl3_t *opl3;
    196 
    197     opl3 = snd_timer_chip(timer);
    198     spin_lock_irqsave(&opl3->timer_lock, flags);
    199     ticks = timer->sticks;
    200     tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
    201     opl3->timer_enable = tmp;
    202     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks);      /* timer 1 count */
    203     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);       /* enable timer 1 IRQ */
    204     spin_unlock_irqrestore(&opl3->timer_lock, flags);
    205     return 0;
    206 }
    207 
    208 static int snd_opl3_timer2_stop(snd_timer_t * timer)
    209 {
    210     unsigned long flags;
    211     unsigned char tmp;
    212     opl3_t *opl3;
    213 
    214     opl3 = snd_timer_chip(timer);
    215     spin_lock_irqsave(&opl3->timer_lock, flags);
    216     tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
    217     opl3->timer_enable = tmp;
    218     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);       /* disable timer #1 */
    219     spin_unlock_irqrestore(&opl3->timer_lock, flags);
    220     return 0;
    221 }
    222 
    223 /*
    224 
    225 */
    226 
    227 static struct _snd_timer_hardware snd_opl3_timer1 =
    228 {
    229     SNDRV_TIMER_HW_STOP,
    230     80000,
    231     256,
    232     0,0,0,
    233     snd_opl3_timer1_start,
    234     snd_opl3_timer1_stop,
     193static int snd_opl3_timer2_start(struct snd_timer * timer)
     194{
     195        unsigned long flags;
     196        unsigned char tmp;
     197        unsigned int ticks;
     198        struct snd_opl3 *opl3;
     199
     200        opl3 = snd_timer_chip(timer);
     201        spin_lock_irqsave(&opl3->timer_lock, flags);
     202        ticks = timer->sticks;
     203        tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
     204        opl3->timer_enable = tmp;
     205        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks);  /* timer 1 count */
     206        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* enable timer 1 IRQ */
     207        spin_unlock_irqrestore(&opl3->timer_lock, flags);
     208        return 0;
     209}
     210
     211static int snd_opl3_timer2_stop(struct snd_timer * timer)
     212{
     213        unsigned long flags;
     214        unsigned char tmp;
     215        struct snd_opl3 *opl3;
     216
     217        opl3 = snd_timer_chip(timer);
     218        spin_lock_irqsave(&opl3->timer_lock, flags);
     219        tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
     220        opl3->timer_enable = tmp;
     221        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* disable timer #1 */
     222        spin_unlock_irqrestore(&opl3->timer_lock, flags);
     223        return 0;
     224}
     225
     226/*
     227
     228 */
     229
     230static struct snd_timer_hardware snd_opl3_timer1 =
     231{
     232        .flags =        SNDRV_TIMER_HW_STOP,
     233        .resolution =   80000,
     234        .ticks =        256,
     235        .start =        snd_opl3_timer1_start,
     236        .stop =         snd_opl3_timer1_stop,
    235237};
    236238
    237 static struct _snd_timer_hardware snd_opl3_timer2 =
    238 {
    239     SNDRV_TIMER_HW_STOP,
    240     320000,
    241     256,
    242     0,0,0,
    243     snd_opl3_timer2_start,
    244     snd_opl3_timer2_stop,
     239static struct snd_timer_hardware snd_opl3_timer2 =
     240{
     241        .flags =        SNDRV_TIMER_HW_STOP,
     242        .resolution =   320000,
     243        .ticks =        256,
     244        .start =        snd_opl3_timer2_start,
     245        .stop =         snd_opl3_timer2_stop,
    245246};
    246247
    247 static int snd_opl3_timer1_init(opl3_t * opl3, int timer_no)
    248 {
    249     snd_timer_t *timer = NULL;
    250     snd_timer_id_t tid;
    251     int err;
    252 
    253     tid.dev_class = SNDRV_TIMER_CLASS_CARD;
    254     tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
    255     tid.card = opl3->card->number;
    256     tid.device = timer_no;
    257     tid.subdevice = 0;
    258     if ((err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer)) >= 0) {
    259         strcpy(timer->name, "AdLib timer #1");
    260         timer->private_data = opl3;
    261         timer->hw = snd_opl3_timer1;
    262     }
    263     opl3->timer1 = timer;
    264     return err;
    265 }
    266 
    267 static int snd_opl3_timer2_init(opl3_t * opl3, int timer_no)
    268 {
    269     snd_timer_t *timer = NULL;
    270     snd_timer_id_t tid;
    271     int err;
    272 
    273     tid.dev_class = SNDRV_TIMER_CLASS_CARD;
    274     tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
    275     tid.card = opl3->card->number;
    276     tid.device = timer_no;
    277     tid.subdevice = 0;
    278     if ((err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer)) >= 0) {
    279         strcpy(timer->name, "AdLib timer #2");
    280         timer->private_data = opl3;
    281         timer->hw = snd_opl3_timer2;
    282     }
    283     opl3->timer2 = timer;
    284     return err;
    285 }
    286 
    287 /*
    288 
    289 */
    290 
    291 void snd_opl3_interrupt(snd_hwdep_t * hw)
    292 {
    293     unsigned char status;
    294     opl3_t *opl3;
    295     snd_timer_t *timer;
    296 
    297     if (hw == NULL)
    298         return;
    299 
    300     opl3 = hw->private_data;
    301     status = inb(opl3->l_port);
     248static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
     249{
     250        struct snd_timer *timer = NULL;
     251        struct snd_timer_id tid;
     252        int err;
     253
     254        tid.dev_class = SNDRV_TIMER_CLASS_CARD;
     255        tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
     256        tid.card = opl3->card->number;
     257        tid.device = timer_no;
     258        tid.subdevice = 0;
     259        if ((err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer)) >= 0) {
     260                strcpy(timer->name, "AdLib timer #1");
     261                timer->private_data = opl3;
     262                timer->hw = snd_opl3_timer1;
     263        }
     264        opl3->timer1 = timer;
     265        return err;
     266}
     267
     268static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
     269{
     270        struct snd_timer *timer = NULL;
     271        struct snd_timer_id tid;
     272        int err;
     273
     274        tid.dev_class = SNDRV_TIMER_CLASS_CARD;
     275        tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
     276        tid.card = opl3->card->number;
     277        tid.device = timer_no;
     278        tid.subdevice = 0;
     279        if ((err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer)) >= 0) {
     280                strcpy(timer->name, "AdLib timer #2");
     281                timer->private_data = opl3;
     282                timer->hw = snd_opl3_timer2;
     283        }
     284        opl3->timer2 = timer;
     285        return err;
     286}
     287
     288/*
     289
     290 */
     291
     292void snd_opl3_interrupt(struct snd_hwdep * hw)
     293{
     294        unsigned char status;
     295        struct snd_opl3 *opl3;
     296        struct snd_timer *timer;
     297
     298        if (hw == NULL)
     299                return;
     300
     301        opl3 = hw->private_data;
     302        status = inb(opl3->l_port);
    302303#if 0
    303     snd_printk("AdLib IRQ status = 0x%x\n", status);
     304        snd_printk("AdLib IRQ status = 0x%x\n", status);
    304305#endif
    305     if (!(status & 0x80))
    306         return;
    307 
    308     if (status & 0x40) {
    309         timer = opl3->timer1;
    310         snd_timer_interrupt(timer, timer->sticks);
    311     }
    312     if (status & 0x20) {
    313         timer = opl3->timer2;
    314         snd_timer_interrupt(timer, timer->sticks);
    315     }
    316 }
    317 
    318 /*
    319 
    320 */
    321 
    322 static int snd_opl3_free(opl3_t *opl3)
    323 {
    324     snd_assert(opl3 != NULL, return -ENXIO);
    325     if (opl3->private_free)
    326         opl3->private_free(opl3);
    327     if (opl3->res_l_port) {
    328         release_resource(opl3->res_l_port);
    329         kfree_nocheck(opl3->res_l_port);
    330     }
    331     if (opl3->res_r_port) {
    332         release_resource(opl3->res_r_port);
    333         kfree_nocheck(opl3->res_r_port);
    334     }
    335     kfree(opl3);
    336     return 0;
    337 }
    338 
    339 static int snd_opl3_dev_free(snd_device_t *device)
    340 {
    341     opl3_t *opl3 = device->device_data;
    342     return snd_opl3_free(opl3);
    343 }
    344 
    345 int snd_opl3_new(snd_card_t *card,
    346                     unsigned short hardware,
    347                     opl3_t ** ropl3)
    348 {
    349 #ifdef TARGET_OS2
    350     static snd_device_ops_t ops = {
    351         snd_opl3_dev_free,0,0,0
    352     };
    353 #else
    354     static snd_device_ops_t ops = {
    355     dev_free: snd_opl3_dev_free,
    356     };
     306        if (!(status & 0x80))
     307                return;
     308
     309        if (status & 0x40) {
     310                timer = opl3->timer1;
     311                snd_timer_interrupt(timer, timer->sticks);
     312        }
     313        if (status & 0x20) {
     314                timer = opl3->timer2;
     315                snd_timer_interrupt(timer, timer->sticks);
     316        }
     317}
     318
     319/*
     320
     321 */
     322
     323static int snd_opl3_free(struct snd_opl3 *opl3)
     324{
     325        snd_assert(opl3 != NULL, return -ENXIO);
     326        if (opl3->private_free)
     327                opl3->private_free(opl3);
     328        release_and_free_resource(opl3->res_l_port);
     329        release_and_free_resource(opl3->res_r_port);
     330        kfree(opl3);
     331        return 0;
     332}
     333
     334static int snd_opl3_dev_free(struct snd_device *device)
     335{
     336        struct snd_opl3 *opl3 = device->device_data;
     337        return snd_opl3_free(opl3);
     338}
     339
     340int snd_opl3_new(struct snd_card *card,
     341                 unsigned short hardware,
     342                 struct snd_opl3 **ropl3)
     343{
     344        static struct snd_device_ops ops = {
     345                .dev_free = snd_opl3_dev_free,
     346        };
     347        struct snd_opl3 *opl3;
     348        int err;
     349
     350        *ropl3 = NULL;
     351        opl3 = (struct snd_opl3 *)kzalloc(sizeof(*opl3), GFP_KERNEL);
     352        if (opl3 == NULL) {
     353                snd_printk(KERN_ERR "opl3: cannot allocate\n");
     354                return -ENOMEM;
     355        }
     356
     357        opl3->card = card;
     358        opl3->hardware = hardware;
     359        spin_lock_init(&opl3->reg_lock);
     360        spin_lock_init(&opl3->timer_lock);
     361        init_MUTEX(&opl3->access_mutex);
     362
     363        if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
     364                snd_opl3_free(opl3);
     365                return err;
     366        }
     367
     368        *ropl3 = opl3;
     369        return 0;
     370}
     371
     372int snd_opl3_init(struct snd_opl3 *opl3)
     373{
     374        if (! opl3->command) {
     375                printk(KERN_ERR "snd_opl3_init: command not defined!\n");
     376                return -EINVAL;
     377        }
     378
     379        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
     380        /* Melodic mode */
     381        opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
     382
     383        switch (opl3->hardware & OPL3_HW_MASK) {
     384        case OPL3_HW_OPL2:
     385                opl3->max_voices = MAX_OPL2_VOICES;
     386                break;
     387        case OPL3_HW_OPL3:
     388        case OPL3_HW_OPL4:
     389                opl3->max_voices = MAX_OPL3_VOICES;
     390                /* Enter OPL3 mode */
     391                opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
     392        }
     393        return 0;
     394}
     395
     396int snd_opl3_create(struct snd_card *card,
     397                    unsigned long l_port,
     398                    unsigned long r_port,
     399                    unsigned short hardware,
     400                    int integrated,
     401                    struct snd_opl3 ** ropl3)
     402{
     403        struct snd_opl3 *opl3;
     404        int err;
     405
     406        *ropl3 = NULL;
     407        if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
     408                return err;
     409        if (! integrated) {
     410                if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
     411                        snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
     412                        snd_opl3_free(opl3);
     413                        return -EBUSY;
     414                }
     415                if (r_port != 0 &&
     416                    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
     417                        snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
     418                        snd_opl3_free(opl3);
     419                        return -EBUSY;
     420                }
     421        }
     422        opl3->l_port = l_port;
     423        opl3->r_port = r_port;
     424
     425        switch (opl3->hardware) {
     426        /* some hardware doesn't support timers */
     427        case OPL3_HW_OPL3_SV:
     428        case OPL3_HW_OPL3_CS:
     429        case OPL3_HW_OPL3_FM801:
     430                opl3->command = &snd_opl3_command;
     431                break;
     432        default:
     433                opl3->command = &snd_opl2_command;
     434                if ((err = snd_opl3_detect(opl3)) < 0) {
     435                        snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
     436                                   opl3->l_port, opl3->r_port);
     437                        snd_opl3_free(opl3);
     438                        return err;
     439                }
     440                /* detect routine returns correct hardware type */
     441                switch (opl3->hardware & OPL3_HW_MASK) {
     442                case OPL3_HW_OPL3:
     443                case OPL3_HW_OPL4:
     444                        opl3->command = &snd_opl3_command;
     445                }
     446        }
     447
     448        snd_opl3_init(opl3);
     449
     450        *ropl3 = opl3;
     451        return 0;
     452}
     453
     454int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
     455{
     456        int err;
     457
     458        if (timer1_dev >= 0)
     459                if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
     460                        return err;
     461        if (timer2_dev >= 0) {
     462                if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
     463                        snd_device_free(opl3->card, opl3->timer1);
     464                        opl3->timer1 = NULL;
     465                        return err;
     466                }
     467        }
     468        return 0;
     469}
     470
     471int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
     472                       int device, int seq_device,
     473                       struct snd_hwdep ** rhwdep)
     474{
     475        struct snd_hwdep *hw;
     476        struct snd_card *card = opl3->card;
     477        int err;
     478
     479        if (rhwdep)
     480                *rhwdep = NULL;
     481
     482        /* create hardware dependent device (direct FM) */
     483
     484        if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
     485                snd_device_free(card, opl3);
     486                return err;
     487        }
     488        hw->private_data = opl3;
     489#ifdef CONFIG_SND_OSSEMUL
     490        if (device == 0) {
     491                hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
     492                sprintf(hw->oss_dev, "dmfm%i", card->number);
     493        }
    357494#endif
    358     opl3_t *opl3;
    359     int err;
    360     *ropl3 = NULL;
    361     opl3 = kcalloc(1, sizeof(*opl3), GFP_KERNEL);
    362     if (opl3 == NULL)
    363         return -ENOMEM;
    364 
    365     opl3->card = card;
    366     opl3->hardware = hardware;
    367     spin_lock_init(&opl3->reg_lock);
    368     spin_lock_init(&opl3->timer_lock);
    369     init_MUTEX(&opl3->access_mutex);
    370 
    371     if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, opl3, &ops)) < 0) {
    372         snd_opl3_free(opl3);
    373         return err;
    374     }
    375 
    376     *ropl3 = opl3;
    377     return 0;
    378 }
    379 
    380 int snd_opl3_init(opl3_t *opl3)
    381 {
    382     if (! opl3->command) {
    383         printk(KERN_ERR "snd_opl3_init: command not defined!\n");
    384         return -EINVAL;
    385     }
    386 
    387     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
    388     /* Melodic mode */
    389     opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
    390 
    391     switch (opl3->hardware & OPL3_HW_MASK) {
    392     case OPL3_HW_OPL2:
    393         opl3->max_voices = MAX_OPL2_VOICES;
    394         break;
    395     case OPL3_HW_OPL3:
    396     case OPL3_HW_OPL4:
    397         opl3->max_voices = MAX_OPL3_VOICES;
    398         /* Enter OPL3 mode */
    399         opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
    400     }
    401     return 0;
    402 }
    403 
    404 int snd_opl3_create(snd_card_t * card,
    405                     unsigned long l_port,
    406                     unsigned long r_port,
    407                     unsigned short hardware,
    408                     int integrated,
    409                     opl3_t ** ropl3)
    410 {
    411     opl3_t *opl3;
    412     int err;
    413 
    414     *ropl3 = NULL;
    415     if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
    416         return err;
    417     if (! integrated) {
    418         if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
    419             snd_opl3_free(opl3);
    420             return -EBUSY;
    421         }
    422         if (r_port != 0 &&
    423             (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
    424             snd_opl3_free(opl3);
    425             return -EBUSY;
    426         }
    427     }
    428     opl3->l_port = l_port;
    429     opl3->r_port = r_port;
    430 
    431     switch (opl3->hardware) {
    432         /* some hardware doesn't support timers */
    433     case OPL3_HW_OPL3_SV:
    434     case OPL3_HW_OPL3_CS:
    435     case OPL3_HW_OPL3_FM801:
    436         opl3->command = &snd_opl3_command;
    437         break;
    438     case OPL3_HW_OPL3_PC98:
    439         opl3->command = &snd_opl3_command;
    440 
    441         /* Initialize? */
    442         opl3->command(opl3, OPL3_RIGHT | 0x05, 0x05);
    443         opl3->command(opl3, OPL3_RIGHT | 0x08, 0x04);
    444         opl3->command(opl3, OPL3_RIGHT | 0x08, 0x00);
    445         opl3->command(opl3, OPL3_LEFT | 0xf7, 0x00);
    446         opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
    447         opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
    448         inb(opl3->l_port);
    449 
    450         opl3->command(opl3, OPL3_LEFT | 0x02, 0xff);
    451         opl3->command(opl3, OPL3_LEFT | 0x04, 0x21);
    452         inb(opl3->l_port);
    453 
    454         opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
    455         opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
    456 
    457         break;
    458     default:
    459         opl3->command = &snd_opl2_command;
    460         if ((err = snd_opl3_detect(opl3)) < 0) {
    461             snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
    462                        opl3->l_port, opl3->r_port);
    463             snd_opl3_free(opl3);
    464             return err;
    465         }
    466         /* detect routine returns correct hardware type */
    467         switch (opl3->hardware & OPL3_HW_MASK) {
    468         case OPL3_HW_OPL3:
    469         case OPL3_HW_OPL4:
    470             opl3->command = &snd_opl3_command;
    471         }
    472     }
    473 
    474     snd_opl3_init(opl3);
    475 
    476     *ropl3 = opl3;
    477     return 0;
    478 }
    479 
    480 int snd_opl3_timer_new(opl3_t * opl3, int timer1_dev, int timer2_dev)
    481 {
    482     int err;
    483 
    484     if (timer1_dev >= 0)
    485         if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
    486             return err;
    487     if (timer2_dev >= 0) {
    488         if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
    489             snd_device_free(opl3->card, opl3->timer1);
    490             opl3->timer1 = NULL;
    491             return err;
    492         }
    493     }
    494     return 0;
    495 }
    496 
    497 int snd_opl3_hwdep_new(opl3_t * opl3,
    498                        int device, int seq_device,
    499                        snd_hwdep_t ** rhwdep)
    500 {
    501     snd_hwdep_t *hw;
    502     snd_card_t *card = opl3->card;
    503     int err;
    504 
    505     if (rhwdep)
    506         *rhwdep = NULL;
    507 
    508     /* create hardware dependent device (direct FM) */
    509 
    510     if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
    511         snd_device_free(card, opl3);
    512         return err;
    513     }
    514     hw->private_data = opl3;
    515 #ifdef CONFIG_SND_OSSEMUL
    516     if (device == 0) {
    517         hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
    518         sprintf(hw->oss_dev, "dmfm%i", card->number);
    519     }
     495        strcpy(hw->name, hw->id);
     496        switch (opl3->hardware & OPL3_HW_MASK) {
     497        case OPL3_HW_OPL2:
     498                strcpy(hw->name, "OPL2 FM");
     499                hw->iface = SNDRV_HWDEP_IFACE_OPL2;
     500                break;
     501        case OPL3_HW_OPL3:
     502                strcpy(hw->name, "OPL3 FM");
     503                hw->iface = SNDRV_HWDEP_IFACE_OPL3;
     504                break;
     505        case OPL3_HW_OPL4:
     506                strcpy(hw->name, "OPL4 FM");
     507                hw->iface = SNDRV_HWDEP_IFACE_OPL4;
     508                break;
     509        }
     510
     511        /* operators - only ioctl */
     512        hw->ops.open = snd_opl3_open;
     513        hw->ops.ioctl = snd_opl3_ioctl;
     514        hw->ops.release = snd_opl3_release;
     515
     516        opl3->seq_dev_num = seq_device;
     517#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
     518        if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
     519                               sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
     520                strcpy(opl3->seq_dev->name, hw->name);
     521                *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
     522        }
    520523#endif
    521     strcpy(hw->name, hw->id);
    522     switch (opl3->hardware & OPL3_HW_MASK) {
    523     case OPL3_HW_OPL2:
    524         strcpy(hw->name, "OPL2 FM");
    525         hw->iface = SNDRV_HWDEP_IFACE_OPL2;
    526         break;
    527     case OPL3_HW_OPL3:
    528         strcpy(hw->name, "OPL3 FM");
    529         hw->iface = SNDRV_HWDEP_IFACE_OPL3;
    530         break;
    531     case OPL3_HW_OPL4:
    532         strcpy(hw->name, "OPL4 FM");
    533         hw->iface = SNDRV_HWDEP_IFACE_OPL4;
    534         break;
    535     }
    536 
    537     /* operators - only ioctl */
    538     hw->ops.open = snd_opl3_open;
    539     hw->ops.ioctl = snd_opl3_ioctl;
    540     hw->ops.release = snd_opl3_release;
    541 
    542     opl3->seq_dev_num = seq_device;
    543 #ifdef CONFIG_SND_SEQUENCER
    544     if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
    545                            sizeof(opl3_t*), &opl3->seq_dev) >= 0) {
    546         strcpy(opl3->seq_dev->name, hw->name);
    547         *(opl3_t**)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
    548     }
    549 #endif
    550     if (rhwdep)
    551         *rhwdep = hw;
    552     return 0;
     524        if (rhwdep)
     525                *rhwdep = hw;
     526        return 0;
    553527}
    554528
     
    570544static int __init alsa_opl3_init(void)
    571545{
    572     return 0;
     546        return 0;
    573547}
    574548
  • GPL/trunk/alsa-kernel/drivers/opl3/opl3_midi.c

    r33 r34  
    2424
    2525#include "opl3_voice.h"
     26#include <sound/asoundef.h>
    2627
    2728extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
     
    4142static char opl3_volume_table[128] =
    4243{
    43     -63, -48, -40, -35, -32, -29, -27, -26,
    44     -24, -23, -21, -20, -19, -18, -18, -17,
    45     -16, -15, -15, -14, -13, -13, -12, -12,
    46     -11, -11, -10, -10, -10, -9, -9, -8,
    47     -8, -8, -7, -7, -7, -6, -6, -6,
    48     -5, -5, -5, -5, -4, -4, -4, -4,
    49     -3, -3, -3, -3, -2, -2, -2, -2,
    50     -2, -1, -1, -1, -1, 0, 0, 0,
    51     0, 0, 0, 1, 1, 1, 1, 1,
    52     1, 2, 2, 2, 2, 2, 2, 2,
    53     3, 3, 3, 3, 3, 3, 3, 4,
    54     4, 4, 4, 4, 4, 4, 4, 5,
    55     5, 5, 5, 5, 5, 5, 5, 5,
    56     6, 6, 6, 6, 6, 6, 6, 6,
    57     6, 7, 7, 7, 7, 7, 7, 7,
    58     7, 7, 7, 8, 8, 8, 8, 8
     44        -63, -48, -40, -35, -32, -29, -27, -26,
     45        -24, -23, -21, -20, -19, -18, -18, -17,
     46        -16, -15, -15, -14, -13, -13, -12, -12,
     47        -11, -11, -10, -10, -10, -9, -9, -8,
     48        -8, -8, -7, -7, -7, -6, -6, -6,
     49        -5, -5, -5, -5, -4, -4, -4, -4,
     50        -3, -3, -3, -3, -2, -2, -2, -2,
     51        -2, -1, -1, -1, -1, 0, 0, 0,
     52        0, 0, 0, 1, 1, 1, 1, 1,
     53        1, 2, 2, 2, 2, 2, 2, 2,
     54        3, 3, 3, 3, 3, 3, 3, 4,
     55        4, 4, 4, 4, 4, 4, 4, 5,
     56        5, 5, 5, 5, 5, 5, 5, 5,
     57        6, 6, 6, 6, 6, 6, 6, 6,
     58        6, 7, 7, 7, 7, 7, 7, 7,
     59        7, 7, 7, 8, 8, 8, 8, 8
    5960};
    6061
    6162void snd_opl3_calc_volume(unsigned char *volbyte, int vel,
    62                           snd_midi_channel_t *chan)
    63 {
    64     int oldvol, newvol, n;
    65     int volume;
    66 
    67     volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127);
    68     if (volume > 127)
    69         volume = 127;
    70 
    71     oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK);
    72 
    73     newvol = opl3_volume_table[volume] + oldvol;
    74     if (newvol > OPL3_TOTAL_LEVEL_MASK)
    75         newvol = OPL3_TOTAL_LEVEL_MASK;
    76     else if (newvol < 0)
    77         newvol = 0;
    78 
    79     n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK);
    80 
    81     *volbyte = (*volbyte & OPL3_KSL_MASK) | (n & OPL3_TOTAL_LEVEL_MASK);
     63                          struct snd_midi_channel *chan)
     64{
     65        int oldvol, newvol, n;
     66        int volume;
     67
     68        volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127);
     69        if (volume > 127)
     70                volume = 127;
     71
     72        oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK);
     73
     74        newvol = opl3_volume_table[volume] + oldvol;
     75        if (newvol > OPL3_TOTAL_LEVEL_MASK)
     76                newvol = OPL3_TOTAL_LEVEL_MASK;
     77        else if (newvol < 0)
     78                newvol = 0;
     79
     80        n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK);
     81
     82        *volbyte = (*volbyte & OPL3_KSL_MASK) | (n & OPL3_TOTAL_LEVEL_MASK);
    8283}
    8384
     
    8788static short opl3_note_table[16] =
    8889{
    89     305, 323,   /* for pitch bending, -2 semitones */
    90     343, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647,
    91     686, 726    /* for pitch bending, +2 semitones */
     90        305, 323,       /* for pitch bending, -2 semitones */
     91        343, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647,
     92        686, 726        /* for pitch bending, +2 semitones */
    9293};
    9394
    9495static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum,
    95                                 int note, snd_midi_channel_t *chan)
    96 {
    97     int block = ((note / 12) & 0x07) - 1;
    98     int idx = (note % 12) + 2;
    99     int freq;
    100 
    101     if (chan->midi_pitchbend) {
    102         int pitchbend = chan->midi_pitchbend;
    103         int segment;
    104 
    105         if (pitchbend > 0x1FFF)
    106             pitchbend = 0x1FFF;
    107 
    108         segment = pitchbend / 0x1000;
    109         freq = opl3_note_table[idx+segment];
    110         freq += ((opl3_note_table[idx+segment+1] - freq) *
    111                 (pitchbend % 0x1000)) / 0x1000;
    112     } else {
    113         freq = opl3_note_table[idx];
    114     }
    115 
    116     *fnum = (unsigned char) freq;
    117     *blocknum = ((freq >> 8) & OPL3_FNUM_HIGH_MASK) |
    118         ((block << 2) & OPL3_BLOCKNUM_MASK);
     96                                int note, struct snd_midi_channel *chan)
     97{
     98        int block = ((note / 12) & 0x07) - 1;
     99        int idx = (note % 12) + 2;
     100        int freq;
     101
     102        if (chan->midi_pitchbend) {
     103                int pitchbend = chan->midi_pitchbend;
     104                int segment;
     105
     106                if (pitchbend > 0x1FFF)
     107                        pitchbend = 0x1FFF;
     108
     109                segment = pitchbend / 0x1000;
     110                freq = opl3_note_table[idx+segment];
     111                freq += ((opl3_note_table[idx+segment+1] - freq) *
     112                        (pitchbend % 0x1000)) / 0x1000;
     113        } else {
     114                freq = opl3_note_table[idx];
     115        }
     116
     117        *fnum = (unsigned char) freq;
     118        *blocknum = ((freq >> 8) & OPL3_FNUM_HIGH_MASK) |
     119                ((block << 2) & OPL3_BLOCKNUM_MASK);
    119120}
    120121
    121122
    122123#ifdef DEBUG_ALLOC
    123 static void debug_alloc(opl3_t *opl3, char *s, int voice) {
    124     int i;
    125     char *str = "x.24";
    126 
    127     printk("time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
    128     for (i = 0; i < opl3->max_voices; i++)
    129         printk("%c", *(str + opl3->voices[i].state + 1));
    130     printk("\n");
     124static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
     125        int i;
     126        char *str = "x.24";
     127
     128        printk("time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
     129        for (i = 0; i < opl3->max_voices; i++)
     130                printk("%c", *(str + opl3->voices[i].state + 1));
     131        printk("\n");
    131132}
    132133#endif
     
    135136 * Get a FM voice (channel) to play a note on.
    136137 */
    137 static int opl3_get_voice(opl3_t *opl3, int instr_4op,
    138                           snd_midi_channel_t *chan) {
    139     int chan_4op_1;             /* first voice for 4op instrument */
    140     int chan_4op_2;             /* second voice for 4op instrument */
    141 
    142     snd_opl3_voice_t *vp, *vp2;
    143     unsigned int voice_time;
    144     int i;
     138static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
     139                          struct snd_midi_channel *chan) {
     140        int chan_4op_1;         /* first voice for 4op instrument */
     141        int chan_4op_2;         /* second voice for 4op instrument */
     142
     143        struct snd_opl3_voice *vp, *vp2;
     144        unsigned int voice_time;
     145        int i;
    145146
    146147#ifdef DEBUG_ALLOC
    147     char *alloc_type[3] = { "FREE     ", "CHEAP    ", "EXPENSIVE" };
    148 #endif
    149 
    150     /* This is our "allocation cost" table */
    151     enum {
    152         FREE = 0, CHEAP, EXPENSIVE, END
    153     };
    154 
    155     /* Keeps track of what we are finding */
    156     struct best {
    157         unsigned int time;
    158         int voice;
    159     } best[END];
    160     struct best *bp;
    161 
    162     for (i = 0; i < END; i++) {
    163         best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
    164         best[i].voice = -1;
    165     }
    166 
    167     /* Look through all the channels for the most suitable. */
    168     for (i = 0; i < opl3->max_voices; i++) {
    169         vp = &opl3->voices[i];
    170 
    171         if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL)
    172             /* skip unavailable channels, allocated by
    173              drum voices or by bounded 4op voices) */
    174             continue;
    175 
    176         voice_time = vp->time;
    177         bp = best;
    178 
    179         chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
    180         chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
    181         if (instr_4op) {
    182             /* allocate 4op voice */
    183             /* skip channels unavailable to 4op instrument */
    184             if (!chan_4op_1)
    185                 continue;
    186 
    187             if (vp->state)
    188                 /* kill one voice, CHEAP */
    189                 bp++;
    190             /* get state of bounded 2op channel
    191              to be allocated for 4op instrument */
    192             vp2 = &opl3->voices[i + 3];
    193             if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
    194                 /* kill two voices, EXPENSIVE */
    195                 bp++;
    196                 voice_time = (voice_time > vp->time) ?
    197                     voice_time : vp->time;
    198             }
    199         } else {
    200             /* allocate 2op voice */
    201             if ((chan_4op_1) || (chan_4op_2))
    202                 /* use bounded channels for 2op, CHEAP */
    203                 bp++;
    204             else if (vp->state)
    205                 /* kill one voice on 2op channel, CHEAP */
    206                 bp++;
    207             /* raise kill cost to EXPENSIVE for all channels */
    208             if (vp->state)
    209                 bp++;
    210         }
    211         if (voice_time < bp->time) {
    212             bp->time = voice_time;
    213             bp->voice = i;
    214         }
    215     }
    216 
    217     for (i = 0; i < END; i++) {
    218         if (best[i].voice >= 0) {
     148        char *alloc_type[3] = { "FREE     ", "CHEAP    ", "EXPENSIVE" };
     149#endif
     150
     151        /* This is our "allocation cost" table */
     152        enum {
     153                FREE = 0, CHEAP, EXPENSIVE, END
     154        };
     155
     156        /* Keeps track of what we are finding */
     157        struct best {
     158                unsigned int time;
     159                int voice;
     160        } best[END];
     161        struct best *bp;
     162
     163        for (i = 0; i < END; i++) {
     164                best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
     165                best[i].voice = -1;
     166        }
     167
     168        /* Look through all the channels for the most suitable. */
     169        for (i = 0; i < opl3->max_voices; i++) {
     170                vp = &opl3->voices[i];
     171
     172                if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL)
     173                  /* skip unavailable channels, allocated by
     174                     drum voices or by bounded 4op voices) */
     175                        continue;
     176
     177                voice_time = vp->time;
     178                bp = best;
     179
     180                chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
     181                chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
     182                if (instr_4op) {
     183                        /* allocate 4op voice */
     184                        /* skip channels unavailable to 4op instrument */
     185                        if (!chan_4op_1)
     186                                continue;
     187
     188                        if (vp->state)
     189                                /* kill one voice, CHEAP */
     190                                bp++;
     191                        /* get state of bounded 2op channel
     192                           to be allocated for 4op instrument */
     193                        vp2 = &opl3->voices[i + 3];
     194                        if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
     195                                /* kill two voices, EXPENSIVE */
     196                                bp++;
     197                                voice_time = (voice_time > vp->time) ?
     198                                        voice_time : vp->time;
     199                        }
     200                } else {
     201                        /* allocate 2op voice */
     202                        if ((chan_4op_1) || (chan_4op_2))
     203                                /* use bounded channels for 2op, CHEAP */
     204                                bp++;
     205                        else if (vp->state)
     206                                /* kill one voice on 2op channel, CHEAP */
     207                                bp++;
     208                        /* raise kill cost to EXPENSIVE for all channels */
     209                        if (vp->state)
     210                                bp++;
     211                }
     212                if (voice_time < bp->time) {
     213                        bp->time = voice_time;
     214                        bp->voice = i;
     215                }
     216        }
     217
     218        for (i = 0; i < END; i++) {
     219                if (best[i].voice >= 0) {
    219220#ifdef DEBUG_ALLOC
    220             printk("%s %iop allocation on voice %i\n",
    221                    alloc_type[i], instr_4op ? 4 : 2,
    222                    best[i].voice);
    223 #endif
    224             return best[i].voice;
    225         }
    226     }
    227     /* not found */
    228     return -1;
     221                        printk("%s %iop allocation on voice %i\n",
     222                               alloc_type[i], instr_4op ? 4 : 2,
     223                               best[i].voice);
     224#endif
     225                        return best[i].voice;
     226                }
     227        }
     228        /* not found */
     229        return -1;
    229230}
    230231
     
    237238{
    238239
    239     opl3_t *opl3 = (opl3_t *)data;
    240     int again = 0;
    241     int i;
    242 
    243     spin_lock(&opl3->sys_timer_lock);
    244     for (i = 0; i < opl3->max_voices; i++) {
    245         snd_opl3_voice_t *vp = &opl3->voices[i];
    246         if (vp->state > 0 && vp->note_off_check) {
    247             if (vp->note_off == jiffies)
    248                 snd_opl3_note_off(opl3, vp->note, 0, vp->chan);
    249             else
    250                 again++;
    251         }
    252     }
    253     if (again) {
    254         opl3->tlist.expires = jiffies + 1;      /* invoke again */
    255         add_timer(&opl3->tlist);
    256     } else {
    257         opl3->sys_timer_status = 0;
    258     }
    259     spin_unlock(&opl3->sys_timer_lock);
     240        struct snd_opl3 *opl3 = (struct snd_opl3 *)data;
     241        int again = 0;
     242        int i;
     243
     244        spin_lock(&opl3->sys_timer_lock);
     245        for (i = 0; i < opl3->max_voices; i++) {
     246                struct snd_opl3_voice *vp = &opl3->voices[i];
     247                if (vp->state > 0 && vp->note_off_check) {
     248                        if (vp->note_off == jiffies)
     249                                snd_opl3_note_off(opl3, vp->note, 0, vp->chan);
     250                        else
     251                                again++;
     252                }
     253        }
     254        if (again) {
     255                opl3->tlist.expires = jiffies + 1;      /* invoke again */
     256                add_timer(&opl3->tlist);
     257        } else {
     258                opl3->sys_timer_status = 0;
     259        }
     260        spin_unlock(&opl3->sys_timer_lock);
    260261}
    261262
     
    263264 * Start system timer
    264265 */
    265 void snd_opl3_start_timer(opl3_t *opl3)
    266 {
    267     unsigned long flags;
    268     spin_lock_irqsave(&opl3->sys_timer_lock, flags);
    269     if (! opl3->sys_timer_status) {
    270         opl3->tlist.expires = jiffies + 1;
    271         add_timer(&opl3->tlist);
    272         opl3->sys_timer_status = 1;
    273     }
    274     spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
     266static void snd_opl3_start_timer(struct snd_opl3 *opl3)
     267{
     268        unsigned long flags;
     269        spin_lock_irqsave(&opl3->sys_timer_lock, flags);
     270        if (! opl3->sys_timer_status) {
     271                opl3->tlist.expires = jiffies + 1;
     272                add_timer(&opl3->tlist);
     273                opl3->sys_timer_status = 1;
     274        }
     275        spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
    275276}
    276277
     
    279280
    280281static int snd_opl3_oss_map[MAX_OPL3_VOICES] = {
    281     0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14
     282        0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14
    282283};
    283284
     
    285286 * Start a note.
    286287 */
    287 void snd_opl3_note_on(void *p, int note, int vel, snd_midi_channel_t *chan)
    288 {
    289     opl3_t *opl3;
    290     snd_seq_instr_t wanted;
    291     snd_seq_kinstr_t *kinstr;
    292     int instr_4op;
    293 
    294     int voice;
    295     snd_opl3_voice_t *vp, *vp2;
    296     unsigned short connect_mask;
    297     unsigned char connection;
    298     unsigned char vol_op[4];
    299 
    300     int extra_prg = 0;
    301 
    302     unsigned short reg_side;
    303     unsigned char op_offset;
    304     unsigned char voice_offset;
    305     unsigned short opl3_reg;
    306     unsigned char reg_val;
    307 
    308     int key = note;
    309     unsigned char fnum, blocknum;
    310     int i;
    311 
    312     fm_instrument_t *fm;
    313     unsigned long flags;
    314 
    315     opl3 = p;
    316 
    317 #ifdef DEBUG_MIDI
    318     snd_printk("Note on, ch %i, inst %i, note %i, vel %i\n",
    319                chan->number, chan->midi_program, note, vel);
    320 #endif
    321     wanted.cluster = 0;
    322     wanted.std = SNDRV_SEQ_INSTR_TYPE2_OPL2_3;
    323 
    324     /* in SYNTH mode, application takes care of voices */
    325     /* in SEQ mode, drum voice numbers are notes on drum channel */
    326     if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
    327         if (chan->drum_channel) {
    328             /* percussion instruments are located in bank 128 */
    329             wanted.bank = 128;
    330             wanted.prg = note;
    331         } else {
    332             wanted.bank = chan->gm_bank_select;
    333             wanted.prg = chan->midi_program;
    334         }
    335     } else {
    336         /* Prepare for OSS mode */
    337         if (chan->number >= MAX_OPL3_VOICES)
    338             return;
    339 
    340         /* OSS instruments are located in bank 127 */
    341         wanted.bank = 127;
    342         wanted.prg = chan->midi_program;
    343     }
    344 
    345     spin_lock_irqsave(&opl3->voice_lock, flags);
    346 
    347     if (use_internal_drums) {
    348         snd_opl3_drum_switch(opl3, note, vel, 1, chan);
    349         spin_unlock_irqrestore(&opl3->voice_lock, flags);
    350         return;
    351     }
    352 
    353     __extra_prg:
    354     kinstr = snd_seq_instr_find(opl3->ilist, &wanted, 1, 0);
    355     if (kinstr == NULL) {
    356         spin_unlock_irqrestore(&opl3->voice_lock, flags);
    357         return;
    358     }
    359 
    360     fm = KINSTR_DATA(kinstr);
    361 
    362     switch (fm->type) {
    363     case FM_PATCH_OPL2:
    364         instr_4op = 0;
    365         break;
    366     case FM_PATCH_OPL3:
    367         if (opl3->hardware >= OPL3_HW_OPL3) {
    368             instr_4op = 1;
    369             break;
    370         }
    371     default:
    372         snd_seq_instr_free_use(opl3->ilist, kinstr);
    373         spin_unlock_irqrestore(&opl3->voice_lock, flags);
    374         return;
    375     }
    376 
    377 #ifdef DEBUG_MIDI
    378     snd_printk("  --> OPL%i instrument: %s\n",
    379                instr_4op ? 3 : 2, kinstr->name);
    380 #endif
    381     /* in SYNTH mode, application takes care of voices */
    382     /* in SEQ mode, allocate voice on free OPL3 channel */
    383     if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
    384         voice = opl3_get_voice(opl3, instr_4op, chan);
    385     } else {
    386         /* remap OSS voice */
    387         voice = snd_opl3_oss_map[chan->number];
    388     }
    389 
    390     if (voice < MAX_OPL2_VOICES) {
    391         /* Left register block for voices 0 .. 8 */
    392         reg_side = OPL3_LEFT;
    393         voice_offset = voice;
    394         connect_mask = (OPL3_LEFT_4OP_0 << voice_offset) & 0x07;
    395     } else {
    396         /* Right register block for voices 9 .. 17 */
    397         reg_side = OPL3_RIGHT;
    398         voice_offset = voice - MAX_OPL2_VOICES;
    399         connect_mask = (OPL3_RIGHT_4OP_0 << voice_offset) & 0x38;
    400     }
    401 
    402     /* kill voice on channel */
    403     vp = &opl3->voices[voice];
    404     if (vp->state > 0) {
    405         opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
    406         reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
    407         opl3->command(opl3, opl3_reg, reg_val);
    408     }
    409     if (instr_4op) {
    410         vp2 = &opl3->voices[voice + 3];
    411         if (vp->state > 0) {
    412             opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK +
    413                                    voice_offset + 3);
    414             reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
    415             opl3->command(opl3, opl3_reg, reg_val);
    416         }
    417     }
    418 
    419     /* set connection register */
    420     if (instr_4op) {
    421         if ((opl3->connection_reg ^ connect_mask) & connect_mask) {
    422             opl3->connection_reg |= connect_mask;
    423             /* set connection bit */
    424             opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
    425             opl3->command(opl3, opl3_reg, opl3->connection_reg);
    426         }
    427     } else {
    428         if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) {
    429             opl3->connection_reg &= ~connect_mask;
    430             /* clear connection bit */
    431             opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
    432             opl3->command(opl3, opl3_reg, opl3->connection_reg);
    433         }
    434     }
    435 
    436 #ifdef DEBUG_MIDI
    437     snd_printk("  --> setting OPL3 connection: 0x%x\n",
    438                opl3->connection_reg);
    439 #endif
    440     /*
    441     * calculate volume depending on connection
    442     * between FM operators (see include/opl3.h)
    443     */
    444     for (i = 0; i < (instr_4op ? 4 : 2); i++)
    445         vol_op[i] = fm->op[i].ksl_level;
    446 
    447     connection = fm->feedback_connection[0] & 0x01;
    448     if (instr_4op) {
    449         connection <<= 1;
    450         connection |= fm->feedback_connection[1] & 0x01;
    451 
    452         snd_opl3_calc_volume(&vol_op[3], vel, chan);
    453         switch (connection) {
    454         case 0x03:
    455             snd_opl3_calc_volume(&vol_op[2], vel, chan);
    456             /* fallthru */
    457         case 0x02:
    458             snd_opl3_calc_volume(&vol_op[0], vel, chan);
    459             break;
    460         case 0x01:
    461             snd_opl3_calc_volume(&vol_op[1], vel, chan);
    462         }
    463     } else {
    464         snd_opl3_calc_volume(&vol_op[1], vel, chan);
    465         if (connection)
    466             snd_opl3_calc_volume(&vol_op[0], vel, chan);
    467     }
    468 
    469     /* Program the FM voice characteristics */
    470     for (i = 0; i < (instr_4op ? 4 : 2); i++) {
    471 #ifdef DEBUG_MIDI
    472         snd_printk("  --> programming operator %i\n", i);
    473 #endif
    474         op_offset = snd_opl3_regmap[voice_offset][i];
    475 
    476         /* Set OPL3 AM_VIB register of requested voice/operator */
    477         reg_val = fm->op[i].am_vib;
    478         opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
    479         opl3->command(opl3, opl3_reg, reg_val);
    480 
    481         /* Set OPL3 KSL_LEVEL register of requested voice/operator */
    482         reg_val = vol_op[i];
    483         opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
    484         opl3->command(opl3, opl3_reg, reg_val);
    485 
    486         /* Set OPL3 ATTACK_DECAY register of requested voice/operator */
    487         reg_val = fm->op[i].attack_decay;
    488         opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
    489         opl3->command(opl3, opl3_reg, reg_val);
    490 
    491         /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */
    492         reg_val = fm->op[i].sustain_release;
    493         opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
    494         opl3->command(opl3, opl3_reg, reg_val);
    495 
    496         /* Select waveform */
    497         reg_val = fm->op[i].wave_select;
    498         opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
    499         opl3->command(opl3, opl3_reg, reg_val);
    500     }
    501 
    502     /* Set operator feedback and 2op inter-operator connection */
    503     reg_val = fm->feedback_connection[0];
    504     /* Set output voice connection */
    505     reg_val |= OPL3_STEREO_BITS;
    506     if (chan->gm_pan < 43)
    507         reg_val &= ~OPL3_VOICE_TO_RIGHT;
    508     if (chan->gm_pan > 85)
    509         reg_val &= ~OPL3_VOICE_TO_LEFT;
    510     opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
    511     opl3->command(opl3, opl3_reg, reg_val);
    512 
    513     if (instr_4op) {
    514         /* Set 4op inter-operator connection */
    515         reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT;
    516         /* Set output voice connection */
    517         reg_val |= OPL3_STEREO_BITS;
    518         if (chan->gm_pan < 43)
    519             reg_val &= ~OPL3_VOICE_TO_RIGHT;
    520         if (chan->gm_pan > 85)
    521             reg_val &= ~OPL3_VOICE_TO_LEFT;
    522         opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION +
    523                                voice_offset + 3);
    524         opl3->command(opl3, opl3_reg, reg_val);
    525     }
    526 
    527     /*
    528     * Special treatment of percussion notes for fm:
    529     * Requested pitch is really program, and pitch for
    530     * device is whatever was specified in the patch library.
    531     */
    532     if (fm->fix_key)
    533         note = fm->fix_key;
    534     /*
    535     * use transpose if defined in patch library
    536     */
    537     if (fm->trnsps)
    538         note += (fm->trnsps - 64);
    539 
    540     snd_opl3_calc_pitch(&fnum, &blocknum, note, chan);
    541 
    542     /* Set OPL3 FNUM_LOW register of requested voice */
    543     opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
    544     opl3->command(opl3, opl3_reg, fnum);
    545 
    546     opl3->voices[voice].keyon_reg = blocknum;
    547 
    548     /* Set output sound flag */
    549     blocknum |= OPL3_KEYON_BIT;
    550 
    551 #ifdef DEBUG_MIDI
    552     snd_printk("  --> trigger voice %i\n", voice);
    553 #endif
    554     /* Set OPL3 KEYON_BLOCK register of requested voice */
    555     opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
    556     opl3->command(opl3, opl3_reg, blocknum);
    557 
    558     /* kill note after fixed duration (in centiseconds) */
    559     if (fm->fix_dur) {
    560         opl3->voices[voice].note_off = jiffies +
    561             (fm->fix_dur * HZ) / 100;
    562         snd_opl3_start_timer(opl3);
    563         opl3->voices[voice].note_off_check = 1;
    564     } else
    565         opl3->voices[voice].note_off_check = 0;
    566 
    567     /* get extra pgm, but avoid possible loops */
    568     extra_prg = (extra_prg) ? 0 : fm->modes;
    569 
    570     snd_seq_instr_free_use(opl3->ilist, kinstr);
    571 
    572     /* do the bookkeeping */
    573     vp->time = opl3->use_time++;
    574     vp->note = key;
    575     vp->chan = chan;
    576 
    577     if (instr_4op) {
    578         vp->state = SNDRV_OPL3_ST_ON_4OP;
    579 
    580         vp2 = &opl3->voices[voice + 3];
    581         vp2->time = opl3->use_time++;
    582         vp2->note = key;
    583         vp2->chan = chan;
    584         vp2->state = SNDRV_OPL3_ST_NOT_AVAIL;
    585     } else {
    586         if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
    587             /* 4op killed by 2op, release bounded voice */
    588             vp2 = &opl3->voices[voice + 3];
    589             vp2->time = opl3->use_time++;
    590             vp2->state = SNDRV_OPL3_ST_OFF;
    591         }
    592         vp->state = SNDRV_OPL3_ST_ON_2OP;
    593     }
     288void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
     289{
     290        struct snd_opl3 *opl3;
     291        struct snd_seq_instr wanted;
     292        struct snd_seq_kinstr *kinstr;
     293        int instr_4op;
     294
     295        int voice;
     296        struct snd_opl3_voice *vp, *vp2;
     297        unsigned short connect_mask;
     298        unsigned char connection;
     299        unsigned char vol_op[4];
     300
     301        int extra_prg = 0;
     302
     303        unsigned short reg_side;
     304        unsigned char op_offset;
     305        unsigned char voice_offset;
     306        unsigned short opl3_reg;
     307        unsigned char reg_val;
     308
     309        int key = note;
     310        unsigned char fnum, blocknum;
     311        int i;
     312
     313        struct fm_instrument *fm;
     314        unsigned long flags;
     315
     316        opl3 = p;
     317
     318#ifdef DEBUG_MIDI
     319        snd_printk("Note on, ch %i, inst %i, note %i, vel %i\n",
     320                   chan->number, chan->midi_program, note, vel);
     321#endif
     322        wanted.cluster = 0;
     323        wanted.std = SNDRV_SEQ_INSTR_TYPE2_OPL2_3;
     324
     325        /* in SYNTH mode, application takes care of voices */
     326        /* in SEQ mode, drum voice numbers are notes on drum channel */
     327        if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
     328                if (chan->drum_channel) {
     329                        /* percussion instruments are located in bank 128 */
     330                        wanted.bank = 128;
     331                        wanted.prg = note;
     332                } else {
     333                        wanted.bank = chan->gm_bank_select;
     334                        wanted.prg = chan->midi_program;
     335                }
     336        } else {
     337                /* Prepare for OSS mode */
     338                if (chan->number >= MAX_OPL3_VOICES)
     339                        return;
     340
     341                /* OSS instruments are located in bank 127 */
     342                wanted.bank = 127;
     343                wanted.prg = chan->midi_program;
     344        }
     345
     346        spin_lock_irqsave(&opl3->voice_lock, flags);
     347
     348        if (use_internal_drums) {
     349                snd_opl3_drum_switch(opl3, note, vel, 1, chan);
     350                spin_unlock_irqrestore(&opl3->voice_lock, flags);
     351                return;
     352        }
     353
     354 __extra_prg:
     355        kinstr = snd_seq_instr_find(opl3->ilist, &wanted, 1, 0);
     356        if (kinstr == NULL) {
     357                spin_unlock_irqrestore(&opl3->voice_lock, flags);
     358                return;
     359        }
     360
     361        fm = KINSTR_DATA(kinstr);
     362
     363        switch (fm->type) {
     364        case FM_PATCH_OPL2:
     365                instr_4op = 0;
     366                break;
     367        case FM_PATCH_OPL3:
     368                if (opl3->hardware >= OPL3_HW_OPL3) {
     369                        instr_4op = 1;
     370                        break;
     371                }
     372        default:
     373                snd_seq_instr_free_use(opl3->ilist, kinstr);
     374                spin_unlock_irqrestore(&opl3->voice_lock, flags);
     375                return;
     376        }
     377
     378#ifdef DEBUG_MIDI
     379        snd_printk("  --> OPL%i instrument: %s\n",
     380                   instr_4op ? 3 : 2, kinstr->name);
     381#endif
     382        /* in SYNTH mode, application takes care of voices */
     383        /* in SEQ mode, allocate voice on free OPL3 channel */
     384        if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
     385                voice = opl3_get_voice(opl3, instr_4op, chan);
     386        } else {
     387                /* remap OSS voice */
     388                voice = snd_opl3_oss_map[chan->number];         
     389        }
     390
     391        if (voice < MAX_OPL2_VOICES) {
     392                /* Left register block for voices 0 .. 8 */
     393                reg_side = OPL3_LEFT;
     394                voice_offset = voice;
     395                connect_mask = (OPL3_LEFT_4OP_0 << voice_offset) & 0x07;
     396        } else {
     397                /* Right register block for voices 9 .. 17 */
     398                reg_side = OPL3_RIGHT;
     399                voice_offset = voice - MAX_OPL2_VOICES;
     400                connect_mask = (OPL3_RIGHT_4OP_0 << voice_offset) & 0x38;
     401        }
     402
     403        /* kill voice on channel */
     404        vp = &opl3->voices[voice];
     405        if (vp->state > 0) {
     406                opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
     407                reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
     408                opl3->command(opl3, opl3_reg, reg_val);
     409        }
     410        if (instr_4op) {
     411                vp2 = &opl3->voices[voice + 3];
     412                if (vp->state > 0) {
     413                        opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK +
     414                                               voice_offset + 3);
     415                        reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
     416                        opl3->command(opl3, opl3_reg, reg_val);
     417                }
     418        }
     419
     420        /* set connection register */
     421        if (instr_4op) {
     422                if ((opl3->connection_reg ^ connect_mask) & connect_mask) {
     423                        opl3->connection_reg |= connect_mask;
     424                        /* set connection bit */
     425                        opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
     426                        opl3->command(opl3, opl3_reg, opl3->connection_reg);
     427                }
     428        } else {
     429                if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) {
     430                        opl3->connection_reg &= ~connect_mask;
     431                        /* clear connection bit */
     432                        opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
     433                        opl3->command(opl3, opl3_reg, opl3->connection_reg);
     434                }
     435        }
     436
     437#ifdef DEBUG_MIDI
     438        snd_printk("  --> setting OPL3 connection: 0x%x\n",
     439                   opl3->connection_reg);
     440#endif
     441        /*
     442        * calculate volume depending on connection
     443        * between FM operators (see include/opl3.h)
     444        */
     445        for (i = 0; i < (instr_4op ? 4 : 2); i++)
     446                vol_op[i] = fm->op[i].ksl_level;
     447
     448        connection = fm->feedback_connection[0] & 0x01;
     449        if (instr_4op) {
     450                connection <<= 1;
     451                connection |= fm->feedback_connection[1] & 0x01;
     452
     453                snd_opl3_calc_volume(&vol_op[3], vel, chan);
     454                switch (connection) {
     455                case 0x03:
     456                        snd_opl3_calc_volume(&vol_op[2], vel, chan);
     457                        /* fallthru */
     458                case 0x02:
     459                        snd_opl3_calc_volume(&vol_op[0], vel, chan);
     460                        break;
     461                case 0x01:
     462                        snd_opl3_calc_volume(&vol_op[1], vel, chan);
     463                }
     464        } else {
     465                snd_opl3_calc_volume(&vol_op[1], vel, chan);
     466                if (connection)
     467                        snd_opl3_calc_volume(&vol_op[0], vel, chan);
     468        }
     469
     470        /* Program the FM voice characteristics */
     471        for (i = 0; i < (instr_4op ? 4 : 2); i++) {
     472#ifdef DEBUG_MIDI
     473                snd_printk("  --> programming operator %i\n", i);
     474#endif
     475                op_offset = snd_opl3_regmap[voice_offset][i];
     476
     477                /* Set OPL3 AM_VIB register of requested voice/operator */
     478                reg_val = fm->op[i].am_vib;
     479                opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
     480                opl3->command(opl3, opl3_reg, reg_val);
     481
     482                /* Set OPL3 KSL_LEVEL register of requested voice/operator */
     483                reg_val = vol_op[i];
     484                opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
     485                opl3->command(opl3, opl3_reg, reg_val);
     486
     487                /* Set OPL3 ATTACK_DECAY register of requested voice/operator */
     488                reg_val = fm->op[i].attack_decay;
     489                opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
     490                opl3->command(opl3, opl3_reg, reg_val);
     491
     492                /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */
     493                reg_val = fm->op[i].sustain_release;
     494                opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
     495                opl3->command(opl3, opl3_reg, reg_val);
     496
     497                /* Select waveform */
     498                reg_val = fm->op[i].wave_select;
     499                opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
     500                opl3->command(opl3, opl3_reg, reg_val);
     501        }
     502
     503        /* Set operator feedback and 2op inter-operator connection */
     504        reg_val = fm->feedback_connection[0];
     505        /* Set output voice connection */
     506        reg_val |= OPL3_STEREO_BITS;
     507        if (chan->gm_pan < 43)
     508                reg_val &= ~OPL3_VOICE_TO_RIGHT;
     509        if (chan->gm_pan > 85)
     510                reg_val &= ~OPL3_VOICE_TO_LEFT;
     511        opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
     512        opl3->command(opl3, opl3_reg, reg_val);
     513
     514        if (instr_4op) {
     515                /* Set 4op inter-operator connection */
     516                reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT;
     517                /* Set output voice connection */
     518                reg_val |= OPL3_STEREO_BITS;
     519                if (chan->gm_pan < 43)
     520                        reg_val &= ~OPL3_VOICE_TO_RIGHT;
     521                if (chan->gm_pan > 85)
     522                        reg_val &= ~OPL3_VOICE_TO_LEFT;
     523                opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION +
     524                                       voice_offset + 3);
     525                opl3->command(opl3, opl3_reg, reg_val);
     526        }
     527
     528        /*
     529        * Special treatment of percussion notes for fm:
     530        * Requested pitch is really program, and pitch for
     531        * device is whatever was specified in the patch library.
     532        */
     533        if (fm->fix_key)
     534                note = fm->fix_key;
     535        /*
     536        * use transpose if defined in patch library
     537        */
     538        if (fm->trnsps)
     539                note += (fm->trnsps - 64);
     540
     541        snd_opl3_calc_pitch(&fnum, &blocknum, note, chan);
     542
     543        /* Set OPL3 FNUM_LOW register of requested voice */
     544        opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
     545        opl3->command(opl3, opl3_reg, fnum);
     546
     547        opl3->voices[voice].keyon_reg = blocknum;
     548
     549        /* Set output sound flag */
     550        blocknum |= OPL3_KEYON_BIT;
     551
     552#ifdef DEBUG_MIDI
     553        snd_printk("  --> trigger voice %i\n", voice);
     554#endif
     555        /* Set OPL3 KEYON_BLOCK register of requested voice */
     556        opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
     557        opl3->command(opl3, opl3_reg, blocknum);
     558
     559        /* kill note after fixed duration (in centiseconds) */
     560        if (fm->fix_dur) {
     561                opl3->voices[voice].note_off = jiffies +
     562                        (fm->fix_dur * HZ) / 100;
     563                snd_opl3_start_timer(opl3);
     564                opl3->voices[voice].note_off_check = 1;
     565        } else
     566                opl3->voices[voice].note_off_check = 0;
     567
     568        /* get extra pgm, but avoid possible loops */
     569        extra_prg = (extra_prg) ? 0 : fm->modes;
     570
     571        snd_seq_instr_free_use(opl3->ilist, kinstr);
     572
     573        /* do the bookkeeping */
     574        vp->time = opl3->use_time++;
     575        vp->note = key;
     576        vp->chan = chan;
     577
     578        if (instr_4op) {
     579                vp->state = SNDRV_OPL3_ST_ON_4OP;
     580
     581                vp2 = &opl3->voices[voice + 3];
     582                vp2->time = opl3->use_time++;
     583                vp2->note = key;
     584                vp2->chan = chan;
     585                vp2->state = SNDRV_OPL3_ST_NOT_AVAIL;
     586        } else {
     587                if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
     588                        /* 4op killed by 2op, release bounded voice */
     589                        vp2 = &opl3->voices[voice + 3];
     590                        vp2->time = opl3->use_time++;
     591                        vp2->state = SNDRV_OPL3_ST_OFF;
     592                }
     593                vp->state = SNDRV_OPL3_ST_ON_2OP;
     594        }
    594595
    595596#ifdef DEBUG_ALLOC
    596     debug_alloc(opl3, "note on ", voice);
    597 #endif
    598 
    599     /* allocate extra program if specified in patch library */
    600     if (extra_prg) {
    601         if (extra_prg > 128) {
    602             wanted.bank = 128;
    603             /* percussions start at 35 */
    604             wanted.prg = extra_prg - 128 + 35 - 1;
    605         } else {
    606             wanted.bank = 0;
    607             wanted.prg = extra_prg - 1;
    608         }
    609 #ifdef DEBUG_MIDI
    610         snd_printk(" *** allocating extra program\n");
    611 #endif
    612         goto __extra_prg;
    613     }
    614     spin_unlock_irqrestore(&opl3->voice_lock, flags);
    615 }
    616 
    617 static void snd_opl3_kill_voice(opl3_t *opl3, int voice)
    618 {
    619     unsigned short reg_side;
    620     unsigned char voice_offset;
    621     unsigned short opl3_reg;
    622 
    623     snd_opl3_voice_t *vp, *vp2;
    624 
    625     snd_assert(voice < MAX_OPL3_VOICES, return);
    626     vp = &opl3->voices[voice];
    627     if (voice < MAX_OPL2_VOICES) {
    628         /* Left register block for voices 0 .. 8 */
    629         reg_side = OPL3_LEFT;
    630         voice_offset = voice;
    631     } else {
    632         /* Right register block for voices 9 .. 17 */
    633         reg_side = OPL3_RIGHT;
    634         voice_offset = voice - MAX_OPL2_VOICES;
    635     }
    636 
    637     /* kill voice */
    638 #ifdef DEBUG_MIDI
    639     snd_printk("  --> kill voice %i\n", voice);
    640 #endif
    641     opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
    642     /* clear Key ON bit */
    643     opl3->command(opl3, opl3_reg, vp->keyon_reg);
    644 
    645     /* do the bookkeeping */
    646     vp->time = opl3->use_time++;
    647 
    648     if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
    649         vp2 = &opl3->voices[voice + 3];
    650 
    651         vp2->time = opl3->use_time++;
    652         vp2->state = SNDRV_OPL3_ST_OFF;
    653     }
    654     vp->state = SNDRV_OPL3_ST_OFF;
     597        debug_alloc(opl3, "note on ", voice);
     598#endif
     599
     600        /* allocate extra program if specified in patch library */
     601        if (extra_prg) {
     602                if (extra_prg > 128) {
     603                        wanted.bank = 128;
     604                        /* percussions start at 35 */
     605                        wanted.prg = extra_prg - 128 + 35 - 1;
     606                } else {
     607                        wanted.bank = 0;
     608                        wanted.prg = extra_prg - 1;
     609                }
     610#ifdef DEBUG_MIDI
     611                snd_printk(" *** allocating extra program\n");
     612#endif
     613                goto __extra_prg;
     614        }
     615        spin_unlock_irqrestore(&opl3->voice_lock, flags);
     616}
     617
     618static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
     619{
     620        unsigned short reg_side;
     621        unsigned char voice_offset;
     622        unsigned short opl3_reg;
     623
     624        struct snd_opl3_voice *vp, *vp2;
     625
     626        snd_assert(voice < MAX_OPL3_VOICES, return);
     627
     628        vp = &opl3->voices[voice];
     629        if (voice < MAX_OPL2_VOICES) {
     630                /* Left register block for voices 0 .. 8 */
     631                reg_side = OPL3_LEFT;
     632                voice_offset = voice;
     633        } else {
     634                /* Right register block for voices 9 .. 17 */
     635                reg_side = OPL3_RIGHT;
     636                voice_offset = voice - MAX_OPL2_VOICES;
     637        }
     638
     639        /* kill voice */
     640#ifdef DEBUG_MIDI
     641        snd_printk("  --> kill voice %i\n", voice);
     642#endif
     643        opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
     644        /* clear Key ON bit */
     645        opl3->command(opl3, opl3_reg, vp->keyon_reg);
     646
     647        /* do the bookkeeping */
     648        vp->time = opl3->use_time++;
     649
     650        if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
     651                vp2 = &opl3->voices[voice + 3];
     652
     653                vp2->time = opl3->use_time++;
     654                vp2->state = SNDRV_OPL3_ST_OFF;
     655        }
     656        vp->state = SNDRV_OPL3_ST_OFF;
    655657#ifdef DEBUG_ALLOC
    656     debug_alloc(opl3, "note off", voice);
     658        debug_alloc(opl3, "note off", voice);
    657659#endif
    658660
     
    662664 * Release a note in response to a midi note off.
    663665 */
    664 void snd_opl3_note_off(void *p, int note, int vel, snd_midi_channel_t *chan)
    665 {
    666     opl3_t *opl3;
    667 
    668     int voice;
    669     snd_opl3_voice_t *vp;
    670 
    671     unsigned long flags;
    672 
    673     opl3 = p;
    674 
    675 #ifdef DEBUG_MIDI
    676     snd_printk("Note off, ch %i, inst %i, note %i\n",
    677                chan->number, chan->midi_program, note);
    678 #endif
    679 
    680     spin_lock_irqsave(&opl3->voice_lock, flags);
    681 
    682     if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
    683         if (chan->drum_channel && use_internal_drums) {
    684             snd_opl3_drum_switch(opl3, note, vel, 0, chan);
    685             spin_unlock_irqrestore(&opl3->voice_lock, flags);
    686             return;
    687         }
    688         /* this loop will hopefully kill all extra voices, because
    689          they are grouped by the same channel and note values */
    690         for (voice = 0; voice < opl3->max_voices; voice++) {
    691             vp = &opl3->voices[voice];
    692             if (vp->state > 0 && vp->chan == chan && vp->note == note) {
    693                 snd_opl3_kill_voice(opl3, voice);
    694             }
    695         }
    696     } else {
    697         /* remap OSS voices */
    698         if (chan->number < MAX_OPL3_VOICES) {
    699             voice = snd_opl3_oss_map[chan->number];
    700             snd_opl3_kill_voice(opl3, voice);
    701         }
    702     }
    703     spin_unlock_irqrestore(&opl3->voice_lock, flags);
     666void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
     667{
     668        struct snd_opl3 *opl3;
     669
     670        int voice;
     671        struct snd_opl3_voice *vp;
     672
     673        unsigned long flags;
     674
     675        opl3 = p;
     676
     677#ifdef DEBUG_MIDI
     678        snd_printk("Note off, ch %i, inst %i, note %i\n",
     679                   chan->number, chan->midi_program, note);
     680#endif
     681
     682        spin_lock_irqsave(&opl3->voice_lock, flags);
     683
     684        if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
     685                if (chan->drum_channel && use_internal_drums) {
     686                        snd_opl3_drum_switch(opl3, note, vel, 0, chan);
     687                        spin_unlock_irqrestore(&opl3->voice_lock, flags);
     688                        return;
     689                }
     690                /* this loop will hopefully kill all extra voices, because
     691                   they are grouped by the same channel and note values */
     692                for (voice = 0; voice < opl3->max_voices; voice++) {
     693                        vp = &opl3->voices[voice];
     694                        if (vp->state > 0 && vp->chan == chan && vp->note == note) {
     695                                snd_opl3_kill_voice(opl3, voice);
     696                        }
     697                }
     698        } else {
     699                /* remap OSS voices */
     700                if (chan->number < MAX_OPL3_VOICES) {
     701                        voice = snd_opl3_oss_map[chan->number];         
     702                        snd_opl3_kill_voice(opl3, voice);
     703                }
     704        }
     705        spin_unlock_irqrestore(&opl3->voice_lock, flags);
    704706}
    705707
     
    707709 * key pressure change
    708710 */
    709 void snd_opl3_key_press(void *p, int note, int vel, snd_midi_channel_t *chan)
    710 {
    711     opl3_t *opl3;
    712 
    713     opl3 = p;
    714 #ifdef DEBUG_MIDI
    715     snd_printk("Key pressure, ch#: %i, inst#: %i\n",
    716                chan->number, chan->midi_program);
     711void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
     712{
     713        struct snd_opl3 *opl3;
     714
     715        opl3 = p;
     716#ifdef DEBUG_MIDI
     717        snd_printk("Key pressure, ch#: %i, inst#: %i\n",
     718                   chan->number, chan->midi_program);
    717719#endif
    718720}
     
    721723 * terminate note
    722724 */
    723 void snd_opl3_terminate_note(void *p, int note, snd_midi_channel_t *chan)
    724 {
    725     opl3_t *opl3;
    726 
    727     opl3 = p;
    728 #ifdef DEBUG_MIDI
    729     snd_printk("Terminate note, ch#: %i, inst#: %i\n",
    730                chan->number, chan->midi_program);
    731 #endif
    732 }
    733 
    734 static void snd_opl3_update_pitch(opl3_t *opl3, int voice)
    735 {
    736     unsigned short reg_side;
    737     unsigned char voice_offset;
    738     unsigned short opl3_reg;
    739 
    740     unsigned char fnum, blocknum;
    741 
    742     snd_opl3_voice_t *vp;
    743 
    744     snd_assert(voice < MAX_OPL3_VOICES, return);
    745 
    746     vp = &opl3->voices[voice];
    747     if (vp->chan == NULL)
    748         return; /* not allocated? */
    749 
    750     if (voice < MAX_OPL2_VOICES) {
    751         /* Left register block for voices 0 .. 8 */
    752         reg_side = OPL3_LEFT;
    753         voice_offset = voice;
    754     } else {
    755         /* Right register block for voices 9 .. 17 */
    756         reg_side = OPL3_RIGHT;
    757         voice_offset = voice - MAX_OPL2_VOICES;
    758     }
    759 
    760     snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan);
    761 
    762     /* Set OPL3 FNUM_LOW register of requested voice */
    763     opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
    764     opl3->command(opl3, opl3_reg, fnum);
    765 
    766     vp->keyon_reg = blocknum;
    767 
    768     /* Set output sound flag */
    769     blocknum |= OPL3_KEYON_BIT;
    770 
    771     /* Set OPL3 KEYON_BLOCK register of requested voice */
    772     opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
    773     opl3->command(opl3, opl3_reg, blocknum);
    774 
    775     vp->time = opl3->use_time++;
     725void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan)
     726{
     727        struct snd_opl3 *opl3;
     728
     729        opl3 = p;
     730#ifdef DEBUG_MIDI
     731        snd_printk("Terminate note, ch#: %i, inst#: %i\n",
     732                   chan->number, chan->midi_program);
     733#endif
     734}
     735
     736static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
     737{
     738        unsigned short reg_side;
     739        unsigned char voice_offset;
     740        unsigned short opl3_reg;
     741
     742        unsigned char fnum, blocknum;
     743
     744        struct snd_opl3_voice *vp;
     745
     746        snd_assert(voice < MAX_OPL3_VOICES, return);
     747
     748        vp = &opl3->voices[voice];
     749        if (vp->chan == NULL)
     750                return; /* not allocated? */
     751
     752        if (voice < MAX_OPL2_VOICES) {
     753                /* Left register block for voices 0 .. 8 */
     754                reg_side = OPL3_LEFT;
     755                voice_offset = voice;
     756        } else {
     757                /* Right register block for voices 9 .. 17 */
     758                reg_side = OPL3_RIGHT;
     759                voice_offset = voice - MAX_OPL2_VOICES;
     760        }
     761
     762        snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan);
     763
     764        /* Set OPL3 FNUM_LOW register of requested voice */
     765        opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
     766        opl3->command(opl3, opl3_reg, fnum);
     767
     768        vp->keyon_reg = blocknum;
     769
     770        /* Set output sound flag */
     771        blocknum |= OPL3_KEYON_BIT;
     772
     773        /* Set OPL3 KEYON_BLOCK register of requested voice */
     774        opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
     775        opl3->command(opl3, opl3_reg, blocknum);
     776
     777        vp->time = opl3->use_time++;
    776778}
    777779
     
    779781 * Update voice pitch controller
    780782 */
    781 static void snd_opl3_pitch_ctrl(opl3_t *opl3, snd_midi_channel_t *chan)
    782 {
    783     int voice;
    784     snd_opl3_voice_t *vp;
    785 
    786     unsigned long flags;
    787 
    788     spin_lock_irqsave(&opl3->voice_lock, flags);
    789 
    790     if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
    791         for (voice = 0; voice < opl3->max_voices; voice++) {
    792             vp = &opl3->voices[voice];
    793             if (vp->state > 0 && vp->chan == chan) {
    794                 snd_opl3_update_pitch(opl3, voice);
    795             }
    796         }
    797     } else {
    798         /* remap OSS voices */
    799         if (chan->number < MAX_OPL3_VOICES) {
    800             voice = snd_opl3_oss_map[chan->number];
    801             snd_opl3_update_pitch(opl3, voice);
    802         }
    803     }
    804     spin_unlock_irqrestore(&opl3->voice_lock, flags);
     783static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *chan)
     784{
     785        int voice;
     786        struct snd_opl3_voice *vp;
     787
     788        unsigned long flags;
     789
     790        spin_lock_irqsave(&opl3->voice_lock, flags);
     791
     792        if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
     793                for (voice = 0; voice < opl3->max_voices; voice++) {
     794                        vp = &opl3->voices[voice];
     795                        if (vp->state > 0 && vp->chan == chan) {
     796                                snd_opl3_update_pitch(opl3, voice);
     797                        }
     798                }
     799        } else {
     800                /* remap OSS voices */
     801                if (chan->number < MAX_OPL3_VOICES) {
     802                        voice = snd_opl3_oss_map[chan->number];         
     803                        snd_opl3_update_pitch(opl3, voice);
     804                }
     805        }
     806        spin_unlock_irqrestore(&opl3->voice_lock, flags);
    805807}
    806808
     
    809811 * control events, not just the midi controllers
    810812 */
    811 void snd_opl3_control(void *p, int type, snd_midi_channel_t *chan)
    812 {
    813     opl3_t *opl3;
    814 
    815     opl3 = p;
    816 #ifdef DEBUG_MIDI
    817     snd_printk("Controller, TYPE = %i, ch#: %i, inst#: %i\n",
    818                type, chan->number, chan->midi_program);
    819 #endif
    820 
    821     switch (type) {
    822     case MIDI_CTL_MSB_MODWHEEL:
    823         if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63)
    824             opl3->drum_reg |= OPL3_VIBRATO_DEPTH;
    825         else
    826             opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH;
    827         opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
    828                       opl3->drum_reg);
    829         break;
    830     case MIDI_CTL_E2_TREMOLO_DEPTH:
    831         if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63)
    832             opl3->drum_reg |= OPL3_TREMOLO_DEPTH;
    833         else
    834             opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH;
    835         opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
    836                       opl3->drum_reg);
    837         break;
    838     case MIDI_CTL_PITCHBEND:
    839         snd_opl3_pitch_ctrl(opl3, chan);
    840         break;
    841     }
     813void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
     814{
     815        struct snd_opl3 *opl3;
     816
     817        opl3 = p;
     818#ifdef DEBUG_MIDI
     819        snd_printk("Controller, TYPE = %i, ch#: %i, inst#: %i\n",
     820                   type, chan->number, chan->midi_program);
     821#endif
     822
     823        switch (type) {
     824        case MIDI_CTL_MSB_MODWHEEL:
     825                if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63)
     826                        opl3->drum_reg |= OPL3_VIBRATO_DEPTH;
     827                else
     828                        opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH;
     829                opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
     830                                opl3->drum_reg);
     831                break;
     832        case MIDI_CTL_E2_TREMOLO_DEPTH:
     833                if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63)
     834                        opl3->drum_reg |= OPL3_TREMOLO_DEPTH;
     835                else
     836                        opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH;
     837                opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
     838                                opl3->drum_reg);
     839                break;
     840        case MIDI_CTL_PITCHBEND:
     841                snd_opl3_pitch_ctrl(opl3, chan);
     842                break;
     843        }
    842844}
    843845
     
    845847 * NRPN events
    846848 */
    847 void snd_opl3_nrpn(void *p, snd_midi_channel_t *chan,
    848                    snd_midi_channel_set_t *chset)
    849 {
    850     opl3_t *opl3;
    851 
    852     opl3 = p;
    853 #ifdef DEBUG_MIDI
    854     snd_printk("NRPN, ch#: %i, inst#: %i\n",
    855                chan->number, chan->midi_program);
     849void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
     850                   struct snd_midi_channel_set *chset)
     851{
     852        struct snd_opl3 *opl3;
     853
     854        opl3 = p;
     855#ifdef DEBUG_MIDI
     856        snd_printk("NRPN, ch#: %i, inst#: %i\n",
     857                   chan->number, chan->midi_program);
    856858#endif
    857859}
     
    861863 */
    862864void snd_opl3_sysex(void *p, unsigned char *buf, int len,
    863                     int parsed, snd_midi_channel_set_t *chset)
    864 {
    865     opl3_t *opl3;
    866 
    867     opl3 = p;
    868 #ifdef DEBUG_MIDI
    869     snd_printk("SYSEX\n");
    870 #endif
    871 }
     865                    int parsed, struct snd_midi_channel_set *chset)
     866{
     867        struct snd_opl3 *opl3;
     868
     869        opl3 = p;
     870#ifdef DEBUG_MIDI
     871        snd_printk("SYSEX\n");
     872#endif
     873}
  • GPL/trunk/alsa-kernel/drivers/opl3/opl3_seq.c

    r33 r34  
    2323 */
    2424
    25 #define SNDRV_MAIN_OBJECT_FILE
    2625#include "opl3_voice.h"
     26#include <linux/init.h>
     27#include <linux/moduleparam.h>
    2728#include <sound/initval.h>
    2829
     
    3031MODULE_LICENSE("GPL");
    3132MODULE_DESCRIPTION("ALSA driver for OPL3 FM synth");
    32 MODULE_CLASSES("{sound}");
    3333
    3434int use_internal_drums = 0;
    35 MODULE_PARM(use_internal_drums, "i");
     35//module_param(use_internal_drums, bool, 0444);
    3636MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums.");
    3737
    38 int snd_opl3_synth_use_inc(opl3_t * opl3)
    39 {
    40     if (!try_module_get(opl3->card->module))
    41         return -EFAULT;
    42     return 0;
    43 
    44 }
    45 
    46 void snd_opl3_synth_use_dec(opl3_t * opl3)
    47 {
    48     module_put(opl3->card->module);
    49 }
    50 
    51 int snd_opl3_synth_setup(opl3_t * opl3)
    52 {
    53     int idx;
    54 
    55     down(&opl3->access_mutex);
    56     if (opl3->used) {
    57         up(&opl3->access_mutex);
    58         return -EBUSY;
    59     }
    60     opl3->used++;
    61     up(&opl3->access_mutex);
    62 
    63     snd_opl3_reset(opl3);
    64 
    65     for (idx = 0; idx < MAX_OPL3_VOICES; idx++) {
    66         opl3->voices[idx].state = SNDRV_OPL3_ST_OFF;
    67         opl3->voices[idx].time = 0;
    68         opl3->voices[idx].keyon_reg = 0x00;
    69     }
    70     opl3->use_time = 0;
    71     opl3->connection_reg = 0x00;
    72     if (opl3->hardware >= OPL3_HW_OPL3) {
    73         /* Clear 4-op connections */
    74         opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT,
    75                       opl3->connection_reg);
    76         opl3->max_voices = MAX_OPL3_VOICES;
    77     }
    78     return 0;
    79 }
    80 
    81 void snd_opl3_synth_cleanup(opl3_t * opl3)
    82 {
    83     unsigned long flags;
    84 
    85     /* Stop system timer */
    86     spin_lock_irqsave(&opl3->sys_timer_lock, flags);
    87     if (opl3->sys_timer_status) {
    88         del_timer(&opl3->tlist);
    89         opl3->sys_timer_status = 0;
    90     }
    91     spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
    92 
    93     snd_opl3_reset(opl3);
    94     down(&opl3->access_mutex);
    95     opl3->used--;
    96     up(&opl3->access_mutex);
    97 }
    98 
    99 int snd_opl3_synth_use(void *private_data, snd_seq_port_subscribe_t * info)
    100 {
    101     opl3_t *opl3 = private_data;
    102     int err;
    103 
    104     if ((err = snd_opl3_synth_setup(opl3)) < 0)
    105         return err;
    106 
    107     if (use_internal_drums) {
    108         /* Percussion mode */
    109         opl3->voices[6].state = opl3->voices[7].state =
    110             opl3->voices[8].state = SNDRV_OPL3_ST_NOT_AVAIL;
    111         snd_opl3_load_drums(opl3);
    112         opl3->drum_reg = OPL3_PERCUSSION_ENABLE;
    113         opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, opl3->drum_reg);
    114     } else {
    115         opl3->drum_reg = 0x00;
    116     }
    117 
    118     if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
    119         if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
    120             return err;
    121     }
    122     opl3->synth_mode = SNDRV_OPL3_MODE_SEQ;
    123     return 0;
    124 }
    125 
    126 int snd_opl3_synth_unuse(void *private_data, snd_seq_port_subscribe_t * info)
    127 {
    128     opl3_t *opl3 = private_data;
    129 
    130     snd_opl3_synth_cleanup(opl3);
    131 
    132     if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
    133         snd_opl3_synth_use_dec(opl3);
    134     return 0;
     38int snd_opl3_synth_use_inc(struct snd_opl3 * opl3)
     39{
     40        if (!try_module_get(opl3->card->module))
     41                return -EFAULT;
     42        return 0;
     43
     44}
     45
     46void snd_opl3_synth_use_dec(struct snd_opl3 * opl3)
     47{
     48        module_put(opl3->card->module);
     49}
     50
     51int snd_opl3_synth_setup(struct snd_opl3 * opl3)
     52{
     53        int idx;
     54
     55        down(&opl3->access_mutex);
     56        if (opl3->used) {
     57                up(&opl3->access_mutex);
     58                return -EBUSY;
     59        }
     60        opl3->used++;
     61        up(&opl3->access_mutex);
     62
     63        snd_opl3_reset(opl3);
     64
     65        for (idx = 0; idx < MAX_OPL3_VOICES; idx++) {
     66                opl3->voices[idx].state = SNDRV_OPL3_ST_OFF;
     67                opl3->voices[idx].time = 0;
     68                opl3->voices[idx].keyon_reg = 0x00;
     69        }
     70        opl3->use_time = 0;
     71        opl3->connection_reg = 0x00;
     72        if (opl3->hardware >= OPL3_HW_OPL3) {
     73                /* Clear 4-op connections */
     74                opl3->command(opl3, OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT,
     75                                opl3->connection_reg);
     76                opl3->max_voices = MAX_OPL3_VOICES;
     77        }
     78        return 0;
     79}
     80
     81void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
     82{
     83        unsigned long flags;
     84
     85        /* Stop system timer */
     86        spin_lock_irqsave(&opl3->sys_timer_lock, flags);
     87        if (opl3->sys_timer_status) {
     88                del_timer(&opl3->tlist);
     89                opl3->sys_timer_status = 0;
     90        }
     91        spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
     92
     93        snd_opl3_reset(opl3);
     94        down(&opl3->access_mutex);
     95        opl3->used--;
     96        up(&opl3->access_mutex);
     97}
     98
     99static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
     100{
     101        struct snd_opl3 *opl3 = private_data;
     102        int err;
     103
     104        if ((err = snd_opl3_synth_setup(opl3)) < 0)
     105                return err;
     106
     107        if (use_internal_drums) {
     108                /* Percussion mode */
     109                opl3->voices[6].state = opl3->voices[7].state =
     110                        opl3->voices[8].state = SNDRV_OPL3_ST_NOT_AVAIL;
     111                snd_opl3_load_drums(opl3);
     112                opl3->drum_reg = OPL3_PERCUSSION_ENABLE;
     113                opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, opl3->drum_reg);
     114        } else {
     115                opl3->drum_reg = 0x00;
     116        }
     117
     118        if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
     119                if ((err = snd_opl3_synth_use_inc(opl3)) < 0)
     120                        return err;
     121        }
     122        opl3->synth_mode = SNDRV_OPL3_MODE_SEQ;
     123        return 0;
     124}
     125
     126static int snd_opl3_synth_unuse(void *private_data, struct snd_seq_port_subscribe * info)
     127{
     128        struct snd_opl3 *opl3 = private_data;
     129
     130        snd_opl3_synth_cleanup(opl3);
     131
     132        if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
     133                snd_opl3_synth_use_dec(opl3);
     134        return 0;
    135135}
    136136
     
    138138 * MIDI emulation operators
    139139 */
    140 snd_midi_op_t opl3_ops = {
    141     snd_opl3_note_on,
    142     snd_opl3_note_off,
    143     snd_opl3_key_press,
    144     snd_opl3_terminate_note,
    145     snd_opl3_control,
    146     snd_opl3_nrpn,
    147     snd_opl3_sysex,
     140struct snd_midi_op opl3_ops = {
     141        .note_on =              snd_opl3_note_on,
     142        .note_off =             snd_opl3_note_off,
     143        .key_press =            snd_opl3_key_press,
     144        .note_terminate =       snd_opl3_terminate_note,
     145        .control =              snd_opl3_control,
     146        .nrpn =                 snd_opl3_nrpn,
     147        .sysex =                snd_opl3_sysex,
    148148};
    149149
    150 static int snd_opl3_synth_event_input(snd_seq_event_t * ev, int direct,
    151                                       void *private_data, int atomic, int hop)
    152 {
    153     opl3_t *opl3 = private_data;
    154 
    155     if (ev->type >= SNDRV_SEQ_EVENT_INSTR_BEGIN &&
    156         ev->type <= SNDRV_SEQ_EVENT_INSTR_CHANGE) {
    157         if (direct) {
    158             snd_seq_instr_event(&opl3->fm_ops, opl3->ilist, ev,
    159                                 opl3->seq_client, atomic, hop);
    160         }
    161     } else {
    162         snd_midi_process_event(&opl3_ops, ev, opl3->chset);
    163     }
    164     return 0;
     150static int snd_opl3_synth_event_input(struct snd_seq_event * ev, int direct,
     151                                      void *private_data, int atomic, int hop)
     152{
     153        struct snd_opl3 *opl3 = private_data;
     154
     155        if (ev->type >= SNDRV_SEQ_EVENT_INSTR_BEGIN &&
     156            ev->type <= SNDRV_SEQ_EVENT_INSTR_CHANGE) {
     157                if (direct) {
     158                        snd_seq_instr_event(&opl3->fm_ops, opl3->ilist, ev,
     159                                            opl3->seq_client, atomic, hop);
     160                }
     161        } else {
     162                snd_midi_process_event(&opl3_ops, ev, opl3->chset);
     163        }
     164        return 0;
    165165}
    166166
     
    169169static void snd_opl3_synth_free_port(void *private_data)
    170170{
    171     opl3_t *opl3 = private_data;
    172 
    173     snd_midi_channel_free_set(opl3->chset);
    174 }
    175 
    176 static int snd_opl3_synth_create_port(opl3_t * opl3)
    177 {
    178     snd_seq_port_callback_t callbacks;
    179     char name[32];
    180     int voices, opl_ver;
    181 
    182     voices = (opl3->hardware < OPL3_HW_OPL3) ?
    183         MAX_OPL2_VOICES : MAX_OPL3_VOICES;
    184     opl3->chset = snd_midi_channel_alloc_set(16);
    185     if (opl3->chset == NULL)
    186         return -ENOMEM;
    187     opl3->chset->private_data = opl3;
    188 
    189     memset(&callbacks, 0, sizeof(callbacks));
    190     callbacks.owner = THIS_MODULE;
    191     callbacks.use = snd_opl3_synth_use;
    192     callbacks.unuse = snd_opl3_synth_unuse;
    193     callbacks.event_input = snd_opl3_synth_event_input;
    194     callbacks.private_free = snd_opl3_synth_free_port;
    195     callbacks.private_data = opl3;
    196 
    197     opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
    198     sprintf(name, "OPL%i FM Port", opl_ver);
    199 
    200     opl3->chset->client = opl3->seq_client;
    201     opl3->chset->port = snd_seq_event_port_attach(opl3->seq_client, &callbacks,
    202                                                   SNDRV_SEQ_PORT_CAP_WRITE |
    203                                                   SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
    204                                                   SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
    205                                                   SNDRV_SEQ_PORT_TYPE_MIDI_GM |
    206                                                   SNDRV_SEQ_PORT_TYPE_SYNTH,
    207                                                   16, voices,
    208                                                   name);
    209     if (opl3->chset->port < 0) {
    210         snd_midi_channel_free_set(opl3->chset);
    211         return opl3->chset->port;
    212     }
    213     return 0;
     171        struct snd_opl3 *opl3 = private_data;
     172
     173        snd_midi_channel_free_set(opl3->chset);
     174}
     175
     176static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
     177{
     178        struct snd_seq_port_callback callbacks;
     179        char name[32];
     180        int voices, opl_ver;
     181
     182        voices = (opl3->hardware < OPL3_HW_OPL3) ?
     183                MAX_OPL2_VOICES : MAX_OPL3_VOICES;
     184        opl3->chset = snd_midi_channel_alloc_set(16);
     185        if (opl3->chset == NULL)
     186                return -ENOMEM;
     187        opl3->chset->private_data = opl3;
     188
     189        memset(&callbacks, 0, sizeof(callbacks));
     190        callbacks.owner = THIS_MODULE;
     191        callbacks.use = snd_opl3_synth_use;
     192        callbacks.unuse = snd_opl3_synth_unuse;
     193        callbacks.event_input = snd_opl3_synth_event_input;
     194        callbacks.private_free = snd_opl3_synth_free_port;
     195        callbacks.private_data = opl3;
     196
     197        opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
     198        sprintf(name, "OPL%i FM Port", opl_ver);
     199
     200        opl3->chset->client = opl3->seq_client;
     201        opl3->chset->port = snd_seq_event_port_attach(opl3->seq_client, &callbacks,
     202                                                      SNDRV_SEQ_PORT_CAP_WRITE |
     203                                                      SNDRV_SEQ_PORT_CAP_SUBS_WRITE,
     204                                                      SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
     205                                                      SNDRV_SEQ_PORT_TYPE_MIDI_GM |
     206                                                      SNDRV_SEQ_PORT_TYPE_SYNTH,
     207                                                      16, voices,
     208                                                      name);
     209        if (opl3->chset->port < 0) {
     210                snd_midi_channel_free_set(opl3->chset);
     211                return opl3->chset->port;
     212        }
     213        return 0;
    214214}
    215215
    216216/* ------------------------------ */
    217217
    218 static int snd_opl3_seq_new_device(snd_seq_device_t *dev)
    219 {
    220     opl3_t *opl3;
    221     int client;
    222     snd_seq_client_callback_t callbacks;
    223     snd_seq_client_info_t cinfo;
    224     int opl_ver;
    225 
    226     opl3 = *(opl3_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
    227     if (opl3 == NULL)
    228         return -EINVAL;
    229 
    230     spin_lock_init(&opl3->voice_lock);
    231 
    232     opl3->seq_client = -1;
    233 
    234     /* allocate new client */
    235     memset(&callbacks, 0, sizeof(callbacks));
    236     callbacks.private_data = opl3;
    237     callbacks.allow_output = callbacks.allow_input = 1;
    238     client = opl3->seq_client =
    239         snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num, &callbacks);
    240     if (client < 0)
    241         return client;
    242 
    243     /* change name of client */
    244     memset(&cinfo, 0, sizeof(cinfo));
    245     cinfo.client = client;
    246     cinfo.type = KERNEL_CLIENT;
    247     opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
    248     sprintf(cinfo.name, "OPL%i FM synth", opl_ver);
    249     snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
    250 
    251     snd_opl3_synth_create_port(opl3);
    252 
    253     /* initialize instrument list */
    254     opl3->ilist = snd_seq_instr_list_new();
    255     if (opl3->ilist == NULL) {
    256         snd_seq_delete_kernel_client(client);
    257         opl3->seq_client = -1;
    258         return -ENOMEM;
    259     }
    260     opl3->ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT;
    261     snd_seq_fm_init(&opl3->fm_ops, NULL);
    262 
    263     /* setup system timer */
    264     init_timer(&opl3->tlist);
    265     opl3->tlist.function = snd_opl3_timer_func;
    266     opl3->tlist.data = (unsigned long) opl3;
    267     spin_lock_init(&opl3->sys_timer_lock);
    268     opl3->sys_timer_status = 0;
     218static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
     219{
     220        struct snd_opl3 *opl3;
     221        int client;
     222        struct snd_seq_client_callback callbacks;
     223        struct snd_seq_client_info cinfo;
     224        int opl_ver;
     225
     226        opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
     227        if (opl3 == NULL)
     228                return -EINVAL;
     229
     230        spin_lock_init(&opl3->voice_lock);
     231
     232        opl3->seq_client = -1;
     233
     234        /* allocate new client */
     235        memset(&callbacks, 0, sizeof(callbacks));
     236        callbacks.private_data = opl3;
     237        callbacks.allow_output = callbacks.allow_input = 1;
     238        client = opl3->seq_client =
     239            snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num, &callbacks);
     240        if (client < 0)
     241                return client;
     242
     243        /* change name of client */
     244        memset(&cinfo, 0, sizeof(cinfo));
     245        cinfo.client = client;
     246        cinfo.type = KERNEL_CLIENT;
     247        opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
     248        sprintf(cinfo.name, "OPL%i FM synth", opl_ver);
     249        snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
     250
     251        snd_opl3_synth_create_port(opl3);
     252
     253        /* initialize instrument list */
     254        opl3->ilist = snd_seq_instr_list_new();
     255        if (opl3->ilist == NULL) {
     256                snd_seq_delete_kernel_client(client);
     257                opl3->seq_client = -1;
     258                return -ENOMEM;
     259        }
     260        opl3->ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT;
     261        snd_seq_fm_init(&opl3->fm_ops, NULL);
     262
     263        /* setup system timer */
     264        init_timer(&opl3->tlist);
     265        opl3->tlist.function = snd_opl3_timer_func;
     266        opl3->tlist.data = (unsigned long) opl3;
     267        spin_lock_init(&opl3->sys_timer_lock);
     268        opl3->sys_timer_status = 0;
    269269
    270270#ifdef CONFIG_SND_SEQUENCER_OSS
    271     snd_opl3_init_seq_oss(opl3, cinfo.name);
     271        snd_opl3_init_seq_oss(opl3, cinfo.name);
    272272#endif
    273     return 0;
    274 }
    275 
    276 static int snd_opl3_seq_delete_device(snd_seq_device_t *dev)
    277 {
    278     opl3_t *opl3;
    279 
    280     opl3 = *(opl3_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
    281     if (opl3 == NULL)
    282         return -EINVAL;
     273        return 0;
     274}
     275
     276static int snd_opl3_seq_delete_device(struct snd_seq_device *dev)
     277{
     278        struct snd_opl3 *opl3;
     279
     280        opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
     281        if (opl3 == NULL)
     282                return -EINVAL;
    283283
    284284#ifdef CONFIG_SND_SEQUENCER_OSS
    285     snd_opl3_free_seq_oss(opl3);
     285        snd_opl3_free_seq_oss(opl3);
    286286#endif
    287     if (opl3->seq_client >= 0) {
    288         snd_seq_delete_kernel_client(opl3->seq_client);
    289         opl3->seq_client = -1;
    290     }
    291     if (opl3->ilist)
    292         snd_seq_instr_list_free(&opl3->ilist);
    293     return 0;
     287        if (opl3->seq_client >= 0) {
     288                snd_seq_delete_kernel_client(opl3->seq_client);
     289                opl3->seq_client = -1;
     290        }
     291        if (opl3->ilist)
     292                snd_seq_instr_list_free(&opl3->ilist);
     293        return 0;
    294294}
    295295
    296296static int __init alsa_opl3_seq_init(void)
    297297{
    298     static snd_seq_dev_ops_t ops =
    299     {
    300         snd_opl3_seq_new_device,
    301         snd_opl3_seq_delete_device
    302     };
    303 
    304     return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL3, &ops,
    305                                           sizeof(opl3_t*));
     298        static struct snd_seq_dev_ops ops =
     299        {
     300                snd_opl3_seq_new_device,
     301                snd_opl3_seq_delete_device
     302        };
     303
     304        return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL3, &ops,
     305                                              sizeof(struct snd_opl3 *));
    306306}
    307307
    308308static void __exit alsa_opl3_seq_exit(void)
    309309{
    310     snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL3);
     310        snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_OPL3);
    311311}
    312312
Note: See TracChangeset for help on using the changeset viewer.