root/sound/isa/gus/gusmax.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_gusmax_detect
  2. snd_gusmax_interrupt
  3. snd_gusmax_init
  4. snd_gusmax_mixer
  5. snd_gusmax_free
  6. snd_gusmax_match
  7. snd_gusmax_probe
  8. snd_gusmax_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Driver for Gravis UltraSound MAX soundcard
   4  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   5  */
   6 
   7 #include <linux/init.h>
   8 #include <linux/err.h>
   9 #include <linux/isa.h>
  10 #include <linux/delay.h>
  11 #include <linux/time.h>
  12 #include <linux/module.h>
  13 #include <asm/dma.h>
  14 #include <sound/core.h>
  15 #include <sound/gus.h>
  16 #include <sound/wss.h>
  17 #define SNDRV_LEGACY_FIND_FREE_IRQ
  18 #define SNDRV_LEGACY_FIND_FREE_DMA
  19 #include <sound/initval.h>
  20 
  21 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
  22 MODULE_DESCRIPTION("Gravis UltraSound MAX");
  23 MODULE_LICENSE("GPL");
  24 MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound MAX}}");
  25 
  26 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
  27 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
  28 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
  29 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;     /* 0x220,0x230,0x240,0x250,0x260 */
  30 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;        /* 2,3,5,9,11,12,15 */
  31 static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;       /* 1,3,5,6,7 */
  32 static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;       /* 1,3,5,6,7 */
  33 static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
  34                                 /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
  35 static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
  36 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
  37 
  38 module_param_array(index, int, NULL, 0444);
  39 MODULE_PARM_DESC(index, "Index value for GUS MAX soundcard.");
  40 module_param_array(id, charp, NULL, 0444);
  41 MODULE_PARM_DESC(id, "ID string for GUS MAX soundcard.");
  42 module_param_array(enable, bool, NULL, 0444);
  43 MODULE_PARM_DESC(enable, "Enable GUS MAX soundcard.");
  44 module_param_hw_array(port, long, ioport, NULL, 0444);
  45 MODULE_PARM_DESC(port, "Port # for GUS MAX driver.");
  46 module_param_hw_array(irq, int, irq, NULL, 0444);
  47 MODULE_PARM_DESC(irq, "IRQ # for GUS MAX driver.");
  48 module_param_hw_array(dma1, int, dma, NULL, 0444);
  49 MODULE_PARM_DESC(dma1, "DMA1 # for GUS MAX driver.");
  50 module_param_hw_array(dma2, int, dma, NULL, 0444);
  51 MODULE_PARM_DESC(dma2, "DMA2 # for GUS MAX driver.");
  52 module_param_array(joystick_dac, int, NULL, 0444);
  53 MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS MAX driver.");
  54 module_param_array(channels, int, NULL, 0444);
  55 MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver.");
  56 module_param_array(pcm_channels, int, NULL, 0444);
  57 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
  58 
  59 struct snd_gusmax {
  60         int irq;
  61         struct snd_card *card;
  62         struct snd_gus_card *gus;
  63         struct snd_wss *wss;
  64         unsigned short gus_status_reg;
  65         unsigned short pcm_status_reg;
  66 };
  67 
  68 #define PFX     "gusmax: "
  69 
  70 static int snd_gusmax_detect(struct snd_gus_card *gus)
  71 {
  72         unsigned char d;
  73 
  74         snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);   /* reset GF1 */
  75         if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
  76                 snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
  77                 return -ENODEV;
  78         }
  79         udelay(160);
  80         snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);   /* release reset */
  81         udelay(160);
  82         if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
  83                 snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
  84                 return -ENODEV;
  85         }
  86 
  87         return 0;
  88 }
  89 
  90 static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id)
  91 {
  92         struct snd_gusmax *maxcard = dev_id;
  93         int loop, max = 5;
  94         int handled = 0;
  95 
  96         do {
  97                 loop = 0;
  98                 if (inb(maxcard->gus_status_reg)) {
  99                         handled = 1;
 100                         snd_gus_interrupt(irq, maxcard->gus);
 101                         loop++;
 102                 }
 103                 if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
 104                         handled = 1;
 105                         snd_wss_interrupt(irq, maxcard->wss);
 106                         loop++;
 107                 }
 108         } while (loop && --max > 0);
 109         return IRQ_RETVAL(handled);
 110 }
 111 
 112 static void snd_gusmax_init(int dev, struct snd_card *card,
 113                             struct snd_gus_card *gus)
 114 {
 115         gus->equal_irq = 1;
 116         gus->codec_flag = 1;
 117         gus->joystick_dac = joystick_dac[dev];
 118         /* init control register */
 119         gus->max_cntrl_val = (gus->gf1.port >> 4) & 0x0f;
 120         if (gus->gf1.dma1 > 3)
 121                 gus->max_cntrl_val |= 0x10;
 122         if (gus->gf1.dma2 > 3)
 123                 gus->max_cntrl_val |= 0x20;
 124         gus->max_cntrl_val |= 0x40;
 125         outb(gus->max_cntrl_val, GUSP(gus, MAXCNTRLPORT));
 126 }
 127 
 128 static int snd_gusmax_mixer(struct snd_wss *chip)
 129 {
 130         struct snd_card *card = chip->card;
 131         struct snd_ctl_elem_id id1, id2;
 132         int err;
 133         
 134         memset(&id1, 0, sizeof(id1));
 135         memset(&id2, 0, sizeof(id2));
 136         id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 137         /* reassign AUXA to SYNTHESIZER */
 138         strcpy(id1.name, "Aux Playback Switch");
 139         strcpy(id2.name, "Synth Playback Switch");
 140         if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
 141                 return err;
 142         strcpy(id1.name, "Aux Playback Volume");
 143         strcpy(id2.name, "Synth Playback Volume");
 144         if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
 145                 return err;
 146         /* reassign AUXB to CD */
 147         strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
 148         strcpy(id2.name, "CD Playback Switch");
 149         if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
 150                 return err;
 151         strcpy(id1.name, "Aux Playback Volume");
 152         strcpy(id2.name, "CD Playback Volume");
 153         if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
 154                 return err;
 155 #if 0
 156         /* reassign Mono Input to MIC */
 157         if (snd_mixer_group_rename(mixer,
 158                                 SNDRV_MIXER_IN_MONO, 0,
 159                                 SNDRV_MIXER_IN_MIC, 0) < 0)
 160                 goto __error;
 161         if (snd_mixer_elem_rename(mixer,
 162                                 SNDRV_MIXER_IN_MONO, 0, SNDRV_MIXER_ETYPE_INPUT,
 163                                 SNDRV_MIXER_IN_MIC, 0) < 0)
 164                 goto __error;
 165         if (snd_mixer_elem_rename(mixer,
 166                                 "Mono Capture Volume", 0, SNDRV_MIXER_ETYPE_VOLUME1,
 167                                 "Mic Capture Volume", 0) < 0)
 168                 goto __error;
 169         if (snd_mixer_elem_rename(mixer,
 170                                 "Mono Capture Switch", 0, SNDRV_MIXER_ETYPE_SWITCH1,
 171                                 "Mic Capture Switch", 0) < 0)
 172                 goto __error;
 173 #endif
 174         return 0;
 175 }
 176 
 177 static void snd_gusmax_free(struct snd_card *card)
 178 {
 179         struct snd_gusmax *maxcard = card->private_data;
 180         
 181         if (maxcard == NULL)
 182                 return;
 183         if (maxcard->irq >= 0)
 184                 free_irq(maxcard->irq, (void *)maxcard);
 185 }
 186 
 187 static int snd_gusmax_match(struct device *pdev, unsigned int dev)
 188 {
 189         return enable[dev];
 190 }
 191 
 192 static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
 193 {
 194         static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
 195         static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
 196         int xirq, xdma1, xdma2, err;
 197         struct snd_card *card;
 198         struct snd_gus_card *gus = NULL;
 199         struct snd_wss *wss;
 200         struct snd_gusmax *maxcard;
 201 
 202         err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
 203                            sizeof(struct snd_gusmax), &card);
 204         if (err < 0)
 205                 return err;
 206         card->private_free = snd_gusmax_free;
 207         maxcard = card->private_data;
 208         maxcard->card = card;
 209         maxcard->irq = -1;
 210         
 211         xirq = irq[dev];
 212         if (xirq == SNDRV_AUTO_IRQ) {
 213                 if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
 214                         snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
 215                         err = -EBUSY;
 216                         goto _err;
 217                 }
 218         }
 219         xdma1 = dma1[dev];
 220         if (xdma1 == SNDRV_AUTO_DMA) {
 221                 if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
 222                         snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
 223                         err = -EBUSY;
 224                         goto _err;
 225                 }
 226         }
 227         xdma2 = dma2[dev];
 228         if (xdma2 == SNDRV_AUTO_DMA) {
 229                 if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
 230                         snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
 231                         err = -EBUSY;
 232                         goto _err;
 233                 }
 234         }
 235 
 236         if (port[dev] != SNDRV_AUTO_PORT) {
 237                 err = snd_gus_create(card,
 238                                      port[dev],
 239                                      -xirq, xdma1, xdma2,
 240                                      0, channels[dev],
 241                                      pcm_channels[dev],
 242                                      0, &gus);
 243         } else {
 244                 static unsigned long possible_ports[] = {
 245                         0x220, 0x230, 0x240, 0x250, 0x260
 246                 };
 247                 int i;
 248                 for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
 249                         err = snd_gus_create(card,
 250                                              possible_ports[i],
 251                                              -xirq, xdma1, xdma2,
 252                                              0, channels[dev],
 253                                              pcm_channels[dev],
 254                                              0, &gus);
 255                         if (err >= 0) {
 256                                 port[dev] = possible_ports[i];
 257                                 break;
 258                         }
 259                 }
 260         }
 261         if (err < 0)
 262                 goto _err;
 263 
 264         if ((err = snd_gusmax_detect(gus)) < 0)
 265                 goto _err;
 266 
 267         maxcard->gus_status_reg = gus->gf1.reg_irqstat;
 268         maxcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
 269         snd_gusmax_init(dev, card, gus);
 270         if ((err = snd_gus_initialize(gus)) < 0)
 271                 goto _err;
 272 
 273         if (!gus->max_flag) {
 274                 snd_printk(KERN_ERR PFX "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port);
 275                 err = -ENODEV;
 276                 goto _err;
 277         }
 278 
 279         if (request_irq(xirq, snd_gusmax_interrupt, 0, "GUS MAX", (void *)maxcard)) {
 280                 snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
 281                 err = -EBUSY;
 282                 goto _err;
 283         }
 284         maxcard->irq = xirq;
 285         
 286         err = snd_wss_create(card,
 287                              gus->gf1.port + 0x10c, -1, xirq,
 288                              xdma2 < 0 ? xdma1 : xdma2, xdma1,
 289                              WSS_HW_DETECT,
 290                              WSS_HWSHARE_IRQ |
 291                              WSS_HWSHARE_DMA1 |
 292                              WSS_HWSHARE_DMA2,
 293                              &wss);
 294         if (err < 0)
 295                 goto _err;
 296 
 297         err = snd_wss_pcm(wss, 0);
 298         if (err < 0)
 299                 goto _err;
 300 
 301         err = snd_wss_mixer(wss);
 302         if (err < 0)
 303                 goto _err;
 304 
 305         err = snd_wss_timer(wss, 2);
 306         if (err < 0)
 307                 goto _err;
 308 
 309         if (pcm_channels[dev] > 0) {
 310                 if ((err = snd_gf1_pcm_new(gus, 1, 1)) < 0)
 311                         goto _err;
 312         }
 313         err = snd_gusmax_mixer(wss);
 314         if (err < 0)
 315                 goto _err;
 316 
 317         err = snd_gf1_rawmidi_new(gus, 0);
 318         if (err < 0)
 319                 goto _err;
 320 
 321         sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1);
 322         if (xdma2 >= 0)
 323                 sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
 324 
 325         err = snd_card_register(card);
 326         if (err < 0)
 327                 goto _err;
 328                 
 329         maxcard->gus = gus;
 330         maxcard->wss = wss;
 331 
 332         dev_set_drvdata(pdev, card);
 333         return 0;
 334 
 335  _err:
 336         snd_card_free(card);
 337         return err;
 338 }
 339 
 340 static int snd_gusmax_remove(struct device *devptr, unsigned int dev)
 341 {
 342         snd_card_free(dev_get_drvdata(devptr));
 343         return 0;
 344 }
 345 
 346 #define DEV_NAME "gusmax"
 347 
 348 static struct isa_driver snd_gusmax_driver = {
 349         .match          = snd_gusmax_match,
 350         .probe          = snd_gusmax_probe,
 351         .remove         = snd_gusmax_remove,
 352         /* FIXME: suspend/resume */
 353         .driver         = {
 354                 .name   = DEV_NAME
 355         },
 356 };
 357 
 358 module_isa_driver(snd_gusmax_driver, SNDRV_CARDS);

/* [<][>][^][v][top][bottom][index][help] */