1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for Gravis UltraSound MAX soundcard
4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
7 #include <linux/init.h>
10 #include <linux/delay.h>
11 #include <linux/time.h>
12 #include <linux/module.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>
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}}");
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};
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.");
61 struct snd_card
*card
;
62 struct snd_gus_card
*gus
;
64 unsigned short gus_status_reg
;
65 unsigned short pcm_status_reg
;
68 #define PFX "gusmax: "
70 static int snd_gusmax_detect(struct snd_gus_card
*gus
)
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
);
80 snd_gf1_i_write8(gus
, SNDRV_GF1_GB_RESET
, 1); /* release reset */
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
);
90 static irqreturn_t
snd_gusmax_interrupt(int irq
, void *dev_id
)
92 struct snd_gusmax
*maxcard
= dev_id
;
98 if (inb(maxcard
->gus_status_reg
)) {
100 snd_gus_interrupt(irq
, maxcard
->gus
);
103 if (inb(maxcard
->pcm_status_reg
) & 0x01) { /* IRQ bit is set? */
105 snd_wss_interrupt(irq
, maxcard
->wss
);
108 } while (loop
&& --max
> 0);
109 return IRQ_RETVAL(handled
);
112 static void snd_gusmax_init(int dev
, struct snd_card
*card
,
113 struct snd_gus_card
*gus
)
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
));
128 static int snd_gusmax_mixer(struct snd_wss
*chip
)
130 struct snd_card
*card
= chip
->card
;
131 struct snd_ctl_elem_id id1
, id2
;
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)
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)
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)
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)
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)
161 if (snd_mixer_elem_rename(mixer
,
162 SNDRV_MIXER_IN_MONO
, 0, SNDRV_MIXER_ETYPE_INPUT
,
163 SNDRV_MIXER_IN_MIC
, 0) < 0)
165 if (snd_mixer_elem_rename(mixer
,
166 "Mono Capture Volume", 0, SNDRV_MIXER_ETYPE_VOLUME1
,
167 "Mic Capture Volume", 0) < 0)
169 if (snd_mixer_elem_rename(mixer
,
170 "Mono Capture Switch", 0, SNDRV_MIXER_ETYPE_SWITCH1
,
171 "Mic Capture Switch", 0) < 0)
177 static void snd_gusmax_free(struct snd_card
*card
)
179 struct snd_gusmax
*maxcard
= card
->private_data
;
183 if (maxcard
->irq
>= 0)
184 free_irq(maxcard
->irq
, (void *)maxcard
);
187 static int snd_gusmax_match(struct device
*pdev
, unsigned int dev
)
192 static int snd_gusmax_probe(struct device
*pdev
, unsigned int dev
)
194 static const int possible_irqs
[] = {5, 11, 12, 9, 7, 15, 3, -1};
195 static const 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
;
200 struct snd_gusmax
*maxcard
;
202 err
= snd_card_new(pdev
, index
[dev
], id
[dev
], THIS_MODULE
,
203 sizeof(struct snd_gusmax
), &card
);
206 card
->private_free
= snd_gusmax_free
;
207 maxcard
= card
->private_data
;
208 maxcard
->card
= card
;
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");
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");
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");
236 if (port
[dev
] != SNDRV_AUTO_PORT
) {
237 err
= snd_gus_create(card
,
244 static const unsigned long possible_ports
[] = {
245 0x220, 0x230, 0x240, 0x250, 0x260
248 for (i
= 0; i
< ARRAY_SIZE(possible_ports
); i
++) {
249 err
= snd_gus_create(card
,
256 port
[dev
] = possible_ports
[i
];
264 if ((err
= snd_gusmax_detect(gus
)) < 0)
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)
273 if (!gus
->max_flag
) {
274 snd_printk(KERN_ERR PFX
"GUS MAX soundcard was not detected at 0x%lx\n", gus
->gf1
.port
);
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
);
285 card
->sync_irq
= maxcard
->irq
;
287 err
= snd_wss_create(card
,
288 gus
->gf1
.port
+ 0x10c, -1, xirq
,
289 xdma2
< 0 ? xdma1
: xdma2
, xdma1
,
298 err
= snd_wss_pcm(wss
, 0);
302 err
= snd_wss_mixer(wss
);
306 err
= snd_wss_timer(wss
, 2);
310 if (pcm_channels
[dev
] > 0) {
311 if ((err
= snd_gf1_pcm_new(gus
, 1, 1)) < 0)
314 err
= snd_gusmax_mixer(wss
);
318 err
= snd_gf1_rawmidi_new(gus
, 0);
322 sprintf(card
->longname
+ strlen(card
->longname
), " at 0x%lx, irq %i, dma %i", gus
->gf1
.port
, xirq
, xdma1
);
324 sprintf(card
->longname
+ strlen(card
->longname
), "&%i", xdma2
);
326 err
= snd_card_register(card
);
333 dev_set_drvdata(pdev
, card
);
341 static int snd_gusmax_remove(struct device
*devptr
, unsigned int dev
)
343 snd_card_free(dev_get_drvdata(devptr
));
347 #define DEV_NAME "gusmax"
349 static struct isa_driver snd_gusmax_driver
= {
350 .match
= snd_gusmax_match
,
351 .probe
= snd_gusmax_probe
,
352 .remove
= snd_gusmax_remove
,
353 /* FIXME: suspend/resume */
359 module_isa_driver(snd_gusmax_driver
, SNDRV_CARDS
);