MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("S3 SonicVibes PCI");
MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{S3,SonicVibes PCI}}");
+MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
#ifndef PCI_VENDOR_ID_S3
#define PCI_VENDOR_ID_S3 0x5333
module_param_array(index, int, boot_devs, 0444);
MODULE_PARM_DESC(index, "Index value for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
module_param_array(id, charp, boot_devs, 0444);
MODULE_PARM_DESC(id, "ID string for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
module_param_array(enable, bool, boot_devs, 0444);
MODULE_PARM_DESC(enable, "Enable S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
module_param_array(reverb, bool, boot_devs, 0444);
MODULE_PARM_DESC(reverb, "Enable reverb (SRAM is present) for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(reverb, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
module_param_array(mge, bool, boot_devs, 0444);
MODULE_PARM_DESC(mge, "MIC Gain Enable for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(mge, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
module_param(dmaio, uint, 0444);
MODULE_PARM_DESC(dmaio, "DDMA i/o base address for S3 SonicVibes soundcard.");
-MODULE_PARM_SYNTAX(dmaio, "global," SNDRV_PORT_DESC);
/*
* Enhanced port direct registers
*/
typedef struct _snd_sonicvibes sonicvibes_t;
-#define chip_t sonicvibes_t
struct _snd_sonicvibes {
unsigned long dma1size;
int irq;
unsigned long sb_port;
- struct resource *res_sb_port;
unsigned long enh_port;
- struct resource *res_enh_port;
unsigned long synth_port;
- struct resource *res_synth_port;
unsigned long midi_port;
- struct resource *res_midi_port;
unsigned long game_port;
unsigned int dmaa_port;
struct resource *res_dmaa;
static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, dev_id, return IRQ_NONE);
+ sonicvibes_t *sonic = dev_id;
unsigned char status;
status = inb(SV_REG(sonic, STATUS));
static int snd_sonicvibes_playback_prepare(snd_pcm_substream_t * substream)
{
- unsigned long flags;
sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
unsigned char fmt = 0;
fmt |= 2;
snd_sonicvibes_setfmt(sonic, ~3, fmt);
snd_sonicvibes_set_dac_rate(sonic, runtime->rate);
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
snd_sonicvibes_setdmaa(sonic, runtime->dma_addr, size);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_UPPER, count >> 8);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_A_LOWER, count);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
return 0;
}
static int snd_sonicvibes_capture_prepare(snd_pcm_substream_t * substream)
{
- unsigned long flags;
sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
unsigned char fmt = 0;
fmt |= 0x20;
snd_sonicvibes_setfmt(sonic, ~0x30, fmt);
snd_sonicvibes_set_adc_rate(sonic, runtime->rate);
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
snd_sonicvibes_setdmac(sonic, runtime->dma_addr, size);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_UPPER, count >> 8);
snd_sonicvibes_out1(sonic, SV_IREG_DMA_C_LOWER, count);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
return 0;
}
static void snd_sonicvibes_pcm_free(snd_pcm_t *pcm)
{
- sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, pcm->private_data, return);
+ sonicvibes_t *sonic = pcm->private_data;
sonic->pcm = NULL;
snd_pcm_lib_preallocate_free_for_all(pcm);
}
static int snd_sonicvibes_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
ucontrol->value.enumerated.item[1] = ((snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
return 0;
}
static int snd_sonicvibes_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
unsigned short left, right, oval1, oval2;
int change;
return -EINVAL;
left = (ucontrol->value.enumerated.item[0] + 1) << 5;
right = (ucontrol->value.enumerated.item[1] + 1) << 5;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
oval1 = snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC);
oval2 = snd_sonicvibes_in1(sonic, SV_IREG_RIGHT_ADC);
left = (oval1 & ~SV_RECSRC_OUT) | left;
change = left != oval1 || right != oval2;
snd_sonicvibes_out1(sonic, SV_IREG_LEFT_ADC, left);
snd_sonicvibes_out1(sonic, SV_IREG_RIGHT_ADC, right);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
return change;
}
static int snd_sonicvibes_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, reg)>> shift) & mask;
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
if (invert)
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
return 0;
static int snd_sonicvibes_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
if (invert)
val = mask - val;
val <<= shift;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
oval = snd_sonicvibes_in1(sonic, reg);
val = (oval & ~(mask << shift)) | val;
change = val != oval;
snd_sonicvibes_out1(sonic, reg, val);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
return change;
}
static int snd_sonicvibes_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
ucontrol->value.integer.value[0] = (snd_sonicvibes_in1(sonic, left_reg) >> shift_left) & mask;
ucontrol->value.integer.value[1] = (snd_sonicvibes_in1(sonic, right_reg) >> shift_right) & mask;
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
if (invert) {
ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
static int snd_sonicvibes_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
- unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int shift_left = (kcontrol->private_value >> 16) & 0x07;
}
val1 <<= shift_left;
val2 <<= shift_right;
- spin_lock_irqsave(&sonic->reg_lock, flags);
+ spin_lock_irq(&sonic->reg_lock);
oval1 = snd_sonicvibes_in1(sonic, left_reg);
oval2 = snd_sonicvibes_in1(sonic, right_reg);
val1 = (oval1 & ~(mask << shift_left)) | val1;
change = val1 != oval1 || val2 != oval2;
snd_sonicvibes_out1(sonic, left_reg, val1);
snd_sonicvibes_out1(sonic, right_reg, val2);
- spin_unlock_irqrestore(&sonic->reg_lock, flags);
+ spin_unlock_irq(&sonic->reg_lock);
return change;
}
-#define SONICVIBES_CONTROLS (sizeof(snd_sonicvibes_controls)/sizeof(snd_kcontrol_new_t))
-
static snd_kcontrol_new_t snd_sonicvibes_controls[] __devinitdata = {
SONICVIBES_DOUBLE("Capture Volume", 0, SV_IREG_LEFT_ADC, SV_IREG_RIGHT_ADC, 0, 0, 15, 0),
SONICVIBES_DOUBLE("Aux Playback Switch", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 7, 7, 1, 1),
static void snd_sonicvibes_master_free(snd_kcontrol_t *kcontrol)
{
- sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, _snd_kcontrol_chip(kcontrol), return);
+ sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
sonic->master_mute = NULL;
sonic->master_volume = NULL;
}
card = sonic->card;
strcpy(card->mixername, "S3 SonicVibes");
- for (idx = 0; idx < SONICVIBES_CONTROLS; idx++) {
+ for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_controls); idx++) {
if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_sonicvibes_controls[idx], sonic))) < 0)
return err;
switch (idx) {
static void snd_sonicvibes_proc_read(snd_info_entry_t *entry,
snd_info_buffer_t * buffer)
{
- sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, entry->private_data, return);
+ sonicvibes_t *sonic = entry->private_data;
unsigned char tmp;
tmp = sonic->srs_space & 0x0f;
#endif
pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
- if (sonic->res_sb_port) {
- release_resource(sonic->res_sb_port);
- kfree_nocheck(sonic->res_sb_port);
- }
- if (sonic->res_enh_port) {
- release_resource(sonic->res_enh_port);
- kfree_nocheck(sonic->res_enh_port);
- }
- if (sonic->res_synth_port) {
- release_resource(sonic->res_synth_port);
- kfree_nocheck(sonic->res_synth_port);
- }
- if (sonic->res_midi_port) {
- release_resource(sonic->res_midi_port);
- kfree_nocheck(sonic->res_midi_port);
- }
+ if (sonic->irq >= 0)
+ free_irq(sonic->irq, (void *)sonic);
if (sonic->res_dmaa) {
release_resource(sonic->res_dmaa);
kfree_nocheck(sonic->res_dmaa);
release_resource(sonic->res_dmac);
kfree_nocheck(sonic->res_dmac);
}
- if (sonic->irq >= 0)
- free_irq(sonic->irq, (void *)sonic);
- snd_magic_kfree(sonic);
+ pci_release_regions(sonic->pci);
+ kfree(sonic);
return 0;
}
static int snd_sonicvibes_dev_free(snd_device_t *device)
{
- sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, device->device_data, return -ENXIO);
+ sonicvibes_t *sonic = device->device_data;
return snd_sonicvibes_free(sonic);
}
return -ENXIO;
}
- sonic = snd_magic_kcalloc(sonicvibes_t, 0, GFP_KERNEL);
+ sonic = kcalloc(1, sizeof(*sonic), GFP_KERNEL);
if (sonic == NULL)
return -ENOMEM;
spin_lock_init(&sonic->reg_lock);
sonic->card = card;
sonic->pci = pci;
sonic->irq = -1;
- sonic->sb_port = pci_resource_start(pci, 0);
- if ((sonic->res_sb_port = request_region(sonic->sb_port, 0x10, "S3 SonicVibes SB")) == NULL) {
- snd_printk("unable to grab SB port at 0x%lx-0x%lx\n", sonic->sb_port, sonic->sb_port + 0x10 - 1);
- snd_sonicvibes_free(sonic);
- return -EBUSY;
+
+ if ((err = pci_request_regions(pci, "S3 SonicVibes")) < 0) {
+ kfree(sonic);
+ return err;
}
+
+ sonic->sb_port = pci_resource_start(pci, 0);
sonic->enh_port = pci_resource_start(pci, 1);
- if ((sonic->res_enh_port = request_region(sonic->enh_port, 0x10, "S3 SonicVibes Enhanced")) == NULL) {
- snd_printk("unable to grab PCM port at 0x%lx-0x%lx\n", sonic->enh_port, sonic->enh_port + 0x10 - 1);
- snd_sonicvibes_free(sonic);
- return -EBUSY;
- }
sonic->synth_port = pci_resource_start(pci, 2);
- if ((sonic->res_synth_port = request_region(sonic->synth_port, 4, "S3 SonicVibes Synth")) == NULL) {
- snd_printk("unable to grab synth port at 0x%lx-0x%lx\n", sonic->synth_port, sonic->synth_port + 4 - 1);
- snd_sonicvibes_free(sonic);
- return -EBUSY;
- }
sonic->midi_port = pci_resource_start(pci, 3);
- if ((sonic->res_midi_port = request_region(sonic->midi_port, 4, "S3 SonicVibes Midi")) == NULL) {
- snd_printk("unable to grab MIDI port at 0x%lx-0x%lx\n", sonic->midi_port, sonic->midi_port + 4 - 1);
- snd_sonicvibes_free(sonic);
- return -EBUSY;
- }
sonic->game_port = pci_resource_start(pci, 4);
+
if (request_irq(pci->irq, snd_sonicvibes_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", (void *)sonic)) {
snd_printk("unable to grab IRQ %d\n", pci->irq);
snd_sonicvibes_free(sonic);
* MIDI section
*/
-#define SONICVIBES_MIDI_CONTROLS (sizeof(snd_sonicvibes_midi_controls)/sizeof(snd_kcontrol_new_t))
-
static snd_kcontrol_new_t snd_sonicvibes_midi_controls[] __devinitdata = {
SONICVIBES_SINGLE("SonicVibes Wave Source RAM", 0, SV_IREG_WAVE_SOURCE, 0, 1, 0),
SONICVIBES_SINGLE("SonicVibes Wave Source RAM+ROM", 0, SV_IREG_WAVE_SOURCE, 1, 1, 0),
static int snd_sonicvibes_midi_input_open(mpu401_t * mpu)
{
- sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, mpu->private_data, return -EIO);
+ sonicvibes_t *sonic = mpu->private_data;
outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
return 0;
}
static void snd_sonicvibes_midi_input_close(mpu401_t * mpu)
{
- sonicvibes_t *sonic = snd_magic_cast(sonicvibes_t, mpu->private_data, return);
+ sonicvibes_t *sonic = mpu->private_data;
outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
}
static int __devinit snd_sonicvibes_midi(sonicvibes_t * sonic, snd_rawmidi_t * rmidi)
{
- mpu401_t * mpu = snd_magic_cast(mpu401_t, rmidi->private_data, return -ENXIO);
+ mpu401_t * mpu = rmidi->private_data;
snd_card_t *card = sonic->card;
snd_rawmidi_str_t *dir;
unsigned int idx;
mpu->open_input = snd_sonicvibes_midi_input_open;
mpu->close_input = snd_sonicvibes_midi_input_close;
dir = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
- for (idx = 0; idx < SONICVIBES_MIDI_CONTROLS; idx++)
+ for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++)
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic))) < 0)
return err;
return 0;