diff options
| author | Linus Torvalds <torvalds@home.osdl.org> | 2003-08-20 21:58:51 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-08-20 21:58:51 -0700 |
| commit | c68e9daadc70f34cb2d4cd46524f902e262dbc74 (patch) | |
| tree | 71c3da42e55bf8a386a5cc60e1cef29f7ab7d08b | |
| parent | bf4a3963a5a87aa42cdc9dd99e1c73bc80390d3a (diff) | |
| parent | dbc7be6c02344928e331e058d0107cc60007e87a (diff) | |
Merge http://linux-sound.bkbits.net/linux-sound
into home.osdl.org:/home/torvalds/v2.5/linux
35 files changed, 507 insertions, 443 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 628e1d1716df..d3b5d2793175 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1033,6 +1033,7 @@ Module parameters Module for Digigram VX-Pocket VX222, V222 v2 and Mic cards. mic - Enable Microphone on V222 Mic (NYI) + ibl - Capture IBL size. (default = 0, minimum size) Module supports up to 8 cards. @@ -1042,12 +1043,21 @@ Module parameters post-install snd-vx222 "/usr/bin/vxload" + IBL size defines the interrupts period for PCM. The smaller size + gives smaller latency but leads to more CPU consumption, too. + The size is usually aligned to 126. As default (=0), the smallest + size is chosen. The possible IBL values can be found in + /proc/asound/cardX/vx-status proc file. + Module snd-vxpocket ------------------- Module for Digigram VX-Pocket VX2 PCMCIA card. irq_mask - IRQ bitmask, specifies the available IRQs as bits + (default = 0xffff, all available) + irq_list - List of available interrupts (default = -1, not specified) + ibl - Capture IBL size. (default = 0, minimum size) Module supports up to 8 cards. The module is compiled only when PCMCIA is supported on kernel. @@ -1058,12 +1068,19 @@ Module parameters For loading the firmware, use vxloader utility in alsa-tools package. + The irq_mask and irq_list are provided to avoid allocation of + specific IRQs. Usually you don't need to specify them. + + About capture IBL, see the description of snd-vx222 module. + Module snd-vxp440 ----------------- Module for Digigram VX-Pocket 440 PCMCIA card. irq_mask - IRQ bitmask, specifies the available IRQs as bits + irq_list - List of available interrupts (default = -1, not specified) + ibl - Capture IBL size. (default = 0, minimum size) Module supports up to 8 cards. The module is compiled only when PCMCIA is supported on kernel. @@ -1074,6 +1091,11 @@ Module parameters For loading the firmware, use vxloader utility in alsa-tools package. + The irq_mask and irq_list are provided to avoid allocation of + specific IRQs. Usually you don't need to specify them. + + About capture IBL, see the description of snd-vx222 module. + Module snd-ymfpci ----------------- diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index 7a8f7fc66106..c2c3d8d7b4b4 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -438,7 +438,7 @@ // chip-specific constructor // (see "Management of Cards and Components") static int __devinit snd_mychip_create(snd_card_t *card, - struct pci_device *pci, + struct pci_dev *pci, mychip_t **rchip) { mychip_t *chip; @@ -1340,7 +1340,7 @@ } // PCI IDs - static struct pci_device_id snd_mychip_ids[] __devinitdata = { + static struct pci_device_id snd_mychip_ids[] = { { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, .... @@ -1718,7 +1718,7 @@ <informalexample> <programlisting> <![CDATA[ - static struct pci_device_id snd_mychip_ids[] __devinitdata = { + static struct pci_device_id snd_mychip_ids[] = { { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, .... @@ -1915,7 +1915,7 @@ }; /* open callback */ - static int snd_mychip_pcm_open(snd_pcm_substream_t *subs) + static int snd_mychip_pcm_open(snd_pcm_substream_t *substream) { mychip_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; @@ -2716,7 +2716,7 @@ struct _snd_pcm_runtime { <informalexample> <programlisting> <![CDATA[ - static int snd_xxx_open(snd_pcm_substream_t *subs); + static int snd_xxx_open(snd_pcm_substream_t *substream); ]]> </programlisting> </informalexample> @@ -2767,7 +2767,7 @@ struct _snd_pcm_runtime { <informalexample> <programlisting> <![CDATA[ - static int snd_xxx_close(snd_pcm_substream_t *subs); + static int snd_xxx_close(snd_pcm_substream_t *substream); ]]> </programlisting> </informalexample> diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index ef96513330df..e41e774307ee 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h @@ -345,13 +345,20 @@ void snd_ac97_suspend(ac97_t *ac97); void snd_ac97_resume(ac97_t *ac97); #endif -enum { AC97_TUNE_HP_ONLY, AC97_TUNE_SWAP_HP, AC97_TUNE_SWAP_SURROUND }; +/* quirk types */ +enum { + AC97_TUNE_HP_ONLY, /* headphone (true line-out) control as master only */ + AC97_TUNE_SWAP_HP, /* swap headphone and master controls */ + AC97_TUNE_SWAP_SURROUND, /* swap master and surround controls */ + AC97_TUNE_AD_SHARING /* for AD1985, turn on OMS bit and use headphone */ +}; struct ac97_quirk { - unsigned short vendor; - unsigned short device; - const char *name; - int type; + unsigned short vendor; /* PCI vendor id */ + unsigned short device; /* PCI device id */ + unsigned short mask; /* device id bit mask, 0 = accept all */ + const char *name; /* name shown as info */ + int type; /* quirk type above */ }; int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk); diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 0babb7dce20f..1fbd9f3fa82b 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -852,7 +852,7 @@ typedef struct { unsigned int value[32]; unsigned int min; /* minimum range */ unsigned int max; /* maximum range */ - unsigned int translation; /* translation type (EMU10K1_GRP_TRANSLATION*) */ + unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ snd_kcontrol_t *kcontrol; } snd_emu10k1_fx8010_ctl_t; @@ -1282,8 +1282,8 @@ typedef struct { #define EMU10K1_GPR_TRANSLATION_NONE 0 #define EMU10K1_GPR_TRANSLATION_TABLE100 1 -#define EMU10K1_GRP_TRANSLATION_BASS 2 -#define EMU10K1_GRP_TRANSLATION_TREBLE 3 +#define EMU10K1_GPR_TRANSLATION_BASS 2 +#define EMU10K1_GPR_TRANSLATION_TREBLE 3 #define EMU10K1_GPR_TRANSLATION_ONOFF 4 typedef struct { @@ -1294,7 +1294,7 @@ typedef struct { unsigned int value[32]; /* initial values */ unsigned int min; /* minimum range */ unsigned int max; /* maximum range */ - unsigned int translation; /* translation type (EMU10K1_GRP_TRANSLATION*) */ + unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ } emu10k1_fx8010_control_gpr_t; typedef struct { diff --git a/include/sound/version.h b/include/sound/version.h index 7a720532c1b7..51f4968670a9 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by configure. */ #define CONFIG_SND_VERSION "0.9.6" -#define CONFIG_SND_DATE " (Mon Jul 28 11:08:42 2003 UTC)" +#define CONFIG_SND_DATE " (Wed Aug 20 20:27:13 2003 UTC)" diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c index 445bb99e2b8e..43c84393dc00 100644 --- a/sound/arm/sa11xx-uda1341.c +++ b/sound/arm/sa11xx-uda1341.c @@ -21,7 +21,7 @@ * merged HAL layer (patches from Brian) */ -/* $Id: sa11xx-uda1341.c,v 1.11 2003/04/30 14:53:11 perex Exp $ */ +/* $Id: sa11xx-uda1341.c,v 1.12 2003/08/13 13:14:31 tiwai Exp $ */ /*************************************************************************************************** * @@ -965,6 +965,8 @@ static int __init sa11xx_uda1341_init(void) sa11xx_uda1341 = snd_magic_kcalloc(sa11xx_uda1341_t, 0, GFP_KERNEL); if (sa11xx_uda1341 == NULL) return -ENOMEM; + spin_lock_init(&chip->s[0].dma_lock); + spin_lock_init(&chip->s[1].dma_lock); card->private_data = (void *)sa11xx_uda1341; card->private_free = snd_sa11xx_uda1341_free; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 257ad284120f..50ffd13db2a8 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1614,8 +1614,12 @@ static int snd_pcm_oss_open_file(struct file *file, if ((f_mode & FMODE_READ) && !(csetup && csetup->disable)) { if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_CAPTURE, &csubstream)) < 0) { - snd_pcm_oss_release_file(pcm_oss_file); - return err; + if (!(f_mode & FMODE_WRITE) || err != -ENODEV) { + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } else { + csubstream = NULL; + } } pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE] = csubstream; } diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 5da5c1bc004f..098e652eec59 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -923,47 +923,6 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offs return 0; } -int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset, - unsigned int channels, snd_pcm_uframes_t frames, int format) -{ - int width = snd_pcm_format_physical_width(format); - while (channels > 0) { - void *addr = dst_areas->addr; - unsigned int step = dst_areas->step; - const snd_pcm_channel_area_t *begin = dst_areas; - int vc = channels; - unsigned int v = 0; - int err; - while (1) { - vc--; - v++; - dst_areas++; - if (vc == 0 || - dst_areas->addr != addr || - dst_areas->step != step || - dst_areas->first != dst_areas[-1].first + width) - break; - } - if (v > 1 && v * width == step) { - /* Collapse the areas */ - snd_pcm_channel_area_t d; - d.addr = begin->addr; - d.first = begin->first; - d.step = width; - err = snd_pcm_area_silence(&d, dst_offset * v, frames * v, format); - channels -= v; - } else { - err = snd_pcm_area_silence(begin, dst_offset, frames, format); - dst_areas = begin + 1; - channels--; - } - if (err < 0) - return err; - } - return 0; -} - - int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset, const snd_pcm_channel_area_t *dst_area, size_t dst_offset, size_t samples, int format) @@ -1058,50 +1017,3 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset, } return 0; } - -int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_areas, snd_pcm_uframes_t src_offset, - const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_t dst_offset, - unsigned int channels, snd_pcm_uframes_t frames, int format) -{ - int width = snd_pcm_format_physical_width(format); - while (channels > 0) { - unsigned int step = src_areas->step; - void *src_addr = src_areas->addr; - const snd_pcm_channel_area_t *src_start = src_areas; - void *dst_addr = dst_areas->addr; - const snd_pcm_channel_area_t *dst_start = dst_areas; - int vc = channels; - unsigned int v = 0; - while (dst_areas->step == step) { - vc--; - v++; - src_areas++; - dst_areas++; - if (vc == 0 || - src_areas->step != step || - src_areas->addr != src_addr || - dst_areas->addr != dst_addr || - src_areas->first != src_areas[-1].first + width || - dst_areas->first != dst_areas[-1].first + width) - break; - } - if (v > 1 && v * width == step) { - /* Collapse the areas */ - snd_pcm_channel_area_t s, d; - s.addr = src_start->addr; - s.first = src_start->first; - s.step = width; - d.addr = dst_start->addr; - d.first = dst_start->first; - d.step = width; - snd_pcm_area_copy(&s, src_offset * v, &d, dst_offset * v, frames * v, format); - channels -= v; - } else { - snd_pcm_area_copy(src_start, src_offset, dst_start, dst_offset, frames, format); - src_areas = src_start + 1; - dst_areas = dst_start + 1; - channels--; - } - } - return 0; -} diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h index e010af47992f..94db5495ea2d 100644 --- a/sound/core/oss/pcm_plugin.h +++ b/sound/core/oss/pcm_plugin.h @@ -219,14 +219,9 @@ snd_pcm_sframes_t snd_pcm_plugin_client_channels(snd_pcm_plugin_t *plugin, int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset, size_t samples, int format); -int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, - unsigned int channels, snd_pcm_uframes_t frames, int format); int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, size_t src_offset, const snd_pcm_channel_area_t *dst_channel, size_t dst_offset, size_t samples, int format); -int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset, - const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, - unsigned int channels, snd_pcm_uframes_t frames, int format); void *snd_pcm_plug_buf_alloc(snd_pcm_plug_t *plug, snd_pcm_uframes_t size); void snd_pcm_plug_buf_unlock(snd_pcm_plug_t *plug, void *ptr); diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 4667d5345831..6a7fdc053325 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c @@ -189,8 +189,8 @@ static int __init snd_gusclassic_probe(int dev) return err; } if (gus->max_flag || gus->ess_flag) { - snd_card_free(card); snd_printdd("GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port); + snd_card_free(card); return -ENODEV; } if ((err = snd_gf1_new_mixer(gus)) < 0) { diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 1cf25700fab4..f9887f802a8a 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -284,8 +284,8 @@ static int __init snd_gusextreme_probe(int dev) return err; } if (!gus->ess_flag) { - snd_card_free(card); snd_printdd("GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port); + snd_card_free(card); return -ENODEV; } if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0) { diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index 11a85a6154e8..c300a736b5a9 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -293,8 +293,8 @@ static int __init snd_gusmax_probe(int dev) return err; } if (!gus->max_flag) { - snd_card_free(card); printk(KERN_ERR "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port); + snd_card_free(card); return -ENODEV; } diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index c4ce19389449..c857cca5d22f 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -103,7 +103,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { { 0x41445370, 0xffffffff, "AD1980", patch_ad1980, NULL }, { 0x41445372, 0xffffffff, "AD1981A", patch_ad1881, NULL }, { 0x41445374, 0xffffffff, "AD1981B", patch_ad1881, NULL }, -{ 0x41445375, 0xffffffff, "AD1985", patch_ad1980, NULL }, +{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL }, { 0x414c4300, 0xfffffff0, "RL5306", NULL, NULL }, { 0x414c4310, 0xfffffff0, "RL5382", NULL, NULL }, { 0x414c4320, 0xfffffff0, "RL5383", NULL, NULL }, @@ -823,7 +823,13 @@ static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT, v); } else { + unsigned short extst = ac97->regs[AC97_EXTENDED_STATUS]; + snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */ + change |= snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val); + if (extst & AC97_EA_SPDIF) { + snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ + } } return change; @@ -2235,6 +2241,14 @@ static int swap_surround(ac97_t *ac97) return 0; } +static int tune_ad_sharing(ac97_t *ac97) +{ + unsigned short scfg; + /* Turn on OMS bit to route microphone to back panel */ + scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG); + snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x0200); + return swap_headphone(ac97, 1); +} /** * snd_ac97_tune_hardware - tune up the hardware @@ -2253,7 +2267,10 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk) snd_assert(quirk, return -EINVAL); for (; quirk->vendor; quirk++) { - if (quirk->vendor == ac97->subsystem_vendor && quirk->device == ac97->subsystem_device) { + if (quirk->vendor != ac97->subsystem_vendor) + continue; + if ((! quirk->mask && quirk->device == ac97->subsystem_device) || + quirk->device == (quirk->mask & ac97->subsystem_device)) { snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device); switch (quirk->type) { case AC97_TUNE_HP_ONLY: @@ -2262,6 +2279,8 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk) return swap_headphone(ac97, 0); case AC97_TUNE_SWAP_SURROUND: return swap_surround(ac97); + case AC97_TUNE_AD_SHARING: + return tune_ad_sharing(ac97); } snd_printk(KERN_ERR "invalid quirk type %d for %s\n", quirk->type, quirk->name); return -EINVAL; diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index ebd7c1f35d7c..ac63b96095d1 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -759,6 +759,19 @@ int patch_ad1980(ac97_t * ac97) return 0; } +int patch_ad1985(ac97_t * ac97) +{ + unsigned short misc; + + patch_ad1881(ac97); + ac97->build_ops = &patch_ad1980_build_ops; + misc = snd_ac97_read(ac97, AC97_AD_MISC); + /* switch front/surround line-out/hp-out */ + /* center/LFE, surround in High-Z mode */ + snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | 0x1c28); + return 0; +} + static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0), AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0), diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index c517c44b5c18..6a10ff352851 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h @@ -42,6 +42,7 @@ int patch_ad1881(ac97_t * ac97); int patch_ad1885(ac97_t * ac97); int patch_ad1886(ac97_t * ac97); int patch_ad1980(ac97_t * ac97); +int patch_ad1985(ac97_t * ac97); int patch_alc650(ac97_t * ac97); int patch_cm9738(ac97_t * ac97); int patch_cm9739(ac97_t * ac97); diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index d32b450dabd0..a28d98454bdd 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1347,38 +1347,38 @@ static int __devinit snd_azf3328_create(snd_card_t * card, chip->codec_port = pci_resource_start(pci, 0); if ((chip->res_codec_port = request_region(chip->codec_port, 0x80, "Aztech AZF3328 I/O")) == NULL) { - snd_azf3328_free(chip); snd_printk("unable to grab I/O port at 0x%lx-0x%lx\n", chip->codec_port, chip->codec_port + 0x80 - 1); + snd_azf3328_free(chip); return -EBUSY; } chip->io2_port = pci_resource_start(pci, 1); if ((chip->res_io2_port = request_region(chip->io2_port, 0x08, "Aztech AZF3328 I/O 2")) == NULL) { - snd_azf3328_free(chip); snd_printk("unable to grab I/O 2 port at 0x%lx-0x%lx\n", chip->io2_port, chip->io2_port + 0x08 - 1); + snd_azf3328_free(chip); return -EBUSY; } chip->mpu_port = pci_resource_start(pci, 2); if ((chip->res_mpu_port = request_region(chip->mpu_port, 0x04, "Aztech AZF3328 MPU401")) == NULL) { - snd_azf3328_free(chip); snd_printk("unable to grab MPU401 port at 0x%lx-0x%lx\n", chip->mpu_port, chip->mpu_port + 0x04 - 1); + snd_azf3328_free(chip); return -EBUSY; } chip->synth_port = pci_resource_start(pci, 3); if ((chip->res_synth_port = request_region(chip->synth_port, 0x08, "Aztech AZF3328 OPL3")) == NULL) { - snd_azf3328_free(chip); snd_printk("unable to grab OPL3 port at 0x%lx-0x%lx\n", chip->synth_port, chip->synth_port + 0x08 - 1); + snd_azf3328_free(chip); return -EBUSY; } chip->mixer_port = pci_resource_start(pci, 4); if ((chip->res_mixer_port = request_region(chip->mixer_port, 0x40, "Aztech AZF3328 Mixer")) == NULL) { - snd_azf3328_free(chip); snd_printk("unable to grab mixer port at 0x%lx-0x%lx\n", chip->mixer_port, chip->mixer_port + 0x40 - 1); + snd_azf3328_free(chip); return -EBUSY; } if (request_irq(pci->irq, snd_azf3328_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) { - snd_azf3328_free(chip); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_azf3328_free(chip); return -EBUSY; } chip->irq = pci->irq; @@ -1499,8 +1499,8 @@ static int __devinit snd_azf3328_probe(struct pci_dev *pci, if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401, chip->mpu_port, 1, pci->irq, 0, &chip->rmidi)) < 0) { - snd_card_free(card); snd_printk("azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port); + snd_card_free(card); return err; } diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 0b2709596814..facc28d16e38 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -1439,18 +1439,18 @@ static int __devinit snd_cs4281_create(snd_card_t * card, chip->dual_codec = dual_codec; if ((chip->ba0_res = request_mem_region(chip->ba0_addr, CS4281_BA0_SIZE, "CS4281 BA0")) == NULL) { - snd_cs4281_free(chip); snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->ba0_addr, chip->ba0_addr + CS4281_BA0_SIZE - 1); + snd_cs4281_free(chip); return -ENOMEM; } if ((chip->ba1_res = request_mem_region(chip->ba1_addr, CS4281_BA1_SIZE, "CS4281 BA1")) == NULL) { - snd_cs4281_free(chip); snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->ba1_addr, chip->ba1_addr + CS4281_BA1_SIZE - 1); + snd_cs4281_free(chip); return -ENOMEM; } if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS4281", (void *)chip)) { - snd_cs4281_free(chip); snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + snd_cs4281_free(chip); return -ENOMEM; } chip->irq = pci->irq; diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 4954fd2ea911..f48464c28de3 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -3887,8 +3887,8 @@ int __devinit snd_cs46xx_create(snd_card_t * card, chip->ba1_addr = pci_resource_start(pci, 1); if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { - snd_cs46xx_free(chip); snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr); + snd_cs46xx_free(chip); return -ENOMEM; } diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index d2683e849da0..c038e776f6c9 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -364,12 +364,12 @@ static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value case EMU10K1_GPR_TRANSLATION_TABLE100: snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]); break; - case EMU10K1_GRP_TRANSLATION_BASS: + case EMU10K1_GPR_TRANSLATION_BASS: snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error); for (j = 0; j < 5; j++) snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]); break; - case EMU10K1_GRP_TRANSLATION_TREBLE: + case EMU10K1_GPR_TRANSLATION_TREBLE: snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error); for (j = 0; j < 5; j++) snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]); @@ -1434,7 +1434,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) ctl->min = 0; ctl->max = 40; ctl->value[0] = ctl->value[1] = 20; - ctl->translation = EMU10K1_GRP_TRANSLATION_BASS; + ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; ctl = &controls[nctl + 1]; ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; strcpy(ctl->id.name, "Tone Control - Treble"); @@ -1443,7 +1443,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) ctl->min = 0; ctl->max = 40; ctl->value[0] = ctl->value[1] = 20; - ctl->translation = EMU10K1_GRP_TRANSLATION_TREBLE; + ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; #define BASS_GPR 0x8c #define TREBLE_GPR 0x96 @@ -1946,7 +1946,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) ctl->min = 0; ctl->max = 40; ctl->value[0] = ctl->value[1] = 20; - ctl->translation = EMU10K1_GRP_TRANSLATION_BASS; + ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; ctl = &controls[i + 1]; ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; strcpy(ctl->id.name, "Tone Control - Treble"); @@ -1955,7 +1955,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) ctl->min = 0; ctl->max = 40; ctl->value[0] = ctl->value[1] = 20; - ctl->translation = EMU10K1_GRP_TRANSLATION_TREBLE; + ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; #define BASS_GPR 0x8c #define TREBLE_GPR 0x96 diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index bb34b31bc41e..2a779b11de52 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -1902,20 +1902,20 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, ensoniq->irq = -1; ensoniq->port = pci_resource_start(pci, 0); if ((ensoniq->res_port = request_region(ensoniq->port, 0x40, "Ensoniq AudioPCI")) == NULL) { - snd_ensoniq_free(ensoniq); snd_printk("unable to grab ports 0x%lx-0x%lx\n", ensoniq->port, ensoniq->port + 0x40 - 1); + snd_ensoniq_free(ensoniq); return -EBUSY; } if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) { - snd_ensoniq_free(ensoniq); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_ensoniq_free(ensoniq); return -EBUSY; } ensoniq->irq = pci->irq; #ifdef CHIP1370 if ((ensoniq->bugbuf = snd_malloc_pci_pages(pci, 16, &ensoniq->bugbuf_addr)) == NULL) { - snd_ensoniq_free(ensoniq); snd_printk("unable to allocate space for phantom area - bugbuf\n"); + snd_ensoniq_free(ensoniq); return -EBUSY; } #endif diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 1b83b1c2fe2f..5811228c6fdf 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1413,37 +1413,37 @@ static int __devinit snd_es1938_create(snd_card_t * card, chip->pci = pci; chip->io_port = pci_resource_start(pci, 0); if ((chip->res_io_port = request_region(chip->io_port, 8, "ESS Solo-1")) == NULL) { - snd_es1938_free(chip); snd_printk("unable to grab region 0x%lx-0x%lx\n", chip->io_port, chip->io_port + 8 - 1); + snd_es1938_free(chip); return -EBUSY; } chip->sb_port = pci_resource_start(pci, 1); if ((chip->res_sb_port = request_region(chip->sb_port, 0x10, "ESS Solo-1 SB")) == NULL) { - snd_es1938_free(chip); snd_printk("unable to grab SB region 0x%lx-0x%lx\n", chip->sb_port, chip->sb_port + 0x10 - 1); + snd_es1938_free(chip); return -EBUSY; } chip->vc_port = pci_resource_start(pci, 2); if ((chip->res_vc_port = request_region(chip->vc_port, 0x10, "ESS Solo-1 VC (DMA)")) == NULL) { - snd_es1938_free(chip); snd_printk("unable to grab VC (DMA) region 0x%lx-0x%lx\n", chip->vc_port, chip->vc_port + 0x10 - 1); + snd_es1938_free(chip); return -EBUSY; } chip->mpu_port = pci_resource_start(pci, 3); if ((chip->res_mpu_port = request_region(chip->mpu_port, 4, "ESS Solo-1 MIDI")) == NULL) { - snd_es1938_free(chip); snd_printk("unable to grab MIDI region 0x%lx-0x%lx\n", chip->mpu_port, chip->mpu_port + 4 - 1); + snd_es1938_free(chip); return -EBUSY; } chip->game_port = pci_resource_start(pci, 4); if ((chip->res_game_port = request_region(chip->game_port, 4, "ESS Solo-1 GAME")) == NULL) { - snd_es1938_free(chip); snd_printk("unable to grab GAME region 0x%lx-0x%lx\n", chip->game_port, chip->game_port + 4 - 1); + snd_es1938_free(chip); return -EBUSY; } if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) { - snd_es1938_free(chip); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_es1938_free(chip); return -EBUSY; } chip->irq = pci->irq; diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 3bde70427d95..e0dd0b644bf7 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -439,7 +439,8 @@ MODULE_PARM_SYNTAX(use_pm, SNDRV_ENABLED ",allows:{{0,1,2}},skill:advanced"); /* capture mixing buffer size */ -#define ESM_MIXBUF_SIZE 512 +#define ESM_MEM_ALIGN 0x1000 +#define ESM_MIXBUF_SIZE 0x400 #define ESM_MODE_PLAY 0 #define ESM_MODE_CAPTURE 1 @@ -583,9 +584,8 @@ struct snd_es1968 { /* Maestro Stuff */ u16 maestro_map[32]; - atomic_t bobclient; /* active timer instancs */ + int bobclient; /* active timer instancs */ int bob_freq; /* timer frequency */ - spinlock_t bob_lock; struct semaphore memory_mutex; /* memory lock */ /* APU states */ @@ -884,13 +884,11 @@ static void snd_es1968_bob_start(es1968_t *chip) spin_unlock_irqrestore(&chip->reg_lock, flags); } +/* call with substream spinlock */ static void snd_es1968_bob_inc(es1968_t *chip, int freq) { - unsigned long flags; - - spin_lock_irqsave(&chip->bob_lock, flags); - atomic_inc(&chip->bobclient); - if (atomic_read(&chip->bobclient) == 1) { + chip->bobclient++; + if (chip->bobclient == 1) { chip->bob_freq = freq; snd_es1968_bob_start(chip); } else if (chip->bob_freq < freq) { @@ -898,35 +896,29 @@ static void snd_es1968_bob_inc(es1968_t *chip, int freq) chip->bob_freq = freq; snd_es1968_bob_start(chip); } - spin_unlock_irqrestore(&chip->bob_lock, flags); } +/* call with substream spinlock */ static void snd_es1968_bob_dec(es1968_t *chip) { - unsigned long flags; - - spin_lock_irqsave(&chip->bob_lock, flags); - atomic_dec(&chip->bobclient); - if (atomic_read(&chip->bobclient) <= 0) + chip->bobclient--; + if (chip->bobclient <= 0) snd_es1968_bob_stop(chip); else if (chip->bob_freq > ESM_BOB_FREQ) { /* check reduction of timer frequency */ struct list_head *p; int max_freq = ESM_BOB_FREQ; - spin_lock(&chip->substream_lock); list_for_each(p, &chip->substream_list) { esschan_t *es = list_entry(p, esschan_t, list); if (max_freq < es->bob_freq) max_freq = es->bob_freq; } - spin_unlock(&chip->substream_lock); if (max_freq != chip->bob_freq) { snd_es1968_bob_stop(chip); chip->bob_freq = max_freq; snd_es1968_bob_start(chip); } } - spin_unlock_irqrestore(&chip->bob_lock, flags); } static int @@ -986,19 +978,15 @@ static void snd_es1968_apu_set_freq(es1968_t *chip, int apu, int freq) /* spin lock held */ inline static void snd_es1968_trigger_apu(es1968_t *esm, int apu, int mode) { - /* dma on, no envelopes, filter to all 1s) */ - __apu_set_register(esm, apu, 0, 0x400f | mode); + /* set the APU mode */ + __apu_set_register(esm, apu, 0, + (__apu_get_register(esm, apu, 0) & 0xff0f) | + (mode << 4)); } static void snd_es1968_pcm_start(es1968_t *chip, esschan_t *es) { - unsigned long flags; - - spin_lock_irqsave(&chip->reg_lock, flags); - if (es->running) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - return; - } + spin_lock(&chip->reg_lock); __apu_set_register(chip, es->apu[0], 5, es->base[0]); snd_es1968_trigger_apu(chip, es->apu[0], es->apu_mode[0]); if (es->mode == ESM_MODE_CAPTURE) { @@ -1013,27 +1001,19 @@ static void snd_es1968_pcm_start(es1968_t *chip, esschan_t *es) snd_es1968_trigger_apu(chip, es->apu[3], es->apu_mode[3]); } } - es->running = 1; - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock(&chip->reg_lock); } static void snd_es1968_pcm_stop(es1968_t *chip, esschan_t *es) { - unsigned long flags; - - spin_lock_irqsave(&chip->reg_lock, flags); - if (! es->running) { - spin_unlock_irqrestore(&chip->reg_lock, flags); - return; - } + spin_lock(&chip->reg_lock); snd_es1968_trigger_apu(chip, es->apu[0], 0); snd_es1968_trigger_apu(chip, es->apu[1], 0); if (es->mode == ESM_MODE_CAPTURE) { snd_es1968_trigger_apu(chip, es->apu[2], 0); snd_es1968_trigger_apu(chip, es->apu[3], 0); } - es->running = 0; - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock(&chip->reg_lock); } /* set the wavecache control reg */ @@ -1115,12 +1095,12 @@ static void snd_es1968_playback_setup(es1968_t *chip, esschan_t *es, /* clear routing stuff */ apu_set_register(chip, apu, 11, 0x0000); /* dma on, no envelopes, filter to all 1s) */ - // apu_set_register(chip, apu, 0, 0x400F); + apu_set_register(chip, apu, 0, 0x400F); if (es->fmt & ESS_FMT_16BIT) - es->apu_mode[channel] = 0x10; /* 16bit mono */ + es->apu_mode[channel] = ESM_APU_16BITLINEAR; else - es->apu_mode[channel] = 0x30; /* 8bit mono */ + es->apu_mode[channel] = ESM_APU_8BITLINEAR; if (es->fmt & ESS_FMT_STEREO) { /* set panning: left or right */ @@ -1130,7 +1110,7 @@ static void snd_es1968_playback_setup(es1968_t *chip, esschan_t *es, and not the APU Regs 4-5. */ apu_set_register(chip, apu, 10, 0x8F00 | (channel ? 0 : 0x10)); - es->apu_mode[channel] += 0x10; /* stereo */ + es->apu_mode[channel] += 1; /* stereo */ } else apu_set_register(chip, apu, 10, 0x8F08); } @@ -1160,119 +1140,91 @@ static void snd_es1968_playback_setup(es1968_t *chip, esschan_t *es, snd_es1968_apu_set_freq(chip, es->apu[1], freq); } + +static void init_capture_apu(es1968_t *chip, esschan_t *es, int channel, + unsigned int pa, unsigned int bsize, + int mode, int route) +{ + int i, apu = es->apu[channel]; + + es->apu_mode[channel] = mode; + + /* set the wavecache control reg */ + snd_es1968_program_wavecache(chip, es, channel, pa, 1); + + /* Offset to PCMBAR */ + pa -= chip->dma.addr; + pa >>= 1; /* words */ + + /* base offset of dma calcs when reading the pointer + on this left one */ + es->base[channel] = pa & 0xFFFF; + pa |= 0x00400000; /* bit 22 -> System RAM */ + + /* Begin loading the APU */ + for (i = 0; i < 16; i++) + apu_set_register(chip, apu, i, 0x0000); + + /* need to enable subgroups.. and we should probably + have different groups for different /dev/dsps.. */ + apu_set_register(chip, apu, 2, 0x8); + + /* Load the buffer into the wave engine */ + apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8); + apu_set_register(chip, apu, 5, pa & 0xFFFF); + apu_set_register(chip, apu, 6, (pa + bsize) & 0xFFFF); + apu_set_register(chip, apu, 7, bsize); + /* clear effects/env.. */ + apu_set_register(chip, apu, 8, 0x00F0); + /* amplitude now? sure. why not. */ + apu_set_register(chip, apu, 9, 0x0000); + /* set filter tune, radius, polar pan */ + apu_set_register(chip, apu, 10, 0x8F08); + /* route input */ + apu_set_register(chip, apu, 11, route); + /* dma on, no envelopes, filter to all 1s) */ + apu_set_register(chip, apu, 0, 0x400F); +} + static void snd_es1968_capture_setup(es1968_t *chip, esschan_t *es, snd_pcm_runtime_t *runtime) { - int apu_step = 2; - int channel, apu; - int i, size; + int size; u32 freq; unsigned long flags; size = es->dma_size >> es->wav_shift; - /* we're given the full size of the buffer, but - in stereo each channel will only use its half */ - if (es->fmt & ESS_FMT_STEREO) - apu_step = 1; - /* APU assignments: 0 = mono/left SRC 1 = right SRC 2 = mono/left Input Mixer - 3 = right Input Mixer */ - for (channel = 0; channel < 4; channel += apu_step) { - int bsize, route; - u32 pa; - - apu = es->apu[channel]; - - /* data seems to flow from the codec, through an apu into - the 'mixbuf' bit of page, then through the SRC apu - and out to the real 'buffer'. ok. sure. */ - - if (channel & 2) { - /* ok, we're an input mixer going from adc - through the mixbuf to the other apus */ - - if (!(channel & 0x01)) { - pa = es->mixbuf->addr; - } else { - pa = es->mixbuf->addr + ESM_MIXBUF_SIZE / 2; - } - - /* we source from a 'magic' apu */ - bsize = ESM_MIXBUF_SIZE / 4; /* half of this channels alloc, in words */ - /* parallel in crap, see maestro reg 0xC [8-11] */ - route = 0x14 + channel - 2; - es->apu_mode[channel] = 0x90; /* Input Mixer */ - } else { - /* we're a rate converter taking - input from the input apus and outputing it to - system memory */ - if (!(channel & 0x01)) - pa = es->memory->addr; - else - pa = es->memory->addr + size * 2; /* size is in word */ - - es->apu_mode[channel] = 0xB0; /* Sample Rate Converter */ - - bsize = size; - /* get input from inputing apu */ - route = es->apu[channel + 2]; - } - - /* set the wavecache control reg */ - snd_es1968_program_wavecache(chip, es, channel, pa, 1); - - /* Offset to PCMBAR */ - pa -= chip->dma.addr; - pa >>= 1; /* words */ - - /* base offset of dma calcs when reading the pointer - on this left one */ - es->base[channel] = pa & 0xFFFF; - - pa |= 0x00400000; /* bit 22 -> System RAM */ - - /* Begin loading the APU */ - for (i = 0; i < 16; i++) - apu_set_register(chip, apu, i, 0x0000); - - /* need to enable subgroups.. and we should probably - have different groups for different /dev/dsps.. */ - apu_set_register(chip, apu, 2, 0x8); - - /* Load the buffer into the wave engine */ - apu_set_register(chip, apu, 4, ((pa >> 16) & 0xFF) << 8); - /* XXX reg is little endian.. */ - apu_set_register(chip, apu, 5, pa & 0xFFFF); - apu_set_register(chip, apu, 6, (pa + bsize) & 0xFFFF); - apu_set_register(chip, apu, 7, bsize); -#if 0 - if (es->fmt & ESS_FMT_STEREO) /* ??? really ??? */ - apu_set_register(chip, apu, 7, bsize - 1); -#endif - - /* clear effects/env.. */ - apu_set_register(chip, apu, 8, 0x00F0); - /* amplitude now? sure. why not. */ - apu_set_register(chip, apu, 9, 0x0000); - /* set filter tune, radius, polar pan */ - apu_set_register(chip, apu, 10, 0x8F08); - /* route input */ - apu_set_register(chip, apu, 11, route); - /* dma on, no envelopes, filter to all 1s) */ - // apu_set_register(chip, apu, 0, 0x400F); + 3 = right Input Mixer + */ + /* data seems to flow from the codec, through an apu into + the 'mixbuf' bit of page, then through the SRC apu + and out to the real 'buffer'. ok. sure. */ + + /* input mixer (left/mono) */ + /* parallel in crap, see maestro reg 0xC [8-11] */ + init_capture_apu(chip, es, 2, + es->mixbuf->addr, ESM_MIXBUF_SIZE/4, /* in words */ + ESM_APU_INPUTMIXER, 0x14); + /* SRC (left/mono); get input from inputing apu */ + init_capture_apu(chip, es, 0, es->memory->addr, size, + ESM_APU_SRCONVERTOR, es->apu[2]); + if (es->fmt & ESS_FMT_STEREO) { + /* input mixer (right) */ + init_capture_apu(chip, es, 3, + es->mixbuf->addr + ESM_MIXBUF_SIZE/2, + ESM_MIXBUF_SIZE/4, /* in words */ + ESM_APU_INPUTMIXER, 0x15); + /* SRC (right) */ + init_capture_apu(chip, es, 1, + es->memory->addr + size*2, size, + ESM_APU_SRCONVERTOR, es->apu[3]); } - spin_lock_irqsave(&chip->reg_lock, flags); - /* clear WP interrupts */ - outw(1, chip->io_port + 0x04); - /* enable WP ints */ - outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); - spin_unlock_irqrestore(&chip->reg_lock, flags); - freq = runtime->rate; /* Sample Rate conversion APUs don't like 0x10000 for their rate */ if (freq > 47999) @@ -1290,6 +1242,13 @@ static void snd_es1968_capture_setup(es1968_t *chip, esschan_t *es, freq = 0x10000; snd_es1968_apu_set_freq(chip, es->apu[2], freq); snd_es1968_apu_set_freq(chip, es->apu[3], freq); + + spin_lock_irqsave(&chip->reg_lock, flags); + /* clear WP interrupts */ + outw(1, chip->io_port + 0x04); + /* enable WP ints */ + outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); + spin_unlock_irqrestore(&chip->reg_lock, flags); } /******************* @@ -1334,30 +1293,28 @@ static int snd_es1968_pcm_trigger(snd_pcm_substream_t *substream, int cmd) esschan_t *es = snd_magic_cast(esschan_t, substream->runtime->private_data, return -ENXIO); unsigned long flags; + spin_lock_irqsave(&chip->substream_lock, flags); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: if (es->running) - return 0; + break; snd_es1968_bob_inc(chip, es->bob_freq); es->count = 0; es->hwptr = 0; snd_es1968_pcm_start(chip, es); - spin_lock_irqsave(&chip->substream_lock, flags); - list_add(&es->list, &chip->substream_list); - spin_unlock_irqrestore(&chip->substream_lock, flags); + es->running = 1; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: if (! es->running) - return 0; + break; snd_es1968_pcm_stop(chip, es); - spin_lock_irqsave(&chip->substream_lock, flags); - list_del(&es->list); - spin_unlock_irqrestore(&chip->substream_lock, flags); + es->running = 0; snd_es1968_bob_dec(chip); break; } + spin_unlock_irqrestore(&chip->substream_lock, flags); return 0; } @@ -1444,6 +1401,7 @@ static esm_memory_t *snd_es1968_new_memory(es1968_t *chip, int size) esm_memory_t *buf; struct list_head *p; + size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN; down(&chip->memory_mutex); list_for_each(p, &chip->buf_list) { buf = list_entry(p, esm_memory_t, list); @@ -1542,10 +1500,10 @@ snd_es1968_init_dmabuf(es1968_t *chip) snd_es1968_free_dmabuf(chip); return -ENOMEM; } - memset(chip->dma.area, 0, 512); - chunk->buf = chip->dma.area + 512; - chunk->addr = chip->dma.addr + 512; - chunk->size = chip->dma.bytes - 512; + memset(chip->dma.area, 0, ESM_MEM_ALIGN); + chunk->buf = chip->dma.area + ESM_MEM_ALIGN; + chunk->addr = chip->dma.addr + ESM_MEM_ALIGN; + chunk->size = chip->dma.bytes - ESM_MEM_ALIGN; chunk->empty = 1; list_add(&chunk->list, &chip->buf_list); @@ -1634,6 +1592,7 @@ static int snd_es1968_playback_open(snd_pcm_substream_t *substream) snd_pcm_runtime_t *runtime = substream->runtime; esschan_t *es; int apu1; + unsigned long flags; /* search 2 APUs */ apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY); @@ -1653,44 +1612,29 @@ static int snd_es1968_playback_open(snd_pcm_substream_t *substream) es->running = 0; es->substream = substream; es->mode = ESM_MODE_PLAY; - INIT_LIST_HEAD(&es->list); runtime->private_data = es; runtime->hw = snd_es1968_playback; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip); +#if 0 + snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + 1024); +#endif + spin_lock_irqsave(&chip->substream_lock, flags); + list_add(&es->list, &chip->substream_list); + spin_unlock_irqrestore(&chip->substream_lock, flags); return 0; } -static int snd_es1968_capture_copy(snd_pcm_substream_t *substream, - int channel, snd_pcm_uframes_t pos, - void *buf, snd_pcm_uframes_t count) -{ - //es1968_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - esschan_t *es = snd_magic_cast(esschan_t, runtime->private_data, return -ENXIO); - char *src = runtime->dma_area; - - if (runtime->channels == 1) - return copy_to_user(buf, src + pos, count) ? -EFAULT : 0; - else { - count /= 2; - pos /= 2; - if (copy_to_user(buf, src + pos, count)) - return -EFAULT; - if (copy_to_user(buf + count, src + pos + es->dma_size/2, count)) - return -EFAULT; - return 0; - } -} - static int snd_es1968_capture_open(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; es1968_t *chip = snd_pcm_substream_chip(substream); esschan_t *es; int apu1, apu2; + unsigned long flags; apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE); if (apu1 < 0) @@ -1719,7 +1663,6 @@ static int snd_es1968_capture_open(snd_pcm_substream_t *substream) es->running = 0; es->substream = substream; es->mode = ESM_MODE_CAPTURE; - INIT_LIST_HEAD(&es->list); /* get mixbuffer */ if ((es->mixbuf = snd_es1968_new_memory(chip, ESM_MIXBUF_SIZE)) == NULL) { @@ -1728,11 +1671,19 @@ static int snd_es1968_capture_open(snd_pcm_substream_t *substream) snd_magic_kfree(es); return -ENOMEM; } + memset(es->mixbuf->buf, 0, ESM_MIXBUF_SIZE); runtime->private_data = es; runtime->hw = snd_es1968_capture; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = - calc_available_memory_size(chip) - 1024; + calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ +#if 0 + snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + 1024); +#endif + spin_lock_irqsave(&chip->substream_lock, flags); + list_add(&es->list, &chip->substream_list); + spin_unlock_irqrestore(&chip->substream_lock, flags); return 0; } @@ -1741,9 +1692,14 @@ static int snd_es1968_playback_close(snd_pcm_substream_t * substream) { es1968_t *chip = snd_pcm_substream_chip(substream); esschan_t *es; + unsigned long flags; + if (substream->runtime->private_data == NULL) return 0; es = snd_magic_cast(esschan_t, substream->runtime->private_data, return -ENXIO); + spin_lock_irqsave(&chip->substream_lock, flags); + list_del(&es->list); + spin_unlock_irqrestore(&chip->substream_lock, flags); snd_es1968_free_apu_pair(chip, es->apu[0]); snd_magic_kfree(es); @@ -1754,9 +1710,14 @@ static int snd_es1968_capture_close(snd_pcm_substream_t * substream) { es1968_t *chip = snd_pcm_substream_chip(substream); esschan_t *es; + unsigned long flags; + if (substream->runtime->private_data == NULL) return 0; es = snd_magic_cast(esschan_t, substream->runtime->private_data, return -ENXIO); + spin_lock_irqsave(&chip->substream_lock, flags); + list_del(&es->list); + spin_unlock_irqrestore(&chip->substream_lock, flags); snd_es1968_free_memory(chip, es->mixbuf); snd_es1968_free_apu_pair(chip, es->apu[0]); snd_es1968_free_apu_pair(chip, es->apu[2]); @@ -1785,7 +1746,6 @@ static snd_pcm_ops_t snd_es1968_capture_ops = { .prepare = snd_es1968_pcm_prepare, .trigger = snd_es1968_pcm_trigger, .pointer = snd_es1968_pcm_pointer, - .copy = snd_es1968_capture_copy, }; @@ -1827,6 +1787,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip) for (i = 0; i < 16; i++) apu_set_register(chip, apu, i, 0x0000); + apu_set_register(chip, apu, 0, 0x400f); apu_set_register(chip, apu, 4, ((pa >> 16) & 0xff) << 8); apu_set_register(chip, apu, 5, pa & 0xffff); apu_set_register(chip, apu, 6, (pa + CLOCK_MEASURE_BUFSIZE/2) & 0xffff); @@ -1844,7 +1805,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip) spin_lock_irqsave(&chip->reg_lock, flags); __apu_set_register(chip, apu, 5, pa & 0xffff); - snd_es1968_trigger_apu(chip, apu, 0x10); /* 16bit mono */ + snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); do_gettimeofday(&start_time); spin_unlock_irqrestore(&chip->reg_lock, flags); #if 0 @@ -2035,14 +1996,12 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *r } if (event & ESM_SOUND_IRQ) { - struct list_head *p, *n; + struct list_head *p; spin_lock(&chip->substream_lock); - /* we need to use list_for_each_safe here since the substream - * can be deleted in period_elapsed(). - */ - list_for_each_safe(p, n, &chip->substream_list) { + list_for_each(p, &chip->substream_list) { esschan_t *es = list_entry(p, esschan_t, list); - snd_es1968_update_pcm(chip, es); + if (es->running) + snd_es1968_update_pcm(chip, es); } spin_unlock(&chip->substream_lock); } @@ -2467,7 +2426,7 @@ static void es1968_resume(es1968_t *chip) snd_ac97_resume(chip->ac97); /* start timer again */ - if (atomic_read(&chip->bobclient)) + if (chip->bobclient) snd_es1968_bob_start(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); @@ -2532,6 +2491,18 @@ static int snd_es1968_dev_free(snd_device_t *device) return snd_es1968_free(chip); } +struct pm_whitelist { + unsigned short type; /* chip type */ + unsigned short vendor; /* subsystem vendor id */ +}; + +static struct pm_whitelist whitelist[] __devinitdata = { + { TYPE_MAESTRO2E, 0x1028 }, + { TYPE_MAESTRO2E, 0x103c }, + { TYPE_MAESTRO2E, 0x1179 }, + { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ +}; + static int __devinit snd_es1968_create(snd_card_t * card, struct pci_dev *pci, int total_bufsize, @@ -2567,7 +2538,6 @@ static int __devinit snd_es1968_create(snd_card_t * card, chip->type = chip_type; spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->substream_lock); - spin_lock_init(&chip->bob_lock); INIT_LIST_HEAD(&chip->buf_list); INIT_LIST_HEAD(&chip->substream_list); init_MUTEX(&chip->memory_mutex); @@ -2581,14 +2551,14 @@ static int __devinit snd_es1968_create(snd_card_t * card, chip->io_port = pci_resource_start(pci, 0); if ((chip->res_io_port = request_region(chip->io_port, 0x100, "ESS Maestro")) == NULL) { - snd_es1968_free(chip); snd_printk("unable to grab region 0x%lx-0x%lx\n", chip->io_port, chip->io_port + 0x100 - 1); + snd_es1968_free(chip); return -EBUSY; } if (request_irq(pci->irq, snd_es1968_interrupt, SA_INTERRUPT|SA_SHIRQ, "ESS Maestro", (void*)chip)) { - snd_es1968_free(chip); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_es1968_free(chip); return -EBUSY; } chip->irq = pci->irq; @@ -2601,18 +2571,22 @@ static int __devinit snd_es1968_create(snd_card_t * card, for (i = 0; i < NR_APUS; i++) chip->apu[i] = ESM_APU_FREE; - atomic_set(&chip->bobclient, 0); - /* just to be sure */ pci_set_master(pci); if (do_pm > 1) { - /* disable power-management if not maestro2e or - * if not on the whitelist - */ + /* disable power-management if not on the whitelist */ unsigned short vend; pci_read_config_word(chip->pci, PCI_SUBSYSTEM_VENDOR_ID, &vend); - if (chip->type != TYPE_MAESTRO2E || (vend != 0x1028 && vend != 0x1179)) { + for (i = 0; i < (int)ARRAY_SIZE(whitelist); i++) { + if (chip->type == whitelist[i].type && + vend == whitelist[i].vendor) { + do_pm = 1; + break; + } + } + if (do_pm > 1) { + /* not matched; disabling pm */ printk(KERN_INFO "es1968: not attempting power management.\n"); do_pm = 0; } @@ -2852,7 +2826,8 @@ module_exit(alsa_card_es1968_exit) total_bufsize, pcm_substreams_p, pcm_substreams_c, - clock + clock, + use_pm */ static int __init alsa_card_es1968_setup(char *str) @@ -2867,7 +2842,8 @@ static int __init alsa_card_es1968_setup(char *str) get_option(&str,&total_bufsize[nr_dev]) == 2 && get_option(&str,&pcm_substreams_p[nr_dev]) == 2 && get_option(&str,&pcm_substreams_c[nr_dev]) == 2 && - get_option(&str,&clock[nr_dev]) == 2); + get_option(&str,&clock[nr_dev]) == 2 && + get_option(&str,&use_pm[nr_dev]) == 2); nr_dev++; return 1; } diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index c6854f54d82b..71c69d6ee12f 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -2387,28 +2387,28 @@ static int __devinit snd_ice1712_create(snd_card_t * card, synchronize_irq(pci->irq); if ((ice->res_port = request_region(ice->port, 32, "ICE1712 - Controller")) == NULL) { - snd_ice1712_free(ice); snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->port, ice->port + 32 - 1); + snd_ice1712_free(ice); return -EIO; } if ((ice->res_ddma_port = request_region(ice->ddma_port, 16, "ICE1712 - DDMA")) == NULL) { - snd_ice1712_free(ice); snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->ddma_port, ice->ddma_port + 16 - 1); + snd_ice1712_free(ice); return -EIO; } if ((ice->res_dmapath_port = request_region(ice->dmapath_port, 16, "ICE1712 - DMA path")) == NULL) { - snd_ice1712_free(ice); snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->dmapath_port, ice->dmapath_port + 16 - 1); + snd_ice1712_free(ice); return -EIO; } if ((ice->res_profi_port = request_region(ice->profi_port, 64, "ICE1712 - Professional")) == NULL) { - snd_ice1712_free(ice); snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->profi_port, ice->profi_port + 16 - 1); + snd_ice1712_free(ice); return -EIO; } if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) { - snd_ice1712_free(ice); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_ice1712_free(ice); return -EIO; } diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 205864dfdae2..0fc548dff5f0 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -566,7 +566,7 @@ static snd_pcm_hardware_t snd_vt1724_playback_pro = SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000, + .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000, .rate_min = 4000, .rate_max = 192000, .channels_min = 2, @@ -585,7 +585,7 @@ static snd_pcm_hardware_t snd_vt1724_capture_pro = SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000, + .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000, .rate_min = 4000, .rate_max = 192000, .channels_min = 2, @@ -720,7 +720,7 @@ static snd_pcm_hardware_t snd_vt1724_playback_spdif = SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START), .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000, + .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000, .rate_min = 4000, .rate_max = 192000, .channels_min = 2, @@ -778,7 +778,7 @@ static int snd_vt1724_playback_spdif_open(snd_pcm_substream_t *substream) snd_pcm_set_sync(substream); snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96); + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192); return 0; } @@ -1796,20 +1796,20 @@ static int __devinit snd_vt1724_create(snd_card_t * card, synchronize_irq(pci->irq); if ((ice->res_port = request_region(ice->port, 32, "ICE1724 - Controller")) == NULL) { - snd_vt1724_free(ice); snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->port, ice->port + 32 - 1); + snd_vt1724_free(ice); return -EIO; } if ((ice->res_profi_port = request_region(ice->profi_port, 128, "ICE1724 - Professional")) == NULL) { - snd_vt1724_free(ice); snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->profi_port, ice->profi_port + 16 - 1); + snd_vt1724_free(ice); return -EIO; } if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) { - snd_vt1724_free(ice); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_vt1724_free(ice); return -EIO; } diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index f7a1ef86cf58..81ede0fe5fd5 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -523,6 +523,19 @@ static void iaputword(intel8x0_t *chip, u32 offset, u16 val) /* * access to AC97 codec via normal i/o (for ICH and SIS7012) */ + +/* return the GLOB_STA bit for the corresponding codec */ +static unsigned int get_ich_codec_bit(intel8x0_t *chip, unsigned int codec) +{ + static unsigned int codec_bit[3] = { + ICH_PCR, ICH_SCR, ICH_TCR + }; + snd_assert(codec < 3, return ICH_PCR); + if (chip->device_type == DEVICE_INTEL_ICH4) + codec = chip->ac97_sdin[codec]; + return codec_bit[codec]; +} + static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec) { int time; @@ -534,19 +547,7 @@ static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec) /* so we check any */ codec = ICH_PCR | ICH_SCR | ICH_TCR; } else { - if (chip->device_type == DEVICE_INTEL_ICH4) { - switch (chip->ac97_sdin[codec]) { - case 0: codec = ICH_PCR; break; - case 1: codec = ICH_SCR; break; - case 2: codec = ICH_TCR; break; - } - } else { - switch (codec) { - case 0: codec = ICH_PCR; break; - case 1: codec = ICH_SCR; break; - case 2: codec = ICH_TCR; break; - } - } + codec = get_ich_codec_bit(chip, codec); } /* codec ready ? */ @@ -1555,13 +1556,98 @@ static struct _ac97_rate_regs ali_ac97_rate_regs[] __devinitdata = { }; static struct ac97_quirk ac97_quirks[] __devinitdata = { - { 0x1028, 0x0126, "Dell Optiplex GX260", AC97_TUNE_HP_ONLY }, - { 0x1734, 0x0088, "Fujitsu-Siemens D1522", AC97_TUNE_HP_ONLY }, - { 0x10f1, 0x2665, "Fujitsu-Siemens Celcius", AC97_TUNE_HP_ONLY }, - { 0x110a, 0x0056, "Fujitsu-Siemens Scenic", AC97_TUNE_HP_ONLY }, - { 0x8086, 0x4d44, "Intel D850EMV2", AC97_TUNE_HP_ONLY }, - /* { 0x4144, 0x5360, "AMD64 Motherboard", AC97_TUNE_HP_ONLY }, */ /* FIXME: this seems invalid */ - { 0x1043, 0x80b0, "ASUS P4PE Mobo", AC97_TUNE_SWAP_SURROUND }, + { + .vendor = 0x1028, + .device = 0x0126, + .name = "Dell Optiplex GX260", + .type = AC97_TUNE_HP_ONLY + }, + { + .vendor = 0x1043, + .device =0x80b0, + .name = "ASUS P4PE Mobo", + .type = AC97_TUNE_SWAP_SURROUND + }, + { + .vendor = 0x1043, + .device = 0x80f3, + .name = "ASUS ICH5/AD1985", + .type = AC97_TUNE_AD_SHARING + }, + { + .vendor = 0x10f1, + .device = 0x2665, + .name = "Fujitsu-Siemens Celcius", + .type = AC97_TUNE_HP_ONLY + }, + { + .vendor = 0x110a, + .device = 0x0056, + .name = "Fujitsu-Siemens Scenic", + .type = AC97_TUNE_HP_ONLY + }, + { + .vendor = 0x11d4, + .device = 0x5375, + .name = "ADI AD1985 (discrete)", + .type = AC97_TUNE_HP_ONLY + }, + { + .vendor = 0x1734, + .device = 0x0088, + .name = "Fujitsu-Siemens D1522", + .type = AC97_TUNE_HP_ONLY + }, +#if 0 + /* FIXME: this seems invalid */ + { + .vendor = 0x4144, + .device = 0x5360, + .type = "AMD64 Motherboard", + .name = AC97_TUNE_HP_ONLY + }, +#endif + { + .vendor = 0x8086, + .device = 0x2000, + .mask = 0xfff0, + .name = "Intel ICH5/AD1985 (discrete)", + .type = AC97_TUNE_HP_ONLY + }, + { + .vendor = 0x8086, + .device = 0x4000, + .mask = 0xfff0, + .name = "Intel ICH5/AD1985", + .type = AC97_TUNE_AD_SHARING + }, + { + .vendor = 0x8086, + .device = 0x4d44, + .name = "Intel D850EMV2", + .type = AC97_TUNE_HP_ONLY + }, + { + .vendor = 0x8086, + .device = 0x6000, + .mask = 0xfff0, + .name = "Intel ICH5/AD1985", + .type = AC97_TUNE_AD_SHARING + }, + { + .vendor = 0x8086, + .device = 0xe000, + .mask = 0xfff0, + .name = "Intel ICH5/AD1985", + .type = AC97_TUNE_AD_SHARING + }, + { + .vendor = 0x8086, + .device = 0xa000, + .mask = 0xfff0, + .name = "Intel ICH5/AD1985 (discrete)", + .type = AC97_TUNE_HP_ONLY + }, { } /* terminator */ }; @@ -1646,9 +1732,14 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock) } } ac97.pci = chip->pci; - if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0) + if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0) { + /* clear the cold-reset bit for the next chance */ + if (chip->device_type != DEVICE_ALI) + iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD); return err; + } chip->ac97[0] = x97; + /* tune up the primary codec */ snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks); /* the following three entries are common among all devices */ chip->ichd[ICHD_PCMOUT].ac97 = x97; @@ -1801,7 +1892,7 @@ static void do_ali_reset(intel8x0_t *chip) schedule_timeout(1);\ } while (0) -static int snd_intel8x0_ich_chip_init(intel8x0_t *chip) +static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing) { unsigned long end_time; unsigned int cnt, status, nstatus; @@ -1830,49 +1921,55 @@ static int snd_intel8x0_ich_chip_init(intel8x0_t *chip) return -EIO; __ok: - /* wait for any codec ready status. - * Once it becomes ready it should remain ready - * as long as we do not disable the ac97 link. - */ - end_time = jiffies + HZ; - do { - status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR); - if (status) - goto __ok1; - do_delay(chip); - } while (time_after_eq(end_time, jiffies)); - snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", igetdword(chip, ICHREG(GLOB_STA))); - return -EIO; - - __ok1: - if (status == (ICH_PCR | ICH_SCR | ICH_TCR)) - goto __ok3; - /* wait for other codecs ready status. No secondary codecs? , ok */ - end_time = jiffies + HZ / 4; - do { - nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR); - if (nstatus != status) { - status = nstatus; - goto __ok2; + if (probing) { + /* wait for any codec ready status. + * Once it becomes ready it should remain ready + * as long as we do not disable the ac97 link. + */ + end_time = jiffies + HZ; + do { + status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR); + if (status) + break; + do_delay(chip); + } while (time_after_eq(end_time, jiffies)); + if (! status) { + /* no codec is found */ + snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", igetdword(chip, ICHREG(GLOB_STA))); + return -EIO; } - do_delay(chip); - } while (time_after_eq(end_time, jiffies)); - __ok2: - if (status == (ICH_PCR | ICH_SCR | ICH_TCR)) - goto __ok3; - /* wait for other codecs ready status. No other secondary codecs? , ok */ - /* end_time is not initialized here */ - do { - nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR); - if (nstatus != status) { - status = nstatus; - goto __ok2; + if (chip->device_type == DEVICE_INTEL_ICH4) + /* ICH4 can have three codecs */ + nstatus = ICH_PCR | ICH_SCR | ICH_TCR; + else + /* others up to two codecs */ + nstatus = ICH_PCR | ICH_SCR; + + /* wait for other codecs ready status. */ + end_time = jiffies + HZ / 4; + while (status != nstatus && time_after_eq(end_time, jiffies)) { + do_delay(chip); + status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus; } - do_delay(chip); - } while (time_after_eq(end_time, jiffies)); - __ok3: + } else { + /* resume phase */ + int i; + status = 0; + for (i = 0; i < 3; i++) + if (chip->ac97[i]) + status |= get_ich_codec_bit(chip, i); + /* wait until all the probed codecs are ready */ + end_time = jiffies + HZ; + do { + nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR); + if (status == nstatus) + break; + do_delay(chip); + } while (time_after_eq(end_time, jiffies)); + } + if (chip->device_type == DEVICE_SIS) { /* unmute the output on SIS7012 */ iputword(chip, 0x4c, igetword(chip, 0x4c) | 1); @@ -1887,7 +1984,7 @@ static int snd_intel8x0_ich_chip_init(intel8x0_t *chip) return 0; } -static int snd_intel8x0_ali_chip_init(intel8x0_t *chip) +static int snd_intel8x0_ali_chip_init(intel8x0_t *chip, int probing) { u32 reg; int i = 0; @@ -1906,7 +2003,8 @@ static int snd_intel8x0_ali_chip_init(intel8x0_t *chip) do_delay(chip); } snd_printk(KERN_ERR "AC'97 reset failed.\n"); - return -EIO; + if (probing) + return -EIO; __ok: for (i = 0; i < HZ / 2; i++) { @@ -1921,17 +2019,17 @@ static int snd_intel8x0_ali_chip_init(intel8x0_t *chip) return 0; } -static int snd_intel8x0_chip_init(intel8x0_t *chip) +static int snd_intel8x0_chip_init(intel8x0_t *chip, int probing) { unsigned int i; int err; if (chip->device_type != DEVICE_ALI) { - if ((err = snd_intel8x0_ich_chip_init(chip)) < 0) + if ((err = snd_intel8x0_ich_chip_init(chip, probing)) < 0) return err; iagetword(chip, 0); /* clear semaphore flag */ } else { - if ((err = snd_intel8x0_ali_chip_init(chip)) < 0) + if ((err = snd_intel8x0_ali_chip_init(chip, probing)) < 0) return err; } @@ -2019,7 +2117,7 @@ static void intel8x0_resume(intel8x0_t *chip) pci_enable_device(chip->pci); pci_set_master(chip->pci); - snd_intel8x0_chip_init(chip); + snd_intel8x0_chip_init(chip, 0); for (i = 0; i < 3; i++) if (chip->ac97[i]) snd_ac97_resume(chip->ac97[i]); @@ -2377,7 +2475,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card, chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA; chip->int_sta_mask = int_sta_masks; - if ((err = snd_intel8x0_chip_init(chip)) < 0) { + if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) { snd_intel8x0_free(chip); return err; } diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 840827a063a2..6af726e1a56c 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -4125,6 +4125,7 @@ static int __devinit snd_hdsp_create(snd_card_t *card, switch (hdsp->firmware_rev & 0xff) { case 0xa: case 0xb: + case 0x32: hdsp->card_name = "RME Hammerfall DSP"; break; diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index b6dea6828c37..5b43f8e98a3a 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -1264,32 +1264,32 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card, 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_sonicvibes_free(sonic); 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; } sonic->enh_port = pci_resource_start(pci, 1); if ((sonic->res_enh_port = request_region(sonic->enh_port, 0x10, "S3 SonicVibes Enhanced")) == NULL) { - snd_sonicvibes_free(sonic); 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_sonicvibes_free(sonic); 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_sonicvibes_free(sonic); 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_magic_kfree(sonic); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_sonicvibes_free(sonic); return -EBUSY; } sonic->irq = pci->irq; diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 2f5d0aa68cba..a8e991a25702 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -3538,13 +3538,13 @@ int __devinit snd_trident_create(snd_card_t * card, trident->port = pci_resource_start(pci, 0); if ((trident->res_port = request_region(trident->port, 0x100, "Trident Audio")) == NULL) { - snd_trident_free(trident); snd_printk("unable to grab I/O region 0x%lx-0x%lx\n", trident->port, trident->port + 0x100 - 1); + snd_trident_free(trident); return -EBUSY; } if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) { - snd_trident_free(trident); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_trident_free(trident); return -EBUSY; } trident->irq = pci->irq; diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index ea4220bb19e1..180653006efb 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -886,9 +886,11 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream) snd_ac97_set_rate(chip->ac97, AC97_PCM_LFE_DAC_RATE, runtime->rate); snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); } +#if 0 if (chip->revision == VIA_REV_8233A) rbits = 0; else +#endif rbits = (0xfffff / 48000) * runtime->rate + ((0xfffff % 48000) * runtime->rate) / 48000; snd_assert((rbits & ~0xfffff) == 0, return -EINVAL); snd_via82xx_channel_reset(chip, viadev); @@ -928,9 +930,12 @@ static int snd_via8233_multi_prepare(snd_pcm_substream_t *substream) fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT; fmt |= runtime->channels << 4; outb(fmt, VIADEV_REG(viadev, OFS_MULTPLAY_FORMAT)); +#if 0 if (chip->revision == VIA_REV_8233A) slots = 0; - else { + else +#endif + { /* set sample number to slot 3, 4, 7, 8, 6, 9 (for VIA8233/C,8235) */ /* corresponding to FL, FR, RL, RR, C, LFE ?? */ switch (runtime->channels) { @@ -1501,7 +1506,12 @@ static void snd_via82xx_mixer_free_ac97(ac97_t *ac97) } static struct ac97_quirk ac97_quirks[] = { - { 0x1106, 0x4161, "ASRock K7VT2", AC97_TUNE_HP_ONLY }, + { + .vendor = 0x1106, + .device = 0x4161, + .name = "ASRock K7VT2", + .type = AC97_TUNE_HP_ONLY + }, { } /* terminator */ }; @@ -1887,14 +1897,14 @@ static int __devinit snd_via82xx_create(snd_card_t * card, chip->port = pci_resource_start(pci, 0); if ((chip->res_port = request_region(chip->port, 256, card->driver)) == NULL) { - snd_via82xx_free(chip); snd_printk("unable to grab ports 0x%lx-0x%lx\n", chip->port, chip->port + 256 - 1); + snd_via82xx_free(chip); return -EBUSY; } if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)chip)) { - snd_via82xx_free(chip); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_via82xx_free(chip); return -EBUSY; } chip->irq = pci->irq; diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index e8139e22e9f0..81f17fd50839 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1880,9 +1880,12 @@ int __devinit snd_ymfpci_joystick(ymfpci_t *chip) static void snd_ymfpci_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) { - // ymfpci_t *chip = snd_magic_cast(ymfpci_t, private_data, return); + ymfpci_t *chip = snd_magic_cast(ymfpci_t, entry->private_data, return); + int i; snd_iprintf(buffer, "YMFPCI\n\n"); + for (i = 0; i <= YDSXGR_WORKBASE; i += 4) + snd_iprintf(buffer, "%04x: %04x\n", i, snd_ymfpci_readl(chip, i)); } static int __devinit snd_ymfpci_proc_init(snd_card_t * card, ymfpci_t *chip) @@ -2285,13 +2288,13 @@ int __devinit snd_ymfpci_create(snd_card_t * card, pci_set_master(pci); if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) { - snd_ymfpci_free(chip); snd_printk("unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); + snd_ymfpci_free(chip); return -EBUSY; } if (request_irq(pci->irq, snd_ymfpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "YMFPCI", (void *) chip)) { - snd_ymfpci_free(chip); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_ymfpci_free(chip); return -EBUSY; } chip->irq = pci->irq; diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 828846242db2..063dbabd3383 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -992,10 +992,10 @@ static int __init snd_amd7930_create(snd_card_t *card, if (request_irq(irq_prop->pri, snd_amd7930_interrupt, SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) { - snd_amd7930_free(amd); snd_printk("amd7930-%d: Unable to grab IRQ %s\n", dev, __irq_itoa(irq_prop->pri)); + snd_amd7930_free(amd); return -EBUSY; } amd->irq = irq_prop->pri; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index ac54f283fe63..36b6710eeb49 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1994,10 +1994,10 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card, if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, SA_SHIRQ, "cs4231", chip)) { - snd_cs4231_sbus_free(chip); snd_printk("cs4231-%d: Unable to grab SBUS IRQ %s\n", dev, __irq_itoa(sdev->irqs[0])); + snd_cs4231_sbus_free(chip); return -EBUSY; } chip->irq[0] = sdev->irqs[0]; diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index cf28b6c928d6..c9a74d3e56bf 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1057,7 +1057,7 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt) int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; int err; - iface = config->interface[fmt->iface]; + iface = get_iface(config, fmt->iface); alts = &iface->altsetting[fmt->altset_idx]; altsd = get_iface_desc(alts); snd_assert(altsd->bAlternateSetting == fmt->altsetting, return -EINVAL); @@ -1182,7 +1182,7 @@ static int snd_usb_hw_params(snd_pcm_substream_t *substream, struct usb_host_config *config = subs->dev->actconfig; struct usb_host_interface *alts; struct usb_interface *iface; - iface = config->interface[fmt->iface]; + iface = get_iface(config, fmt->iface); alts = &iface->altsetting[fmt->altset_idx]; ret = init_usb_sample_rate(subs->dev, subs->interface, alts, fmt, rate); if (ret < 0) @@ -2215,7 +2215,7 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no) config = dev->actconfig; /* parse the interface's altsettings */ - iface = config->interface[iface_no]; + iface = get_iface(config, iface_no); for (i = 0; i < iface->num_altsetting; i++) { alts = &iface->altsetting[i]; altsd = get_iface_desc(alts); @@ -2386,7 +2386,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif) /* find audiocontrol interface */ config = dev->actconfig; - host_iface = &config->interface[ctrlif]->altsetting[0]; + host_iface = &get_iface(config, ctrlif)->altsetting[0]; if (!(p1 = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, NULL, HEADER))) { snd_printk(KERN_ERR "cannot find HEADER\n"); return -EINVAL; @@ -2408,7 +2408,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif) dev->devnum, ctrlif, j); continue; } - iface = config->interface[j]; + iface = get_iface(config, j); if (usb_interface_claimed(iface)) { snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j); continue; @@ -2524,7 +2524,7 @@ static int create_composite_quirk(snd_usb_audio_t *chip, for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) { if (quirk->ifnum >= get_cfg_desc(config)->bNumInterfaces) continue; - iface = config->interface[quirk->ifnum]; + iface = get_iface(config, quirk->ifnum); if (quirk->ifnum != probed_ifnum && usb_interface_claimed(iface)) continue; diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 0f7ffe15e180..2420cabba011 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -210,6 +210,7 @@ void snd_usbmidi_disconnect(struct list_head *p, struct usb_driver *driver); * (conditional for compatibility with the older API) */ #ifndef get_iface_desc +#define get_iface(cfg, num) ((cfg)->interface[(num)]) #define get_iface_desc(iface) (&iface->desc) #define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc) #define get_ep_desc(ep) (&(ep)->desc) diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 01b19aac8269..0d63caf275ed 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -1490,7 +1490,7 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif) int err; const struct usbmix_ctl_map *map; struct usb_device_descriptor *dev = &chip->dev->descriptor; - struct usb_host_interface *hostif = &chip->dev->actconfig->interface[ctrlif]->altsetting[0]; + struct usb_host_interface *hostif = &get_iface(chip->dev->actconfig, ctrlif)->altsetting[0]; strcpy(chip->card->mixername, "USB Mixer"); |
