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

Update source to ALSA 1.0.16 level

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GPL/branches/uniaud-2.0/alsa-kernel/isa/sgalaxy.c

    r32 r305  
    1818 *   You should have received a copy of the GNU General Public License
    1919 *   along with this program; if not, write to the Free Software
    20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    2121 *
    2222 */
    2323
    24 #define SNDRV_MAIN_OBJECT_FILE
    25 #include <sound/driver.h>
     24#include <linux/init.h>
     25#include <linux/err.h>
     26#include <linux/isa.h>
     27#include <linux/delay.h>
     28#include <linux/time.h>
     29#include <linux/interrupt.h>
     30#include <linux/moduleparam.h>
     31#include <asm/dma.h>
     32#include <sound/core.h>
    2633#include <sound/sb.h>
    2734#include <sound/ad1848.h>
     35#include <sound/control.h>
    2836#define SNDRV_LEGACY_FIND_FREE_IRQ
    2937#define SNDRV_LEGACY_FIND_FREE_DMA
    30 #define SNDRV_GET_ID
    3138#include <sound/initval.h>
    3239
    33 EXPORT_NO_SYMBOLS;
     40MODULE_AUTHOR("Christopher Butler <chrisb@sandy.force9.co.uk>");
    3441MODULE_DESCRIPTION("Aztech Sound Galaxy");
    35 MODULE_CLASSES("{sound}");
    36 MODULE_DEVICES("{{Aztech Systems,Sound Galaxy}}");
    37 
    38 static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;  /* Index 0-MAX */
    39 static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;   /* ID for this card */
    40 static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;      /* Enable this card */
    41 static long snd_sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;       /* 0x220,0x240 */
    42 static long snd_wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;      /* 0x530,0xe80,0xf40,0x604 */
    43 static int snd_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;    /* 7,9,10,11 */
    44 static int snd_dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;   /* 0,1,3 */
    45 
    46 MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
    47 MODULE_PARM_DESC(snd_index, "Index value for Sound Galaxy soundcard.");
    48 MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);
    49 MODULE_PARM(snd_id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
    50 MODULE_PARM_DESC(snd_id, "ID string for Sound Galaxy soundcard.");
    51 MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);
    52 MODULE_PARM(snd_sbport, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
    53 MODULE_PARM_DESC(snd_sbport, "Port # for Sound Galaxy SB driver.");
    54 MODULE_PARM_SYNTAX(snd_sbport, SNDRV_ENABLED ",allows:{{0x220},{0x240}},dialog:list");
    55 MODULE_PARM(snd_wssport, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
    56 MODULE_PARM_DESC(snd_wssport, "Port # for Sound Galaxy WSS driver.");
    57 MODULE_PARM_SYNTAX(snd_wssport, SNDRV_ENABLED ",allows:{{0x530},{0xe80},{0xf40},{0x604}},dialog:list");
    58 MODULE_PARM(snd_irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
    59 MODULE_PARM_DESC(snd_irq, "IRQ # for Sound Galaxy driver.");
    60 MODULE_PARM_SYNTAX(snd_irq, SNDRV_ENABLED ",allows:{{7},{9},{10},{11}},dialog:list");
    61 MODULE_PARM(snd_dma1, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
    62 MODULE_PARM_DESC(snd_dma1, "DMA1 # for Sound Galaxy driver.");
    63 MODULE_PARM_SYNTAX(snd_dma1, SNDRV_DMA8_DESC);
     42MODULE_LICENSE("GPL");
     43MODULE_SUPPORTED_DEVICE("{{Aztech Systems,Sound Galaxy}}");
     44
     45static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
     46static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
     47static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;  /* Enable this card */
     48static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;   /* 0x220,0x240 */
     49static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;  /* 0x530,0xe80,0xf40,0x604 */
     50static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;        /* 7,9,10,11 */
     51static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;       /* 0,1,3 */
     52
     53module_param_array(index, int, NULL, 0444);
     54MODULE_PARM_DESC(index, "Index value for Sound Galaxy soundcard.");
     55module_param_array(id, charp, NULL, 0444);
     56MODULE_PARM_DESC(id, "ID string for Sound Galaxy soundcard.");
     57module_param_array(sbport, long, NULL, 0444);
     58MODULE_PARM_DESC(sbport, "Port # for Sound Galaxy SB driver.");
     59module_param_array(wssport, long, NULL, 0444);
     60MODULE_PARM_DESC(wssport, "Port # for Sound Galaxy WSS driver.");
     61module_param_array(irq, int, NULL, 0444);
     62MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
     63module_param_array(dma1, int, NULL, 0444);
     64MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
    6465
    6566#define SGALAXY_AUXC_LEFT 18
    6667#define SGALAXY_AUXC_RIGHT 19
    6768
    68 static snd_card_t *snd_sgalaxy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
     69#define PFX     "sgalaxy: "
    6970
    7071/*
     
    7475#define AD1848P1( port, x ) ( port + c_d_c_AD1848##x )
    7576
    76 /* from lowlevel/sb/sb.c - to avoid having to allocate a sb_t for the */
     77/* from lowlevel/sb/sb.c - to avoid having to allocate a struct snd_sb for the */
    7778/* short time we actually need it.. */
    7879
     
    9394}
    9495
    95 static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val)
     96static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port,
     97                                               unsigned char val)
    9698{
    9799        int i;
     
    106108}
    107109
    108 static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
     110static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
     111{
     112        return IRQ_NONE;
     113}
     114
     115static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
    109116{
    110117        static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1,
     
    113120        int tmp, tmp1;
    114121
    115         unsigned int flags;
    116 
    117122        if ((tmp = inb(port + 3)) == 0xff)
    118123        {
    119                 snd_printdd("I/O address dead (0x%lx)\n", tmp);
     124                snd_printdd("I/O address dead (0x%lx)\n", port);
    120125                return 0;
    121126        }
     
    133138
    134139#if 0
    135         snd_printdd("sgalaxy - setting up IRQ/DMA for WSS\n");
    136 #endif
    137 
    138         save_flags(flags);
    139         cli();
     140        snd_printdd(PFX "setting up IRQ/DMA for WSS\n");
     141#endif
    140142
    141143        /* initialize IRQ for WSS codec */
    142144        tmp = interrupt_bits[irq % 16];
    143         if (tmp < 0) {
    144                 restore_flags(flags);
     145        if (tmp < 0)
    145146                return -EINVAL;
    146         }
     147
     148        if (request_irq(irq, snd_sgalaxy_dummy_interrupt, IRQF_DISABLED, "sgalaxy", NULL)) {
     149                snd_printk(KERN_ERR "sgalaxy: can't grab irq %d\n", irq);
     150                return -EIO;
     151        }
     152
    147153        outb(tmp | 0x40, port);
    148154        tmp1 = dma_bits[dma % 4];
    149155        outb(tmp | tmp1, port);
    150156
    151         restore_flags(flags);
    152         return 0;
    153 }
    154 
    155 static int __init snd_sgalaxy_detect(int dev, int irq, int dma)
     157        free_irq(irq, NULL);
     158
     159        return 0;
     160}
     161
     162static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
    156163{
    157164#if 0
    158         snd_printdd("sgalaxy - switching to WSS mode\n");
     165        snd_printdd(PFX "switching to WSS mode\n");
    159166#endif
    160167
    161168        /* switch to WSS mode */
    162         snd_sgalaxy_sbdsp_reset(snd_sbport[dev]);
    163 
    164         snd_sgalaxy_sbdsp_command(snd_sbport[dev], 9);
    165         snd_sgalaxy_sbdsp_command(snd_sbport[dev], 0);
     169        snd_sgalaxy_sbdsp_reset(sbport[dev]);
     170
     171        snd_sgalaxy_sbdsp_command(sbport[dev], 9);
     172        snd_sgalaxy_sbdsp_command(sbport[dev], 0);
    166173
    167174        udelay(400);
    168         return snd_sgalaxy_setup_wss(snd_wssport[dev], irq, dma);
    169 }
    170 
    171 #define SGALAXY_CONTROLS 2
    172 
    173 static snd_kcontrol_new_t snd_sgalaxy_controls[2] = {
     175        return snd_sgalaxy_setup_wss(wssport[dev], irq, dma);
     176}
     177
     178static struct ad1848_mix_elem snd_sgalaxy_controls[] = {
    174179AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1),
    175180AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
    176181};
    177182
    178 static int __init snd_sgalaxy_mixer(ad1848_t *chip)
    179 {
    180         snd_card_t *card = chip->card;
    181         snd_ctl_elem_id_t id1, id2;
    182         int idx, err;
     183static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip)
     184{
     185        struct snd_card *card = chip->card;
     186        struct snd_ctl_elem_id id1, id2;
     187        unsigned int idx;
     188        int err;
    183189
    184190        memset(&id1, 0, sizeof(id1));
     
    204210                return err;
    205211        /* build AUX2 input */
    206         for (idx = 0; idx < SGALAXY_CONTROLS; idx++) {
    207                 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sgalaxy_controls[idx], chip))) < 0)
     212        for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) {
     213                if ((err = snd_ad1848_add_ctl_elem(chip, &snd_sgalaxy_controls[idx])) < 0)
    208214                        return err;
    209215        }
     
    211217}
    212218
    213 static int __init snd_sgalaxy_probe(int dev)
     219static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev)
     220{
     221        if (!enable[dev])
     222                return 0;
     223        if (sbport[dev] == SNDRV_AUTO_PORT) {
     224                snd_printk(KERN_ERR PFX "specify SB port\n");
     225                return 0;
     226        }
     227        if (wssport[dev] == SNDRV_AUTO_PORT) {
     228                snd_printk(KERN_ERR PFX "specify WSS port\n");
     229                return 0;
     230        }
     231        return 1;
     232}
     233
     234static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
    214235{
    215236        static int possible_irqs[] = {7, 9, 10, 11, -1};
    216237        static int possible_dmas[] = {1, 3, 0, -1};
    217         int err, irq, dma1;
    218         snd_card_t *card;
    219         ad1848_t *chip;
    220 
    221         if (snd_sbport[dev] == SNDRV_AUTO_PORT) {
    222                 snd_printk("specify SB port\n");
    223                 return -EINVAL;
    224         }
    225         if (snd_wssport[dev] == SNDRV_AUTO_PORT) {
    226                 snd_printk("specify WSS port\n");
    227                 return -EINVAL;
    228         }
    229         card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE, 0);
     238        int err, xirq, xdma1;
     239        struct snd_card *card;
     240        struct snd_ad1848 *chip;
     241
     242        card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
    230243        if (card == NULL)
    231244                return -ENOMEM;
    232245
    233         irq = snd_irq[dev];
    234         if (irq == SNDRV_AUTO_IRQ) {
    235                 if ((irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
    236                         snd_card_free(card);
    237                         snd_printk("unable to find a free IRQ\n");
    238                         return -EBUSY;
     246        xirq = irq[dev];
     247        if (xirq == SNDRV_AUTO_IRQ) {
     248                if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
     249                        snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
     250                        err = -EBUSY;
     251                        goto _err;
    239252                }
    240253        }
    241         dma1 = snd_dma1[dev];
    242         if (dma1 == SNDRV_AUTO_DMA) {
    243                 if ((dma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
    244                         snd_card_free(card);
    245                         snd_printk("unable to find a free DMA\n");
    246                         return -EBUSY;
     254        xdma1 = dma1[dev];
     255        if (xdma1 == SNDRV_AUTO_DMA) {
     256                if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
     257                        snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
     258                        err = -EBUSY;
     259                        goto _err;
    247260                }
    248261        }
    249262
    250         if ((err = snd_sgalaxy_detect(dev, irq, dma1)) < 0) {
    251                 snd_card_free(card);
    252                 return err;
    253         }
    254 
    255         if ((err = snd_ad1848_create(card, snd_wssport[dev] + 4,
    256                                      irq, dma1,
    257                                      AD1848_HW_DETECT, &chip)) < 0) {
    258                 snd_card_free(card);
    259                 return err;
    260         }
     263        if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0)
     264                goto _err;
     265
     266        if ((err = snd_ad1848_create(card, wssport[dev] + 4,
     267                                     xirq, xdma1,
     268                                     AD1848_HW_DETECT, &chip)) < 0)
     269                goto _err;
     270        card->private_data = chip;
    261271
    262272        if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) {
    263                 snd_printdd("sgalaxy - error creating new ad1848 PCM device\n");
    264                 snd_card_free(card);
    265                 return err;
     273                snd_printdd(PFX "error creating new ad1848 PCM device\n");
     274                goto _err;
    266275        }
    267276        if ((err = snd_ad1848_mixer(chip)) < 0) {
    268                 snd_printdd("sgalaxy - error creating new ad1848 mixer\n");
    269                 snd_card_free(card);
    270                 return err;
    271         }
    272         if (snd_sgalaxy_mixer(chip) < 0) {
    273                 snd_printdd("sgalaxy - the mixer rewrite failed\n");
    274                 snd_card_free(card);
    275                 return err;
     277                snd_printdd(PFX "error creating new ad1848 mixer\n");
     278                goto _err;
     279        }
     280        if ((err = snd_sgalaxy_mixer(chip)) < 0) {
     281                snd_printdd(PFX "the mixer rewrite failed\n");
     282                goto _err;
    276283        }
    277284
     
    279286        strcpy(card->shortname, "Sound Galaxy");
    280287        sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
    281                 snd_wssport[dev], irq, dma1);
    282 
    283         if ((err = snd_card_register(card)) < 0) {
    284                 snd_card_free(card);
    285                 return err;
    286         }
    287         snd_sgalaxy_cards[dev] = card;
    288         return 0;
    289 }
     288                wssport[dev], xirq, xdma1);
     289
     290        snd_card_set_dev(card, devptr);
     291
     292        if ((err = snd_card_register(card)) < 0)
     293                goto _err;
     294
     295        dev_set_drvdata(devptr, card);
     296        return 0;
     297
     298 _err:
     299        snd_card_free(card);
     300        return err;
     301}
     302
     303static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev)
     304{
     305        snd_card_free(dev_get_drvdata(devptr));
     306        dev_set_drvdata(devptr, NULL);
     307        return 0;
     308}
     309
     310#ifdef CONFIG_PM
     311static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
     312                               pm_message_t state)
     313{
     314        struct snd_card *card = dev_get_drvdata(pdev);
     315        struct snd_ad1848 *chip = card->private_data;
     316
     317        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
     318        chip->suspend(chip);
     319        return 0;
     320}
     321
     322static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
     323{
     324        struct snd_card *card = dev_get_drvdata(pdev);
     325        struct snd_ad1848 *chip = card->private_data;
     326
     327        chip->resume(chip);
     328        snd_ad1848_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]);
     329        snd_ad1848_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]);
     330
     331        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
     332        return 0;
     333}
     334#endif
     335
     336#define DEV_NAME "sgalaxy"
     337
     338static struct isa_driver snd_sgalaxy_driver = {
     339        .match          = snd_sgalaxy_match,
     340        .probe          = snd_sgalaxy_probe,
     341        .remove         = __devexit_p(snd_sgalaxy_remove),
     342#ifdef CONFIG_PM
     343        .suspend        = snd_sgalaxy_suspend,
     344        .resume         = snd_sgalaxy_resume,
     345#endif
     346        .driver         = {
     347                .name   = DEV_NAME
     348        },
     349};
    290350
    291351static int __init alsa_card_sgalaxy_init(void)
    292352{
    293         int dev, cards;
    294 
    295         for (dev = cards = 0; dev < SNDRV_CARDS && snd_enable[dev]; dev++) {
    296                 if (snd_sgalaxy_probe(dev) >= 0)
    297                         cards++;
    298         }
    299         if (!cards) {
    300 #ifdef MODULE
    301                 snd_printk("Sound Galaxy soundcard not found or device busy\n");
    302 #endif
    303                 return -ENODEV;
    304         }
    305 
    306         return 0;
     353        return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS);
    307354}
    308355
    309356static void __exit alsa_card_sgalaxy_exit(void)
    310357{
    311         int idx;
    312 
    313         for (idx = 0; idx < SNDRV_CARDS; idx++)
    314                 snd_card_free(snd_sgalaxy_cards[idx]);
     358        isa_unregister_driver(&snd_sgalaxy_driver);
    315359}
    316360
    317361module_init(alsa_card_sgalaxy_init)
    318362module_exit(alsa_card_sgalaxy_exit)
    319 
    320 #ifndef MODULE
    321 
    322 /* format is: snd-card-sgalaxy=snd_enable,snd_index,snd_id,
    323                                snd_sbport,snd_wssport,
    324                                snd_irq,snd_dma1 */
    325 
    326 static int __init alsa_card_sgalaxy_setup(char *str)
    327 {
    328         static unsigned __initdata nr_dev = 0;
    329 
    330         if (nr_dev >= SNDRV_CARDS)
    331                 return 0;
    332         (void)(get_option(&str,&snd_enable[nr_dev]) == 2 &&
    333                get_option(&str,&snd_index[nr_dev]) == 2 &&
    334                get_id(&str,&snd_id[nr_dev]) == 2 &&
    335                get_option(&str,(int *)&snd_sbport[nr_dev]) == 2 &&
    336                get_option(&str,(int *)&snd_wssport[nr_dev]) == 2 &&
    337                get_option(&str,(int *)&snd_irq[nr_dev]) == 2 &&
    338                get_option(&str,(int *)&snd_dma1[nr_dev]) == 2);
    339         nr_dev++;
    340         return 1;
    341 }
    342 
    343 __setup("snd-card-sgalaxy=", alsa_card_sgalaxy_setup);
    344 
    345 #endif /* ifndef MODULE */
Note: See TracChangeset for help on using the changeset viewer.