diff options
author | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-11-06 15:36:37 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-11-06 15:36:37 +0100 |
commit | 2fc2991175bf77395e6b15fe6b2304d3bf72da40 (patch) | |
tree | b0ff38c09240e7c00e1577d447ebe89143d752dc /sound/pci | |
parent | [MTD] mtdchar: Return EINVAL for bad seeks instead of fixing up to valid byte (diff) | |
parent | [PATCH] nvidiafb: Geforce 7800 series support added (diff) | |
download | linux-dev-2fc2991175bf77395e6b15fe6b2304d3bf72da40.tar.xz linux-dev-2fc2991175bf77395e6b15fe6b2304d3bf72da40.zip |
Merge branch 'master' of /home/tglx/work/mtd/git/linux-2.6.git/
Diffstat (limited to 'sound/pci')
74 files changed, 3210 insertions, 1007 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 6d7a00f34d82..a5d593c66f9f 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -1,11 +1,15 @@ # ALSA PCI drivers -menu "PCI devices" - depends on SND!=n && PCI - config SND_AC97_CODEC tristate select SND_PCM + select SND_AC97_BUS + +config SND_AC97_BUS + tristate + +menu "PCI devices" + depends on SND!=n && PCI config SND_ALI5451 tristate "ALi M5451 PCI Audio Controller" @@ -312,9 +316,21 @@ config SND_YMFPCI To compile this driver as a module, choose M here: the module will be called snd-ymfpci. +config SND_AD1889 + tristate "Analog Devices AD1889" + depends on SND + select SND_AC97_CODEC + help + Say Y here to include support for the integrated AC97 sound + device found in particular on the Hewlett-Packard [BCJ]-xxx0 + class PA-RISC workstations, using the AD1819 codec. + + To compile this as a module, choose M here: the module + will be called snd-ad1889. + config SND_ALS4000 tristate "Avance Logic ALS4000" - depends on SND + depends on SND && ISA_DMA_API select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM diff --git a/sound/pci/Makefile b/sound/pci/Makefile index b40575c3349a..42fabfcfc2a9 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile @@ -3,6 +3,7 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # +snd-ad1889-objs := ad1889.o snd-als4000-objs := als4000.o snd-atiixp-objs := atiixp.o snd-atiixp-modem-objs := atiixp_modem.o @@ -25,6 +26,7 @@ snd-via82xx-objs := via82xx.o snd-via82xx-modem-objs := via82xx_modem.o # Toplevel Module Dependency +obj-$(CONFIG_SND_AD1889) += snd-ad1889.o obj-$(CONFIG_SND_ALS4000) += snd-als4000.o obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 3c3222122d8b..77b3482cb133 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile @@ -10,9 +10,11 @@ snd-ac97-codec-objs += ac97_proc.o endif snd-ak4531-codec-objs := ak4531_codec.o +snd-ac97-bus-objs := ac97_bus.o # Toplevel Module Dependency obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o +obj-$(CONFIG_SND_AC97_BUS) += snd-ac97-bus.o obj-m := $(sort $(obj-m)) diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c new file mode 100644 index 000000000000..ec70fadde7d9 --- /dev/null +++ b/sound/pci/ac97/ac97_bus.c @@ -0,0 +1,72 @@ +/* + * Linux driver model AC97 bus interface + * + * Author: Nicolas Pitre + * Created: Jan 14, 2005 + * Copyright: (C) MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/string.h> + +/* + * Let drivers decide whether they want to support given codec from their + * probe method. Drivers have direct access to the ac97_t structure and may + * decide based on the id field amongst other things. + */ +static int ac97_bus_match(struct device *dev, struct device_driver *drv) +{ + return 1; +} + +static int ac97_bus_suspend(struct device *dev, pm_message_t state) +{ + int ret = 0; + + if (dev->driver && dev->driver->suspend) + ret = dev->driver->suspend(dev, state); + + return ret; +} + +static int ac97_bus_resume(struct device *dev) +{ + int ret = 0; + + if (dev->driver && dev->driver->resume) + ret = dev->driver->resume(dev); + + return ret; +} + +struct bus_type ac97_bus_type = { + .name = "ac97", + .match = ac97_bus_match, + .suspend = ac97_bus_suspend, + .resume = ac97_bus_resume, +}; + +static int __init ac97_bus_init(void) +{ + return bus_register(&ac97_bus_type); +} + +subsys_initcall(ac97_bus_init); + +static void __exit ac97_bus_exit(void) +{ + bus_unregister(&ac97_bus_type); +} + +module_exit(ac97_bus_exit); + +EXPORT_SYMBOL(ac97_bus_type); + +MODULE_LICENSE("GPL"); diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 6983eea226da..41fc290149ed 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -112,6 +112,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { { 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */ { 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL }, { 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL }, +{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ { 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, { 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, { 0x414c4730, 0xffffffff, "ALC101", NULL, NULL }, @@ -157,6 +158,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF +{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, @@ -1307,16 +1309,18 @@ static int snd_ac97_mixer_build(ac97_t * ac97) } /* build master tone controls */ - if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { - for (idx = 0; idx < 2; idx++) { - if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) - return err; - if (ac97->id == AC97_ID_YMF753) { - kctl->private_value &= ~(0xff << 16); - kctl->private_value |= 7 << 16; + if (!(ac97->flags & AC97_HAS_NO_TONE)) { + if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { + for (idx = 0; idx < 2; idx++) { + if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) + return err; + if (ac97->id == AC97_ID_YMF753) { + kctl->private_value &= ~(0xff << 16); + kctl->private_value |= 7 << 16; + } } + snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); } - snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); } /* build PC Speaker controls */ @@ -1339,11 +1343,13 @@ static int snd_ac97_mixer_build(ac97_t * ac97) } /* build MIC controls */ - if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { - if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) - return err; - if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) - return err; + if (!(ac97->flags & AC97_HAS_NO_MIC)) { + if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { + if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) + return err; + if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) + return err; + } } /* build Line controls */ @@ -1402,12 +1408,14 @@ static int snd_ac97_mixer_build(ac97_t * ac97) } snd_ac97_write_cache(ac97, AC97_PCM, init_val); } else { - if (ac97->flags & AC97_HAS_NO_PCM_VOL) - err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); - else - err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); - if (err < 0) - return err; + if (!(ac97->flags & AC97_HAS_NO_STD_PCM)) { + if (ac97->flags & AC97_HAS_NO_PCM_VOL) + err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); + else + err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); + if (err < 0) + return err; + } } /* build Capture controls */ @@ -1549,7 +1557,7 @@ static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97) /* build modem switches */ for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++) - if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_modem_switches[idx], ac97))) < 0) + if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ac97_controls_modem_switches[idx], ac97))) < 0) return err; /* build chip specific controls */ @@ -1789,7 +1797,7 @@ int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, snd_assert(card != NULL, return -EINVAL); snd_assert(rbus != NULL, return -EINVAL); - bus = kcalloc(1, sizeof(*bus), GFP_KERNEL); + bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (bus == NULL) return -ENOMEM; bus->card = card; @@ -1807,6 +1815,38 @@ int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, return 0; } +/* stop no dev release warning */ +static void ac97_device_release(struct device * dev) +{ +} + +/* register ac97 codec to bus */ +static int snd_ac97_dev_register(snd_device_t *device) +{ + ac97_t *ac97 = device->device_data; + int err; + + ac97->dev.bus = &ac97_bus_type; + ac97->dev.parent = ac97->bus->card->dev; + ac97->dev.release = ac97_device_release; + snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "card%d-%d", ac97->bus->card->number, ac97->num); + if ((err = device_register(&ac97->dev)) < 0) { + snd_printk(KERN_ERR "Can't register ac97 bus\n"); + ac97->dev.bus = NULL; + return err; + } + return 0; +} + +/* unregister ac97 codec */ +static int snd_ac97_dev_unregister(snd_device_t *device) +{ + ac97_t *ac97 = device->device_data; + if (ac97->dev.bus) + device_unregister(&ac97->dev); + return snd_ac97_free(ac97); +} + /* build_ops to do nothing */ static struct snd_ac97_build_ops null_build_ops; @@ -1840,6 +1880,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) const ac97_codec_id_t *pid; static snd_device_ops_t ops = { .dev_free = snd_ac97_dev_free, + .dev_register = snd_ac97_dev_register, + .dev_unregister = snd_ac97_dev_unregister, }; snd_assert(rac97 != NULL, return -EINVAL); @@ -1863,7 +1905,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) } card = bus->card; - ac97 = kcalloc(1, sizeof(*ac97), GFP_KERNEL); + ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); if (ac97 == NULL) return -ENOMEM; ac97->private_data = template->private_data; @@ -2539,8 +2581,6 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *o { int result; - snd_assert(quirk, return -EINVAL); - /* quirk overriden? */ if (override && strcmp(override, "-1") && strcmp(override, "default")) { result = apply_quirk_str(ac97, override); @@ -2549,6 +2589,9 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *o return result; } + if (! quirk) + return -EINVAL; + for (; quirk->subvendor; quirk++) { if (quirk->subvendor != ac97->subsystem_vendor) continue; diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h index dadf387ad0b8..6d73514dc49e 100644 --- a/sound/pci/ac97/ac97_id.h +++ b/sound/pci/ac97/ac97_id.h @@ -52,6 +52,7 @@ #define AC97_ID_ALC650F 0x414c4723 #define AC97_ID_ALC655 0x414c4760 #define AC97_ID_ALC658 0x414c4780 +#define AC97_ID_ALC658D 0x414c4781 #define AC97_ID_ALC850 0x414c4790 #define AC97_ID_YMF753 0x594d4803 #define AC97_ID_VT1616 0x49434551 diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 66edc857d3e6..0238cc65d32a 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -370,141 +370,387 @@ int patch_yamaha_ymf753(ac97_t * ac97) * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. */ -int patch_wolfson03(ac97_t * ac97) +static const snd_kcontrol_new_t wm97xx_snd_ac97_controls[] = { +AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), +AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), +}; + +static int patch_wolfson_wm9703_specific(ac97_t * ac97) { /* This is known to work for the ViewSonic ViewPad 1000 - Randolph Bentson <bentson@holmsjoen.com> */ + * Randolph Bentson <bentson@holmsjoen.com> + * WM9703/9707/9708/9717 + */ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { + if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) + return err; + } + snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); + return 0; +} + +static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { + .build_specific = patch_wolfson_wm9703_specific, +}; - // WM9703/9707/9708/9717 - snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); - snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x8000); +int patch_wolfson03(ac97_t * ac97) +{ + ac97->build_ops = &patch_wolfson_wm9703_ops; return 0; } - -int patch_wolfson04(ac97_t * ac97) + +static const snd_kcontrol_new_t wm9704_snd_ac97_controls[] = { +AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), +AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), +AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1), +AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1), +AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1), +AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), +}; + +static int patch_wolfson_wm9704_specific(ac97_t * ac97) { - // WM9704M/9704Q - // set front and rear mixer volume - snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); - snd_ac97_write_cache(ac97, AC97_WM9704_RMIXER_VOL, 0x0808); - - // patch for DVD noise + int err, i; + for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) { + if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97))) < 0) + return err; + } + /* patch for DVD noise */ snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); - - // init vol - snd_ac97_write_cache(ac97, AC97_WM9704_RPCM_VOL, 0x0808); - - // set rear surround volume - snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000); return 0; } - + +static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { + .build_specific = patch_wolfson_wm9704_specific, +}; + +int patch_wolfson04(ac97_t * ac97) +{ + /* WM9704M/9704Q */ + ac97->build_ops = &patch_wolfson_wm9704_ops; + return 0; +} + +static int patch_wolfson_wm9705_specific(ac97_t * ac97) +{ + int err, i; + for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { + if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) + return err; + } + snd_ac97_write_cache(ac97, 0x72, 0x0808); + return 0; +} + +static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { + .build_specific = patch_wolfson_wm9705_specific, +}; + int patch_wolfson05(ac97_t * ac97) { - // WM9705, WM9710 - // set front mixer volume - snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); + /* WM9705, WM9710 */ + ac97->build_ops = &patch_wolfson_wm9705_ops; + return 0; +} + +static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"}; +static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"}; +static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"}; +static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"}; +static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"}; +static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"}; +static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; +static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"}; +static const char* wm9711_rec_sel[] = + {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"}; +static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"}; + +static const struct ac97_enum wm9711_enum[] = { +AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select), +AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix), +AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src), +AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc), +AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc), +AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base), +AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain), +AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic), +AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel), +AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type), +}; + +static const snd_kcontrol_new_t wm9711_snd_ac97_controls[] = { +AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), +AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), +AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), +AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), +AC97_ENUM("ALC Function", wm9711_enum[0]), +AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1), +AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1), +AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), +AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), +AC97_ENUM("ALC NG Type", wm9711_enum[9]), +AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1), + +AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1), +AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1), +AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]), +AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), + +AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), +AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), +AC97_ENUM("Out3 Mux", wm9711_enum[2]), +AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), +AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), + +AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), +AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1), +AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1), +AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1), +AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1), +AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1), + +AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1), +AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1), +AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1), +AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1), +AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1), +AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1), + +AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1), +AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1), + +AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1), +AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1), +AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1), + +AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1), +AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1), +AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1), + +AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), +AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]), +AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), +AC97_ENUM("Capture Select", wm9711_enum[8]), + +AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), +AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), + +AC97_ENUM("Bass Control", wm9711_enum[5]), +AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1), +AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1), +AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), + +AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), +AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), +AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1), +AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), + +AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), +AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), +AC97_ENUM("Mic Select Source", wm9711_enum[7]), +AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1), +AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), + +AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), +AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0), +AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0), +}; + +static int patch_wolfson_wm9711_specific(ac97_t * ac97) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) { + if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97))) < 0) + return err; + } + snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808); + snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808); + snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808); + snd_ac97_write_cache(ac97, AC97_AUX, 0x0808); + snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); + snd_ac97_write_cache(ac97, AC97_CD, 0x0000); return 0; } +static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { + .build_specific = patch_wolfson_wm9711_specific, +}; + int patch_wolfson11(ac97_t * ac97) { - // WM9711, WM9712 - // set out3 volume - snd_ac97_write_cache(ac97, AC97_WM9711_OUT3VOL, 0x0808); + /* WM9711, WM9712 */ + ac97->build_ops = &patch_wolfson_wm9711_ops; + + ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC | + AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; + return 0; } -static const char* wm9713_mic_mixer[] = {"Stereo", "Mic1", "Mic2", "Mute"}; +static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; -static const char* wm9713_rec_src_l[] = {"Mic1", "Mic2", "Line L", "Mono In", "HP Mix L", "Spk Mix", "Mono Mix", "Zh"}; -static const char* wm9713_rec_src_r[] = {"Mic1", "Mic2", "Line R", "Mono In", "HP Mix R", "Spk Mix", "Mono Mix", "Zh"}; +static const char* wm9713_rec_src[] = + {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix", + "Mono Mix", "Zh"}; +static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; +static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"}; +static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"}; +static const char* wm9713_spk_pga[] = + {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"}; +static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"}; +static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"}; +static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"}; +static const char* wm9713_dac_inv[] = + {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R", + "Headphone Mix Mono", "NC", "Vmid"}; +static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"}; +static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"}; static const struct ac97_enum wm9713_enum[] = { AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), -AC97_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src_l), -AC97_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src_r), +AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src), +AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain), +AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select), +AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga), +AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga), +AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga), +AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga), +AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga), +AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv), +AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base), +AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), }; -static const snd_kcontrol_new_t wm13_snd_ac97_controls_line_in[] = { +static const snd_kcontrol_new_t wm13_snd_ac97_controls[] = { AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), -AC97_SINGLE("Line In to Headphone Mute", AC97_PC_BEEP, 15, 1, 1), -AC97_SINGLE("Line In to Speaker Mute", AC97_PC_BEEP, 14, 1, 1), -AC97_SINGLE("Line In to Mono Mute", AC97_PC_BEEP, 13, 1, 1), -}; - -static const snd_kcontrol_new_t wm13_snd_ac97_controls_dac[] = { -AC97_DOUBLE("DAC Volume", AC97_PHONE, 8, 0, 31, 1), -AC97_SINGLE("DAC to Headphone Mute", AC97_PHONE, 15, 1, 1), -AC97_SINGLE("DAC to Speaker Mute", AC97_PHONE, 14, 1, 1), -AC97_SINGLE("DAC to Mono Mute", AC97_PHONE, 13, 1, 1), +AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), +AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1), +AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1), + +AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), +AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1), +AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1), +AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1), + +AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), +AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), +AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1), +AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1), +AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), +AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]), +AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), + +AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1), +AC97_ENUM("Capture Volume Steps", wm9713_enum[4]), +AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0), +AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), + +AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]), +AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), +AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]), +AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), +AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), +AC97_ENUM("Capture Select", wm9713_enum[3]), + +AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), +AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), +AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), +AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), +AC97_ENUM("ALC Function", wm9713_enum[5]), +AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), +AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0), +AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), +AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), +AC97_ENUM("ALC NG Type", wm9713_enum[13]), +AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0), + +AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0), +AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0), +AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0), +AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1), +AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1), +AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1), + +AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1), +AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1), +AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1), +AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1), +AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0), +AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1), + +AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1), +AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1), +AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1), +AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1), +AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1), +AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1), + +AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1), +AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1), +AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1), +AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1), +AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1), +AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1), + +AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1), +AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1), +AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1), +AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1), +AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1), +AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1), + +AC97_ENUM("Mono Input Mux", wm9713_enum[6]), +AC97_ENUM("Master Input Mux", wm9713_enum[7]), +AC97_ENUM("Headphone Input Mux", wm9713_enum[8]), +AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]), +AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]), + +AC97_ENUM("Bass Control", wm9713_enum[12]), +AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), +AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1), +AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0), +AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1), +AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1), }; -static const snd_kcontrol_new_t wm13_snd_ac97_controls_mic[] = { -AC97_SINGLE("MICA Volume", AC97_MIC, 8, 31, 1), -AC97_SINGLE("MICB Volume", AC97_MIC, 0, 31, 1), -AC97_SINGLE("MICA to Mono Mute", AC97_LINE, 7, 1, 1), -AC97_SINGLE("MICB to Mono Mute", AC97_LINE, 6, 1, 1), -AC97_SINGLE("MIC Boost (+20dB)", AC97_LINE, 5, 1, 1), -AC97_ENUM("MIC Headphone Routing", wm9713_enum[0]), -AC97_SINGLE("MIC Headphone Mixer Volume", AC97_LINE, 0, 7, 1) +static const snd_kcontrol_new_t wm13_snd_ac97_controls_3d[] = { +AC97_ENUM("Inv Input Mux", wm9713_enum[11]), +AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0), +AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), +AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), }; -static const snd_kcontrol_new_t wm13_snd_ac97_controls_adc[] = { -AC97_SINGLE("ADC Mute", AC97_CD, 15, 1, 1), -AC97_DOUBLE("Gain Step Size (1.5dB/0.75dB)", AC97_CD, 14, 6, 1, 1), -AC97_DOUBLE("ADC Volume",AC97_CD, 8, 0, 15, 0), -AC97_SINGLE("ADC Zero Cross", AC97_CD, 7, 1, 1), -}; - -static const snd_kcontrol_new_t wm13_snd_ac97_controls_recsel[] = { -AC97_ENUM("Record to Headphone Path", wm9713_enum[1]), -AC97_SINGLE("Record to Headphone Volume", AC97_VIDEO, 11, 7, 0), -AC97_ENUM("Record to Mono Path", wm9713_enum[2]), -AC97_SINGLE("Record to Mono Boost (+20dB)", AC97_VIDEO, 8, 1, 0), -AC97_SINGLE("Record ADC Boost (+20dB)", AC97_VIDEO, 6, 1, 0), -AC97_ENUM("Record Select Left", wm9713_enum[3]), -AC97_ENUM("Record Select Right", wm9713_enum[4]), -}; +static int patch_wolfson_wm9713_3d (ac97_t * ac97) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) { + if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97))) < 0) + return err; + } + return 0; +} static int patch_wolfson_wm9713_specific(ac97_t * ac97) { int err, i; - for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_line_in); i++) { - if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_line_in[i], ac97))) < 0) + for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) { + if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97))) < 0) return err; } snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); - - for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_dac); i++) { - if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_dac[i], ac97))) < 0) - return err; - } snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); - - for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_mic); i++) { - if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_mic[i], ac97))) < 0) - return err; - } snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); - - for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_adc); i++) { - if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_adc[i], ac97))) < 0) - return err; - } snd_ac97_write_cache(ac97, AC97_CD, 0x0808); - - for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_recsel); i++) { - if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_recsel[i], ac97))) < 0) - return err; - } snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); - return 0; } @@ -525,6 +771,7 @@ static void patch_wolfson_wm9713_resume (ac97_t * ac97) static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { .build_specific = patch_wolfson_wm9713_specific, + .build_3d = patch_wolfson_wm9713_3d, #ifdef CONFIG_PM .suspend = patch_wolfson_wm9713_suspend, .resume = patch_wolfson_wm9713_resume @@ -533,10 +780,13 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { int patch_wolfson13(ac97_t * ac97) { + /* WM9713, WM9714 */ ac97->build_ops = &patch_wolfson_wm9713_ops; ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | - AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; + AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE | + AC97_HAS_NO_STD_PCM; + ac97->scaps &= ~AC97_SCAP_MODEM; snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); @@ -1379,6 +1629,7 @@ static void check_ad1981_hp_jack_sense(ac97_t *ac97) u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; switch (subid) { case 0x103c0890: /* HP nc6000 */ + case 0x103c099c: /* HP nx6110 */ case 0x103c006d: /* HP nx9105 */ case 0x17340088: /* FSC Scenic-W */ /* enable headphone jack sense */ @@ -1706,7 +1957,7 @@ static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { }; static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { - AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0), + AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0), AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), /* disable this controls since it doesn't work as expected */ /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ @@ -1849,12 +2100,12 @@ static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_ } static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = { - AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0), + AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0), /* disable this controls since it doesn't work as expected */ /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Playback Route", + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = alc655_iec958_route_info, .get = alc655_iec958_route_get, .put = alc655_iec958_route_put, @@ -1883,7 +2134,13 @@ int patch_alc655(ac97_t * ac97) { unsigned int val; - ac97->spec.dev_flags = (ac97->id == 0x414c4780); /* ALC658 */ + if (ac97->id == AC97_ID_ALC658) { + ac97->spec.dev_flags = 1; /* ALC658 */ + if ((snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f) == 2) { + ac97->id = AC97_ID_ALC658D; + ac97->spec.dev_flags = 2; + } + } ac97->build_ops = &patch_alc655_ops; @@ -1892,10 +2149,15 @@ int patch_alc655(ac97_t * ac97) /* adjust default values */ val = snd_ac97_read(ac97, 0x7a); /* misc control */ - if (ac97->id == 0x414c4780) /* ALC658 */ + if (ac97->spec.dev_flags) /* ALC658 */ val &= ~(1 << 1); /* Pin 47 is spdif input pin */ - else /* ALC655 */ - val |= (1 << 1); /* Pin 47 is spdif input pin */ + else { /* ALC655 */ + if (ac97->subsystem_vendor == 0x1462 && + ac97->subsystem_device == 0x0131) /* MSI S270 laptop */ + val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ + else + val |= (1 << 1); /* Pin 47 is spdif input pin */ + } val &= ~(1 << 12); /* vref enable */ snd_ac97_write_cache(ac97, 0x7a, val); /* set default: spdif-in enabled, @@ -1908,6 +2170,11 @@ int patch_alc655(ac97_t * ac97) /* full DAC volume */ snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); + + /* update undocumented bit... */ + if (ac97->id == AC97_ID_ALC658D) + snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800); + return 0; } @@ -2416,6 +2683,16 @@ int patch_vt1616(ac97_t * ac97) } /* + * VT1617A codec + */ +int patch_vt1617a(ac97_t * ac97) +{ + ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ + ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; + return 0; +} + +/* */ static void it2646_update_jacks(ac97_t *ac97) { @@ -2433,7 +2710,7 @@ static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = { }; static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { - AC97_SINGLE("IEC958 Capture Switch", 0x76, 11, 1, 0), + AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0), AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0), AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0), }; @@ -2475,7 +2752,11 @@ AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1) static int patch_si3036_specific(ac97_t * ac97) { - return patch_build_controls(ac97, snd_ac97_controls_si3036, ARRAY_SIZE(snd_ac97_controls_si3036)); + int idx, err; + for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++) + if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_si3036[idx], ac97))) < 0) + return err; + return 0; } static struct snd_ac97_build_ops patch_si3036_ops = { diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 7b7377d0f2ae..ec1811320106 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h @@ -56,5 +56,6 @@ int patch_cm9739(ac97_t * ac97); int patch_cm9761(ac97_t * ac97); int patch_cm9780(ac97_t * ac97); int patch_vt1616(ac97_t * ac97); +int patch_vt1617a(ac97_t * ac97); int patch_it2646(ac97_t * ac97); int mpatch_si3036(ac97_t * ac97); diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c index f9ce0fd2f52f..4032c5748370 100644 --- a/sound/pci/ac97/ak4531_codec.c +++ b/sound/pci/ac97/ak4531_codec.c @@ -357,7 +357,7 @@ int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531) snd_assert(rak4531 != NULL, return -EINVAL); *rak4531 = NULL; snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL); - ak4531 = kcalloc(1, sizeof(*ak4531), GFP_KERNEL); + ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL); if (ak4531 == NULL) return -ENOMEM; *ak4531 = *_ak4531; diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c new file mode 100644 index 000000000000..d7d99a25c5e5 --- /dev/null +++ b/sound/pci/ad1889.c @@ -0,0 +1,1090 @@ +/* Analog Devices 1889 audio driver + * + * This is a driver for the AD1889 PCI audio chipset found + * on the HP PA-RISC [BCJ]-xxx0 workstations. + * + * Copyright (C) 2004-2005, Kyle McMartin <kyle@parisc-linux.org> + * Copyright (C) 2005, Thibaut Varene <varenet@parisc-linux.org> + * Based on the OSS AD1889 driver by Randolph Chung <tausq@debian.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * TODO: + * Do we need to take care of CCS register? + * Maybe we could use finer grained locking (separate locks for pb/cap)? + * Wishlist: + * Control Interface (mixer) support + * Better AC97 support (VSR...)? + * PM support + * MIDI support + * Game Port support + * SG DMA support (this will need *alot* of work) + */ + +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/compiler.h> +#include <linux/delay.h> + +#include <sound/driver.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/initval.h> +#include <sound/ac97_codec.h> + +#include <asm/io.h> + +#include "ad1889.h" +#include "ac97/ac97_id.h" + +#define AD1889_DRVVER "$Revision: 1.3 $" + +MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>"); +MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}"); + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard."); + +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard."); + +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable AD1889 soundcard."); + +static char *ac97_quirk[SNDRV_CARDS]; +module_param_array(ac97_quirk, charp, NULL, 0444); +MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); + +#define DEVNAME "ad1889" +#define PFX DEVNAME ": " + +/* let's use the global sound debug interfaces */ +#define ad1889_debug(fmt, arg...) snd_printd(KERN_DEBUG fmt, ## arg) + +/* keep track of some hw registers */ +struct ad1889_register_state { + u16 reg; /* reg setup */ + u32 addr; /* dma base address */ + unsigned long size; /* DMA buffer size */ +}; + +struct snd_ad1889 { + snd_card_t *card; + struct pci_dev *pci; + + int irq; + unsigned long bar; + void __iomem *iobase; + + ac97_t *ac97; + ac97_bus_t *ac97_bus; + snd_pcm_t *pcm; + snd_info_entry_t *proc; + + snd_pcm_substream_t *psubs; + snd_pcm_substream_t *csubs; + + /* playback register state */ + struct ad1889_register_state wave; + struct ad1889_register_state ramc; + + spinlock_t lock; +}; + +static inline u16 +ad1889_readw(struct snd_ad1889 *chip, unsigned reg) +{ + return readw(chip->iobase + reg); +} + +static inline void +ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val) +{ + writew(val, chip->iobase + reg); +} + +static inline u32 +ad1889_readl(struct snd_ad1889 *chip, unsigned reg) +{ + return readl(chip->iobase + reg); +} + +static inline void +ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val) +{ + writel(val, chip->iobase + reg); +} + +static inline void +ad1889_unmute(struct snd_ad1889 *chip) +{ + u16 st; + st = ad1889_readw(chip, AD_DS_WADA) & + ~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM); + ad1889_writew(chip, AD_DS_WADA, st); + ad1889_readw(chip, AD_DS_WADA); +} + +static inline void +ad1889_mute(struct snd_ad1889 *chip) +{ + u16 st; + st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM; + ad1889_writew(chip, AD_DS_WADA, st); + ad1889_readw(chip, AD_DS_WADA); +} + +static inline void +ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address) +{ + ad1889_writel(chip, AD_DMA_ADCBA, address); + ad1889_writel(chip, AD_DMA_ADCCA, address); +} + +static inline void +ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count) +{ + ad1889_writel(chip, AD_DMA_ADCBC, count); + ad1889_writel(chip, AD_DMA_ADCCC, count); +} + +static inline void +ad1889_load_adc_interrupt_count(struct snd_ad1889 *chip, u32 count) +{ + ad1889_writel(chip, AD_DMA_ADCIB, count); + ad1889_writel(chip, AD_DMA_ADCIC, count); +} + +static inline void +ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address) +{ + ad1889_writel(chip, AD_DMA_WAVBA, address); + ad1889_writel(chip, AD_DMA_WAVCA, address); +} + +static inline void +ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count) +{ + ad1889_writel(chip, AD_DMA_WAVBC, count); + ad1889_writel(chip, AD_DMA_WAVCC, count); +} + +static inline void +ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count) +{ + ad1889_writel(chip, AD_DMA_WAVIB, count); + ad1889_writel(chip, AD_DMA_WAVIC, count); +} + +static void +ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel) +{ + u16 reg; + + if (channel & AD_CHAN_WAV) { + /* Disable wave channel */ + reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN; + ad1889_writew(chip, AD_DS_WSMC, reg); + chip->wave.reg = reg; + + /* disable IRQs */ + reg = ad1889_readw(chip, AD_DMA_WAV); + reg &= AD_DMA_IM_DIS; + reg &= ~AD_DMA_LOOP; + ad1889_writew(chip, AD_DMA_WAV, reg); + + /* clear IRQ and address counters and pointers */ + ad1889_load_wave_buffer_address(chip, 0x0); + ad1889_load_wave_buffer_count(chip, 0x0); + ad1889_load_wave_interrupt_count(chip, 0x0); + + /* flush */ + ad1889_readw(chip, AD_DMA_WAV); + } + + if (channel & AD_CHAN_ADC) { + /* Disable ADC channel */ + reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN; + ad1889_writew(chip, AD_DS_RAMC, reg); + chip->ramc.reg = reg; + + reg = ad1889_readw(chip, AD_DMA_ADC); + reg &= AD_DMA_IM_DIS; + reg &= ~AD_DMA_LOOP; + ad1889_writew(chip, AD_DMA_ADC, reg); + + ad1889_load_adc_buffer_address(chip, 0x0); + ad1889_load_adc_buffer_count(chip, 0x0); + ad1889_load_adc_interrupt_count(chip, 0x0); + + /* flush */ + ad1889_readw(chip, AD_DMA_ADC); + } +} + +static inline u16 +snd_ad1889_ac97_read(ac97_t *ac97, unsigned short reg) +{ + struct snd_ad1889 *chip = ac97->private_data; + return ad1889_readw(chip, AD_AC97_BASE + reg); +} + +static inline void +snd_ad1889_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) +{ + struct snd_ad1889 *chip = ac97->private_data; + ad1889_writew(chip, AD_AC97_BASE + reg, val); +} + +static int +snd_ad1889_ac97_ready(struct snd_ad1889 *chip) +{ + int retry = 400; /* average needs 352 msec */ + + while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY) + && --retry) + mdelay(1); + if (!retry) { + snd_printk(KERN_ERR PFX "[%s] Link is not ready.\n", + __FUNCTION__); + return -EIO; + } + ad1889_debug("[%s] ready after %d ms\n", __FUNCTION__, 400 - retry); + + return 0; +} + +static int +snd_ad1889_hw_params(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *hw_params) +{ + return snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); +} + +static int +snd_ad1889_hw_free(snd_pcm_substream_t *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + +static snd_pcm_hardware_t snd_ad1889_playback_hw = { + .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, /* docs say 7000, but we're lazy */ + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = BUFFER_BYTES_MAX, + .period_bytes_min = PERIOD_BYTES_MIN, + .period_bytes_max = PERIOD_BYTES_MAX, + .periods_min = PERIODS_MIN, + .periods_max = PERIODS_MAX, + /*.fifo_size = 0,*/ +}; + +static snd_pcm_hardware_t snd_ad1889_capture_hw = { + .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, /* docs say we could to VSR, but we're lazy */ + .rate_max = 48000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = BUFFER_BYTES_MAX, + .period_bytes_min = PERIOD_BYTES_MIN, + .period_bytes_max = PERIOD_BYTES_MAX, + .periods_min = PERIODS_MIN, + .periods_max = PERIODS_MAX, + /*.fifo_size = 0,*/ +}; + +static int +snd_ad1889_playback_open(snd_pcm_substream_t *ss) +{ + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + snd_pcm_runtime_t *rt = ss->runtime; + + chip->psubs = ss; + rt->hw = snd_ad1889_playback_hw; + + return 0; +} + +static int +snd_ad1889_capture_open(snd_pcm_substream_t *ss) +{ + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + snd_pcm_runtime_t *rt = ss->runtime; + + chip->csubs = ss; + rt->hw = snd_ad1889_capture_hw; + + return 0; +} + +static int +snd_ad1889_playback_close(snd_pcm_substream_t *ss) +{ + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + chip->psubs = NULL; + return 0; +} + +static int +snd_ad1889_capture_close(snd_pcm_substream_t *ss) +{ + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + chip->csubs = NULL; + return 0; +} + +static int +snd_ad1889_playback_prepare(snd_pcm_substream_t *ss) +{ + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + snd_pcm_runtime_t *rt = ss->runtime; + unsigned int size = snd_pcm_lib_buffer_bytes(ss); + unsigned int count = snd_pcm_lib_period_bytes(ss); + u16 reg; + + ad1889_channel_reset(chip, AD_CHAN_WAV); + + reg = ad1889_readw(chip, AD_DS_WSMC); + + /* Mask out 16-bit / Stereo */ + reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST); + + if (snd_pcm_format_width(rt->format) == 16) + reg |= AD_DS_WSMC_WA16; + + if (rt->channels > 1) + reg |= AD_DS_WSMC_WAST; + + /* let's make sure we don't clobber ourselves */ + spin_lock_irq(&chip->lock); + + chip->wave.size = size; + chip->wave.reg = reg; + chip->wave.addr = rt->dma_addr; + + ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg); + + /* Set sample rates on the codec */ + ad1889_writew(chip, AD_DS_WAS, rt->rate); + + /* Set up DMA */ + ad1889_load_wave_buffer_address(chip, chip->wave.addr); + ad1889_load_wave_buffer_count(chip, size); + ad1889_load_wave_interrupt_count(chip, count); + + /* writes flush */ + ad1889_readw(chip, AD_DS_WSMC); + + spin_unlock_irq(&chip->lock); + + ad1889_debug("prepare playback: addr = 0x%x, count = %u, " + "size = %u, reg = 0x%x, rate = %u\n", chip->wave.addr, + count, size, reg, rt->rate); + return 0; +} + +static int +snd_ad1889_capture_prepare(snd_pcm_substream_t *ss) +{ + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + snd_pcm_runtime_t *rt = ss->runtime; + unsigned int size = snd_pcm_lib_buffer_bytes(ss); + unsigned int count = snd_pcm_lib_period_bytes(ss); + u16 reg; + + ad1889_channel_reset(chip, AD_CHAN_ADC); + + reg = ad1889_readw(chip, AD_DS_RAMC); + + /* Mask out 16-bit / Stereo */ + reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST); + + if (snd_pcm_format_width(rt->format) == 16) + reg |= AD_DS_RAMC_AD16; + + if (rt->channels > 1) + reg |= AD_DS_RAMC_ADST; + + /* let's make sure we don't clobber ourselves */ + spin_lock_irq(&chip->lock); + + chip->ramc.size = size; + chip->ramc.reg = reg; + chip->ramc.addr = rt->dma_addr; + + ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg); + + /* Set up DMA */ + ad1889_load_adc_buffer_address(chip, chip->ramc.addr); + ad1889_load_adc_buffer_count(chip, size); + ad1889_load_adc_interrupt_count(chip, count); + + /* writes flush */ + ad1889_readw(chip, AD_DS_RAMC); + + spin_unlock_irq(&chip->lock); + + ad1889_debug("prepare capture: addr = 0x%x, count = %u, " + "size = %u, reg = 0x%x, rate = %u\n", chip->ramc.addr, + count, size, reg, rt->rate); + return 0; +} + +/* this is called in atomic context with IRQ disabled. + Must be as fast as possible and not sleep. + DMA should be *triggered* by this call. + The WSMC "WAEN" bit triggers DMA Wave On/Off */ +static int +snd_ad1889_playback_trigger(snd_pcm_substream_t *ss, int cmd) +{ + u16 wsmc; + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + + wsmc = ad1889_readw(chip, AD_DS_WSMC); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* enable DMA loop & interrupts */ + ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT); + wsmc |= AD_DS_WSMC_WAEN; + /* 1 to clear CHSS bit */ + ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS); + ad1889_unmute(chip); + break; + case SNDRV_PCM_TRIGGER_STOP: + ad1889_mute(chip); + wsmc &= ~AD_DS_WSMC_WAEN; + break; + default: + snd_BUG(); + return -EINVAL; + } + + chip->wave.reg = wsmc; + ad1889_writew(chip, AD_DS_WSMC, wsmc); + ad1889_readw(chip, AD_DS_WSMC); /* flush */ + + /* reset the chip when STOP - will disable IRQs */ + if (cmd == SNDRV_PCM_TRIGGER_STOP) + ad1889_channel_reset(chip, AD_CHAN_WAV); + + return 0; +} + +/* this is called in atomic context with IRQ disabled. + Must be as fast as possible and not sleep. + DMA should be *triggered* by this call. + The RAMC "ADEN" bit triggers DMA ADC On/Off */ +static int +snd_ad1889_capture_trigger(snd_pcm_substream_t *ss, int cmd) +{ + u16 ramc; + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + + ramc = ad1889_readw(chip, AD_DS_RAMC); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* enable DMA loop & interrupts */ + ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT); + ramc |= AD_DS_RAMC_ADEN; + /* 1 to clear CHSS bit */ + ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS); + break; + case SNDRV_PCM_TRIGGER_STOP: + ramc &= ~AD_DS_RAMC_ADEN; + break; + default: + return -EINVAL; + } + + chip->ramc.reg = ramc; + ad1889_writew(chip, AD_DS_RAMC, ramc); + ad1889_readw(chip, AD_DS_RAMC); /* flush */ + + /* reset the chip when STOP - will disable IRQs */ + if (cmd == SNDRV_PCM_TRIGGER_STOP) + ad1889_channel_reset(chip, AD_CHAN_ADC); + + return 0; +} + +/* Called in atomic context with IRQ disabled */ +static snd_pcm_uframes_t +snd_ad1889_playback_pointer(snd_pcm_substream_t *ss) +{ + size_t ptr = 0; + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + + if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN))) + return 0; + + ptr = ad1889_readl(chip, AD_DMA_WAVCA); + ptr -= chip->wave.addr; + + snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0); + + return bytes_to_frames(ss->runtime, ptr); +} + +/* Called in atomic context with IRQ disabled */ +static snd_pcm_uframes_t +snd_ad1889_capture_pointer(snd_pcm_substream_t *ss) +{ + size_t ptr = 0; + struct snd_ad1889 *chip = snd_pcm_substream_chip(ss); + + if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN))) + return 0; + + ptr = ad1889_readl(chip, AD_DMA_ADCCA); + ptr -= chip->ramc.addr; + + snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0); + + return bytes_to_frames(ss->runtime, ptr); +} + +static snd_pcm_ops_t snd_ad1889_playback_ops = { + .open = snd_ad1889_playback_open, + .close = snd_ad1889_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_ad1889_hw_params, + .hw_free = snd_ad1889_hw_free, + .prepare = snd_ad1889_playback_prepare, + .trigger = snd_ad1889_playback_trigger, + .pointer = snd_ad1889_playback_pointer, +}; + +static snd_pcm_ops_t snd_ad1889_capture_ops = { + .open = snd_ad1889_capture_open, + .close = snd_ad1889_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_ad1889_hw_params, + .hw_free = snd_ad1889_hw_free, + .prepare = snd_ad1889_capture_prepare, + .trigger = snd_ad1889_capture_trigger, + .pointer = snd_ad1889_capture_pointer, +}; + +static irqreturn_t +snd_ad1889_interrupt(int irq, + void *dev_id, + struct pt_regs *regs) +{ + unsigned long st; + struct snd_ad1889 *chip = dev_id; + + st = ad1889_readl(chip, AD_DMA_DISR); + + /* clear ISR */ + ad1889_writel(chip, AD_DMA_DISR, st); + + st &= AD_INTR_MASK; + + if (unlikely(!st)) + return IRQ_NONE; + + if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI)) + ad1889_debug("Unexpected master or target abort interrupt!\n"); + + if ((st & AD_DMA_DISR_WAVI) && chip->psubs) + snd_pcm_period_elapsed(chip->psubs); + if ((st & AD_DMA_DISR_ADCI) && chip->csubs) + snd_pcm_period_elapsed(chip->csubs); + + return IRQ_HANDLED; +} + +static void +snd_ad1889_pcm_free(snd_pcm_t *pcm) +{ + struct snd_ad1889 *chip = pcm->private_data; + chip->pcm = NULL; + snd_pcm_lib_preallocate_free_for_all(pcm); +} + +static int __devinit +snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, snd_pcm_t **rpcm) +{ + int err; + snd_pcm_t *pcm; + + if (rpcm) + *rpcm = NULL; + + err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm); + if (err < 0) + return err; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_ad1889_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_ad1889_capture_ops); + + pcm->private_data = chip; + pcm->private_free = snd_ad1889_pcm_free; + pcm->info_flags = 0; + strcpy(pcm->name, chip->card->shortname); + + chip->pcm = pcm; + chip->psubs = NULL; + chip->csubs = NULL; + + err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + BUFFER_BYTES_MAX / 2, + BUFFER_BYTES_MAX); + + if (err < 0) { + snd_printk(KERN_ERR PFX "buffer allocation error: %d\n", err); + return err; + } + + if (rpcm) + *rpcm = pcm; + + return 0; +} + +static void +snd_ad1889_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) +{ + struct snd_ad1889 *chip = entry->private_data; + u16 reg; + int tmp; + + reg = ad1889_readw(chip, AD_DS_WSMC); + snd_iprintf(buffer, "Wave output: %s\n", + (reg & AD_DS_WSMC_WAEN) ? "enabled" : "disabled"); + snd_iprintf(buffer, "Wave Channels: %s\n", + (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); + snd_iprintf(buffer, "Wave Quality: %d-bit linear\n", + (reg & AD_DS_WSMC_WA16) ? 16 : 8); + + /* WARQ is at offset 12 */ + tmp = (reg & AD_DS_WSMC_WARQ) ? + (((reg & AD_DS_WSMC_WARQ >> 12) & 0x01) ? 12 : 18) : 4; + tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1; + + snd_iprintf(buffer, "Wave FIFO: %d %s words\n\n", tmp, + (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); + + + snd_iprintf(buffer, "Synthesis output: %s\n", + reg & AD_DS_WSMC_SYEN ? "enabled" : "disabled"); + + /* SYRQ is at offset 4 */ + tmp = (reg & AD_DS_WSMC_SYRQ) ? + (((reg & AD_DS_WSMC_SYRQ >> 4) & 0x01) ? 12 : 18) : 4; + tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1; + + snd_iprintf(buffer, "Synthesis FIFO: %d %s words\n\n", tmp, + (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); + + reg = ad1889_readw(chip, AD_DS_RAMC); + snd_iprintf(buffer, "ADC input: %s\n", + (reg & AD_DS_RAMC_ADEN) ? "enabled" : "disabled"); + snd_iprintf(buffer, "ADC Channels: %s\n", + (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono"); + snd_iprintf(buffer, "ADC Quality: %d-bit linear\n", + (reg & AD_DS_RAMC_AD16) ? 16 : 8); + + /* ACRQ is at offset 4 */ + tmp = (reg & AD_DS_RAMC_ACRQ) ? + (((reg & AD_DS_RAMC_ACRQ >> 4) & 0x01) ? 12 : 18) : 4; + tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1; + + snd_iprintf(buffer, "ADC FIFO: %d %s words\n\n", tmp, + (reg & AD_DS_RAMC_ADST) ? "stereo" : "mono"); + + snd_iprintf(buffer, "Resampler input: %s\n", + reg & AD_DS_RAMC_REEN ? "enabled" : "disabled"); + + /* RERQ is at offset 12 */ + tmp = (reg & AD_DS_RAMC_RERQ) ? + (((reg & AD_DS_RAMC_RERQ >> 12) & 0x01) ? 12 : 18) : 4; + tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1; + + snd_iprintf(buffer, "Resampler FIFO: %d %s words\n\n", tmp, + (reg & AD_DS_WSMC_WAST) ? "stereo" : "mono"); + + + /* doc says LSB represents -1.5dB, but the max value (-94.5dB) + suggests that LSB is -3dB, which is more coherent with the logarithmic + nature of the dB scale */ + reg = ad1889_readw(chip, AD_DS_WADA); + snd_iprintf(buffer, "Left: %s, -%d dB\n", + (reg & AD_DS_WADA_LWAM) ? "mute" : "unmute", + ((reg & AD_DS_WADA_LWAA) >> 8) * 3); + reg = ad1889_readw(chip, AD_DS_WADA); + snd_iprintf(buffer, "Right: %s, -%d dB\n", + (reg & AD_DS_WADA_RWAM) ? "mute" : "unmute", + ((reg & AD_DS_WADA_RWAA) >> 8) * 3); + + reg = ad1889_readw(chip, AD_DS_WAS); + snd_iprintf(buffer, "Wave samplerate: %u Hz\n", reg); + reg = ad1889_readw(chip, AD_DS_RES); + snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg); +} + +static void __devinit +snd_ad1889_proc_init(struct snd_ad1889 *chip) +{ + snd_info_entry_t *entry; + + if (!snd_card_proc_new(chip->card, chip->card->driver, &entry)) + snd_info_set_text_ops(entry, chip, 1024, snd_ad1889_proc_read); +} + +static struct ac97_quirk ac97_quirks[] = { + { + .subvendor = 0x11d4, /* AD */ + .subdevice = 0x1889, /* AD1889 */ + .codec_id = AC97_ID_AD1819, + .name = "AD1889", + .type = AC97_TUNE_HP_ONLY + }, + { } /* terminator */ +}; + +static void __devinit +snd_ad1889_ac97_xinit(struct snd_ad1889 *chip) +{ + u16 reg; + + reg = ad1889_readw(chip, AD_AC97_ACIC); + reg |= AD_AC97_ACIC_ACRD; /* Reset Disable */ + ad1889_writew(chip, AD_AC97_ACIC, reg); + ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */ + udelay(10); + /* Interface Enable */ + reg |= AD_AC97_ACIC_ACIE; + ad1889_writew(chip, AD_AC97_ACIC, reg); + + snd_ad1889_ac97_ready(chip); + + /* Audio Stream Output | Variable Sample Rate Mode */ + reg = ad1889_readw(chip, AD_AC97_ACIC); + reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM; + ad1889_writew(chip, AD_AC97_ACIC, reg); + ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */ + +} + +static void +snd_ad1889_ac97_bus_free(ac97_bus_t *bus) +{ + struct snd_ad1889 *chip = bus->private_data; + chip->ac97_bus = NULL; +} + +static void +snd_ad1889_ac97_free(ac97_t *ac97) +{ + struct snd_ad1889 *chip = ac97->private_data; + chip->ac97 = NULL; +} + +static int __devinit +snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override) +{ + int err; + ac97_template_t ac97; + static ac97_bus_ops_t ops = { + .write = snd_ad1889_ac97_write, + .read = snd_ad1889_ac97_read, + }; + + /* doing that here, it works. */ + snd_ad1889_ac97_xinit(chip); + + err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus); + if (err < 0) + return err; + + chip->ac97_bus->private_free = snd_ad1889_ac97_bus_free; + + memset(&ac97, 0, sizeof(ac97)); + ac97.private_data = chip; + ac97.private_free = snd_ad1889_ac97_free; + ac97.pci = chip->pci; + + err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97); + if (err < 0) + return err; + + snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override); + + return 0; +} + +static int +snd_ad1889_free(struct snd_ad1889 *chip) +{ + if (chip->irq < 0) + goto skip_hw; + + spin_lock_irq(&chip->lock); + + ad1889_mute(chip); + + /* Turn off interrupt on count and zero DMA registers */ + ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC); + + /* clear DISR. If we don't, we'd better jump off the Eiffel Tower */ + ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI); + ad1889_readl(chip, AD_DMA_DISR); /* flush, dammit! */ + + spin_unlock_irq(&chip->lock); + + synchronize_irq(chip->irq); + + if (chip->irq >= 0) + free_irq(chip->irq, (void*)chip); + +skip_hw: + if (chip->iobase) + iounmap(chip->iobase); + + pci_release_regions(chip->pci); + pci_disable_device(chip->pci); + + kfree(chip); + return 0; +} + +static inline int +snd_ad1889_dev_free(snd_device_t *device) +{ + struct snd_ad1889 *chip = device->device_data; + return snd_ad1889_free(chip); +} + +static int __devinit +snd_ad1889_init(struct snd_ad1889 *chip) +{ + ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */ + ad1889_readw(chip, AD_DS_CCS); /* flush posted write */ + + mdelay(10); + + /* enable Master and Target abort interrupts */ + ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE); + + return 0; +} + +static int __devinit +snd_ad1889_create(snd_card_t *card, + struct pci_dev *pci, + struct snd_ad1889 **rchip) +{ + int err; + + struct snd_ad1889 *chip; + static snd_device_ops_t ops = { + .dev_free = snd_ad1889_dev_free, + }; + + *rchip = NULL; + + if ((err = pci_enable_device(pci)) < 0) + return err; + + /* check PCI availability (32bit DMA) */ + if (pci_set_dma_mask(pci, 0xffffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0xffffffff) < 0) { + printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); + pci_disable_device(pci); + return -ENXIO; + } + + /* allocate chip specific data with zero-filled memory */ + if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) { + pci_disable_device(pci); + return -ENOMEM; + } + + chip->card = card; + card->private_data = chip; + chip->pci = pci; + chip->irq = -1; + + /* (1) PCI resource allocation */ + if ((err = pci_request_regions(pci, card->driver)) < 0) + goto free_and_ret; + + chip->bar = pci_resource_start(pci, 0); + chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0)); + if (chip->iobase == NULL) { + printk(KERN_ERR PFX "unable to reserve region.\n"); + err = -EBUSY; + goto free_and_ret; + } + + pci_set_master(pci); + + spin_lock_init(&chip->lock); /* only now can we call ad1889_free */ + + if (request_irq(pci->irq, snd_ad1889_interrupt, + SA_INTERRUPT|SA_SHIRQ, card->driver, (void*)chip)) { + printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq); + snd_ad1889_free(chip); + return -EBUSY; + } + + chip->irq = pci->irq; + synchronize_irq(chip->irq); + + /* (2) initialization of the chip hardware */ + if ((err = snd_ad1889_init(chip)) < 0) { + snd_ad1889_free(chip); + return err; + } + + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { + snd_ad1889_free(chip); + return err; + } + + snd_card_set_dev(card, &pci->dev); + + *rchip = chip; + + return 0; + +free_and_ret: + if (chip) + kfree(chip); + pci_disable_device(pci); + + return err; +} + +static int __devinit +snd_ad1889_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + int err; + static int devno; + snd_card_t *card; + struct snd_ad1889 *chip; + + /* (1) */ + if (devno >= SNDRV_CARDS) + return -ENODEV; + if (!enable[devno]) { + devno++; + return -ENOENT; + } + + /* (2) */ + card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0); + /* XXX REVISIT: we can probably allocate chip in this call */ + if (card == NULL) + return -ENOMEM; + + strcpy(card->driver, "AD1889"); + strcpy(card->shortname, "Analog Devices AD1889"); + + /* (3) */ + err = snd_ad1889_create(card, pci, &chip); + if (err < 0) + goto free_and_ret; + + /* (4) */ + sprintf(card->longname, "%s at 0x%lx irq %i", + card->shortname, chip->bar, chip->irq); + + /* (5) */ + /* register AC97 mixer */ + err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]); + if (err < 0) + goto free_and_ret; + + err = snd_ad1889_pcm_init(chip, 0, NULL); + if (err < 0) + goto free_and_ret; + + /* register proc interface */ + snd_ad1889_proc_init(chip); + + /* (6) */ + err = snd_card_register(card); + if (err < 0) + goto free_and_ret; + + /* (7) */ + pci_set_drvdata(pci, card); + + devno++; + return 0; + +free_and_ret: + snd_card_free(card); + return err; +} + +static void __devexit +snd_ad1889_remove(struct pci_dev *pci) +{ + snd_card_free(pci_get_drvdata(pci)); + pci_set_drvdata(pci, NULL); +} + +static struct pci_device_id snd_ad1889_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, snd_ad1889_ids); + +static struct pci_driver ad1889_pci = { + .name = "AD1889 Audio", + .owner = THIS_MODULE, + .id_table = snd_ad1889_ids, + .probe = snd_ad1889_probe, + .remove = __devexit_p(snd_ad1889_remove), +}; + +static int __init +alsa_ad1889_init(void) +{ + return pci_register_driver(&ad1889_pci); +} + +static void __exit +alsa_ad1889_fini(void) +{ + pci_unregister_driver(&ad1889_pci); +} + +module_init(alsa_ad1889_init); +module_exit(alsa_ad1889_fini); diff --git a/sound/pci/ad1889.h b/sound/pci/ad1889.h new file mode 100644 index 000000000000..5e6dad5341a1 --- /dev/null +++ b/sound/pci/ad1889.h @@ -0,0 +1,189 @@ +/* Analog Devices 1889 audio driver + * Copyright (C) 2004, Kyle McMartin <kyle@parisc-linux.org> + */ + +#ifndef __AD1889_H__ +#define __AD1889_H__ + +#define AD_DS_WSMC 0x00 /* wave/synthesis channel mixer control */ +#define AD_DS_WSMC_SYEN 0x0004 /* synthesis channel enable */ +#define AD_DS_WSMC_SYRQ 0x0030 /* synth. fifo request point */ +#define AD_DS_WSMC_WA16 0x0100 /* wave channel 16bit select */ +#define AD_DS_WSMC_WAST 0x0200 /* wave channel stereo select */ +#define AD_DS_WSMC_WAEN 0x0400 /* wave channel enable */ +#define AD_DS_WSMC_WARQ 0x3000 /* wave fifo request point */ + +#define AD_DS_RAMC 0x02 /* resampler/ADC channel mixer control */ +#define AD_DS_RAMC_AD16 0x0001 /* ADC channel 16bit select */ +#define AD_DS_RAMC_ADST 0x0002 /* ADC channel stereo select */ +#define AD_DS_RAMC_ADEN 0x0004 /* ADC channel enable */ +#define AD_DS_RAMC_ACRQ 0x0030 /* ADC fifo request point */ +#define AD_DS_RAMC_REEN 0x0400 /* resampler channel enable */ +#define AD_DS_RAMC_RERQ 0x3000 /* res. fifo request point */ + +#define AD_DS_WADA 0x04 /* wave channel mix attenuation */ +#define AD_DS_WADA_RWAM 0x0080 /* right wave mute */ +#define AD_DS_WADA_RWAA 0x001f /* right wave attenuation */ +#define AD_DS_WADA_LWAM 0x8000 /* left wave mute */ +#define AD_DS_WADA_LWAA 0x3e00 /* left wave attenuation */ + +#define AD_DS_SYDA 0x06 /* synthesis channel mix attenuation */ +#define AD_DS_SYDA_RSYM 0x0080 /* right synthesis mute */ +#define AD_DS_SYDA_RSYA 0x001f /* right synthesis attenuation */ +#define AD_DS_SYDA_LSYM 0x8000 /* left synthesis mute */ +#define AD_DS_SYDA_LSYA 0x3e00 /* left synthesis attenuation */ + +#define AD_DS_WAS 0x08 /* wave channel sample rate */ +#define AD_DS_WAS_WAS 0xffff /* sample rate mask */ + +#define AD_DS_RES 0x0a /* resampler channel sample rate */ +#define AD_DS_RES_RES 0xffff /* sample rate mask */ + +#define AD_DS_CCS 0x0c /* chip control/status */ +#define AD_DS_CCS_ADO 0x0001 /* ADC channel overflow */ +#define AD_DS_CCS_REO 0x0002 /* resampler channel overflow */ +#define AD_DS_CCS_SYU 0x0004 /* synthesis channel underflow */ +#define AD_DS_CCS_WAU 0x0008 /* wave channel underflow */ +/* bits 4 -> 7, 9, 11 -> 14 reserved */ +#define AD_DS_CCS_XTD 0x0100 /* xtd delay control (4096 clock cycles) */ +#define AD_DS_CCS_PDALL 0x0400 /* power */ +#define AD_DS_CCS_CLKEN 0x8000 /* clock */ + +#define AD_DMA_RESBA 0x40 /* RES base address */ +#define AD_DMA_RESCA 0x44 /* RES current address */ +#define AD_DMA_RESBC 0x48 /* RES base count */ +#define AD_DMA_RESCC 0x4c /* RES current count */ + +#define AD_DMA_ADCBA 0x50 /* ADC base address */ +#define AD_DMA_ADCCA 0x54 /* ADC current address */ +#define AD_DMA_ADCBC 0x58 /* ADC base count */ +#define AD_DMA_ADCCC 0x5c /* ADC current count */ + +#define AD_DMA_SYNBA 0x60 /* synth base address */ +#define AD_DMA_SYNCA 0x64 /* synth current address */ +#define AD_DMA_SYNBC 0x68 /* synth base count */ +#define AD_DMA_SYNCC 0x6c /* synth current count */ + +#define AD_DMA_WAVBA 0x70 /* wave base address */ +#define AD_DMA_WAVCA 0x74 /* wave current address */ +#define AD_DMA_WAVBC 0x78 /* wave base count */ +#define AD_DMA_WAVCC 0x7c /* wave current count */ + +#define AD_DMA_RESIC 0x80 /* RES dma interrupt current byte count */ +#define AD_DMA_RESIB 0x84 /* RES dma interrupt base byte count */ + +#define AD_DMA_ADCIC 0x88 /* ADC dma interrupt current byte count */ +#define AD_DMA_ADCIB 0x8c /* ADC dma interrupt base byte count */ + +#define AD_DMA_SYNIC 0x90 /* synth dma interrupt current byte count */ +#define AD_DMA_SYNIB 0x94 /* synth dma interrupt base byte count */ + +#define AD_DMA_WAVIC 0x98 /* wave dma interrupt current byte count */ +#define AD_DMA_WAVIB 0x9c /* wave dma interrupt base byte count */ + +#define AD_DMA_ICC 0xffffff /* current byte count mask */ +#define AD_DMA_IBC 0xffffff /* base byte count mask */ +/* bits 24 -> 31 reserved */ + +/* 4 bytes pad */ +#define AD_DMA_ADC 0xa8 /* ADC dma control and status */ +#define AD_DMA_SYNTH 0xb0 /* Synth dma control and status */ +#define AD_DMA_WAV 0xb8 /* wave dma control and status */ +#define AD_DMA_RES 0xa0 /* Resample dma control and status */ + +#define AD_DMA_SGDE 0x0001 /* SGD mode enable */ +#define AD_DMA_LOOP 0x0002 /* loop enable */ +#define AD_DMA_IM 0x000c /* interrupt mode mask */ +#define AD_DMA_IM_DIS (~AD_DMA_IM) /* disable */ +#define AD_DMA_IM_CNT 0x0004 /* interrupt on count */ +#define AD_DMA_IM_SGD 0x0008 /* interrupt on SGD flag */ +#define AD_DMA_IM_EOL 0x000c /* interrupt on End of Linked List */ +#define AD_DMA_SGDS 0x0030 /* SGD status */ +#define AD_DMA_SFLG 0x0040 /* SGD flag */ +#define AD_DMA_EOL 0x0080 /* SGD end of list */ +/* bits 8 -> 15 reserved */ + +#define AD_DMA_DISR 0xc0 /* dma interrupt status */ +#define AD_DMA_DISR_RESI 0x000001 /* resampler channel interrupt */ +#define AD_DMA_DISR_ADCI 0x000002 /* ADC channel interrupt */ +#define AD_DMA_DISR_SYNI 0x000004 /* synthesis channel interrupt */ +#define AD_DMA_DISR_WAVI 0x000008 /* wave channel interrupt */ +/* bits 4, 5 reserved */ +#define AD_DMA_DISR_SEPS 0x000040 /* serial eeprom status */ +/* bits 7 -> 13 reserved */ +#define AD_DMA_DISR_PMAI 0x004000 /* pci master abort interrupt */ +#define AD_DMA_DISR_PTAI 0x008000 /* pci target abort interrupt */ +#define AD_DMA_DISR_PTAE 0x010000 /* pci target abort interrupt enable */ +#define AD_DMA_DISR_PMAE 0x020000 /* pci master abort interrupt enable */ +/* bits 19 -> 31 reserved */ + +/* interrupt mask */ +#define AD_INTR_MASK (AD_DMA_DISR_RESI|AD_DMA_DISR_ADCI| \ + AD_DMA_DISR_WAVI|AD_DMA_DISR_SYNI| \ + AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI) + +#define AD_DMA_CHSS 0xc4 /* dma channel stop status */ +#define AD_DMA_CHSS_RESS 0x000001 /* resampler channel stopped */ +#define AD_DMA_CHSS_ADCS 0x000002 /* ADC channel stopped */ +#define AD_DMA_CHSS_SYNS 0x000004 /* synthesis channel stopped */ +#define AD_DMA_CHSS_WAVS 0x000008 /* wave channel stopped */ + +#define AD_GPIO_IPC 0xc8 /* gpio port control */ +#define AD_GPIO_OP 0xca /* gpio output port status */ +#define AD_GPIO_IP 0xcc /* gpio input port status */ + +#define AD_AC97_BASE 0x100 /* ac97 base register */ + +#define AD_AC97_RESET 0x100 /* reset */ + +#define AD_AC97_PWR_CTL 0x126 /* == AC97_POWERDOWN */ +#define AD_AC97_PWR_ADC 0x0001 /* ADC ready status */ +#define AD_AC97_PWR_DAC 0x0002 /* DAC ready status */ +#define AD_AC97_PWR_PR0 0x0100 /* PR0 (ADC) powerdown */ +#define AD_AC97_PWR_PR1 0x0200 /* PR1 (DAC) powerdown */ + +#define AD_MISC_CTL 0x176 /* misc control */ +#define AD_MISC_CTL_DACZ 0x8000 /* set for zero fill, unset for repeat */ +#define AD_MISC_CTL_ARSR 0x0001 /* set for SR1, unset for SR0 */ +#define AD_MISC_CTL_ALSR 0x0100 +#define AD_MISC_CTL_DLSR 0x0400 +#define AD_MISC_CTL_DRSR 0x0004 + +#define AD_AC97_SR0 0x178 /* sample rate 0, 0xbb80 == 48K */ +#define AD_AC97_SR0_48K 0xbb80 /* 48KHz */ +#define AD_AC97_SR1 0x17a /* sample rate 1 */ + +#define AD_AC97_ACIC 0x180 /* ac97 codec interface control */ +#define AD_AC97_ACIC_ACIE 0x0001 /* analog codec interface enable */ +#define AD_AC97_ACIC_ACRD 0x0002 /* analog codec reset disable */ +#define AD_AC97_ACIC_ASOE 0x0004 /* audio stream output enable */ +#define AD_AC97_ACIC_VSRM 0x0008 /* variable sample rate mode */ +#define AD_AC97_ACIC_FSDH 0x0100 /* force SDATA_OUT high */ +#define AD_AC97_ACIC_FSYH 0x0200 /* force sync high */ +#define AD_AC97_ACIC_ACRDY 0x8000 /* analog codec ready status */ +/* bits 10 -> 14 reserved */ + + +#define AD_DS_MEMSIZE 512 +#define AD_OPL_MEMSIZE 16 +#define AD_MIDI_MEMSIZE 16 + +#define AD_WAV_STATE 0 +#define AD_ADC_STATE 1 +#define AD_MAX_STATES 2 + +#define AD_CHAN_WAV 0x0001 +#define AD_CHAN_ADC 0x0002 +#define AD_CHAN_RES 0x0004 +#define AD_CHAN_SYN 0x0008 + + +/* The chip would support 4 GB buffers and 16 MB periods, + * but let's not overdo it ... */ +#define BUFFER_BYTES_MAX (256 * 1024) +#define PERIOD_BYTES_MIN 32 +#define PERIOD_BYTES_MAX (BUFFER_BYTES_MAX / 2) +#define PERIODS_MIN 2 +#define PERIODS_MAX (BUFFER_BYTES_MAX / PERIOD_BYTES_MIN) + +#endif /* __AD1889_H__ */ diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index f08ae71f902d..f35b558c29b2 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -78,15 +78,7 @@ MODULE_PARM_DESC(spdif, "Support SPDIF I/O"); * Constants definition */ -#ifndef PCI_VENDOR_ID_ALI -#define PCI_VENDOR_ID_ALI 0x10b9 -#endif - -#ifndef PCI_DEVICE_ID_ALI_5451 -#define PCI_DEVICE_ID_ALI_5451 0x5451 -#endif - -#define DEVICE_ID_ALI5451 ((PCI_VENDOR_ID_ALI<<16)|PCI_DEVICE_ID_ALI_5451) +#define DEVICE_ID_ALI5451 ((PCI_VENDOR_ID_AL<<16)|PCI_DEVICE_ID_AL_M5451) #define ALI_CHANNELS 32 @@ -326,13 +318,12 @@ static void ali_read_regs(ali_t *codec, int channel) static void ali_read_cfg(unsigned int vendor, unsigned deviceid) { unsigned int dwVal; - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; int i,j; - - pci_dev = pci_find_device(vendor, deviceid, pci_dev); - if (pci_dev == NULL) - return ; + pci_dev = pci_get_device(vendor, deviceid, NULL); + if (pci_dev == NULL) + return ; printk("\nM%x PCI CFG\n", deviceid); printk(" "); @@ -349,6 +340,7 @@ static void ali_read_cfg(unsigned int vendor, unsigned deviceid) } printk("\n"); } + pci_dev_put(pci_dev); } static void ali_read_ac97regs(ali_t *codec, int secondary) { @@ -1842,7 +1834,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr return 0; } -struct ali_pcm_description ali_pcms[] = { +static struct ali_pcm_description ali_pcms[] = { { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops } }; @@ -1959,9 +1951,9 @@ static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinitdata = { /* spdif aplayback switch */ /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */ - ALI5451_SPDIF("IEC958 Output switch", 0, 0), + ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 0, 0), /* spdif out to spdif channel */ - ALI5451_SPDIF("IEC958 Channel Output Switch", 0, 1), + ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Channel Output ",NONE,SWITCH), 0, 1), /* spdif in from spdif channel */ ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) }; @@ -2001,8 +1993,10 @@ static int __devinit snd_ali_mixer(ali_t * codec) if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) { snd_printk("ali mixer %d creating error.\n", i); if(i == 0) - return err; - } + return err; + codec->num_of_codecs = 1; + break; + } } if (codec->spdif_support) { @@ -2116,6 +2110,8 @@ static int snd_ali_free(ali_t * codec) #ifdef CONFIG_PM kfree(codec->image); #endif + pci_dev_put(codec->pci_m1533); + pci_dev_put(codec->pci_m7101); kfree(codec); return 0; } @@ -2249,7 +2245,7 @@ static int __devinit snd_ali_create(snd_card_t * card, return -ENXIO; } - if ((codec = kcalloc(1, sizeof(*codec), GFP_KERNEL)) == NULL) { + if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) { pci_disable_device(pci); return -ENOMEM; } @@ -2305,7 +2301,7 @@ static int __devinit snd_ali_create(snd_card_t * card, codec->chregs.data.ainten = 0x00; /* M1533: southbridge */ - pci_dev = pci_find_device(0x10b9, 0x1533, NULL); + pci_dev = pci_get_device(0x10b9, 0x1533, NULL); codec->pci_m1533 = pci_dev; if (! codec->pci_m1533) { snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); @@ -2313,7 +2309,7 @@ static int __devinit snd_ali_create(snd_card_t * card, return -ENODEV; } /* M7101: power management */ - pci_dev = pci_find_device(0x10b9, 0x7101, NULL); + pci_dev = pci_get_device(0x10b9, 0x7101, NULL); codec->pci_m7101 = pci_dev; if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) { snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); @@ -2417,6 +2413,7 @@ static void __devexit snd_ali_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ALI 5451", + .owner = THIS_MODULE, .id_table = snd_ali_ids, .probe = snd_ali_probe, .remove = __devexit_p(snd_ali_remove), diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index ca28b229c704..196ec1c61bb4 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -770,6 +770,7 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ALS4000", + .owner = THIS_MODULE, .id_table = snd_als4000_ids, .probe = snd_card_als4000_probe, .remove = __devexit_p(snd_card_als4000_remove), diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index cafab4af5c57..241eacf1e652 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -248,6 +248,7 @@ struct snd_atiixp_dma { unsigned int period_bytes, periods; int opened; int running; + int suspended; int pcm_open_flag; int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */ unsigned int saved_curptr; @@ -699,12 +700,18 @@ static int snd_atiixp_pcm_trigger(snd_pcm_substream_t *substream, int cmd) spin_lock(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: dma->ops->enable_transfer(chip, 1); dma->running = 1; + dma->suspended = 0; break; case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: dma->ops->enable_transfer(chip, 0); dma->running = 0; + dma->suspended = cmd == SNDRV_PCM_TRIGGER_SUSPEND; break; default: err = -EINVAL; @@ -975,6 +982,7 @@ static snd_pcm_hardware_t snd_atiixp_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, @@ -1419,7 +1427,7 @@ static int snd_atiixp_suspend(snd_card_t *card, pm_message_t state) snd_atiixp_aclink_down(chip); snd_atiixp_chip_stop(chip); - pci_set_power_state(chip->pci, 3); + pci_set_power_state(chip->pci, PCI_D3hot); pci_disable_device(chip->pci); return 0; } @@ -1430,7 +1438,7 @@ static int snd_atiixp_resume(snd_card_t *card) int i; pci_enable_device(chip->pci); - pci_set_power_state(chip->pci, 0); + pci_set_power_state(chip->pci, PCI_D0); pci_set_master(chip->pci); snd_atiixp_aclink_reset(chip); @@ -1443,8 +1451,9 @@ static int snd_atiixp_resume(snd_card_t *card) for (i = 0; i < NUM_ATI_PCMDEVS; i++) if (chip->pcmdevs[i]) { atiixp_dma_t *dma = &chip->dmas[i]; - if (dma->substream && dma->running) { + if (dma->substream && dma->suspended) { dma->ops->enable_dma(chip, 1); + dma->substream->ops->prepare(dma->substream); writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN, chip->remap_addr + dma->ops->llp_offset); writel(dma->saved_curptr, chip->remap_addr + dma->ops->dt_cur); @@ -1522,7 +1531,7 @@ static int __devinit snd_atiixp_create(snd_card_t *card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1636,6 +1645,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ATI IXP AC97 controller", + .owner = THIS_MODULE, .id_table = snd_atiixp_ids, .probe = snd_atiixp_probe, .remove = __devexit_p(snd_atiixp_remove), diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 8d2002951bd7..c1a239a4dac6 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -405,7 +405,7 @@ static int snd_atiixp_acquire_codec(atiixp_t *chip) while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) { if (! timeout--) { - snd_printk(KERN_WARNING "atiixp: codec acquire timeout\n"); + snd_printk(KERN_WARNING "atiixp-modem: codec acquire timeout\n"); return -EBUSY; } udelay(1); @@ -436,7 +436,7 @@ static unsigned short snd_atiixp_codec_read(atiixp_t *chip, unsigned short codec } while (--timeout); /* time out may happen during reset */ if (reg < 0x7c) - snd_printk(KERN_WARNING "atiixp: codec read timeout (reg %x)\n", reg); + snd_printk(KERN_WARNING "atiixp-modem: codec read timeout (reg %x)\n", reg); return 0xffff; } @@ -498,7 +498,7 @@ static int snd_atiixp_aclink_reset(atiixp_t *chip) do_delay(); atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); if (--timeout) { - snd_printk(KERN_ERR "atiixp: codec reset timeout\n"); + snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n"); break; } } @@ -552,7 +552,7 @@ static int snd_atiixp_codec_detect(atiixp_t *chip) atiixp_write(chip, IER, 0); /* disable irqs */ if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) { - snd_printk(KERN_ERR "atiixp: no codec detected!\n"); + snd_printk(KERN_ERR "atiixp-modem: no codec detected!\n"); return -ENXIO; } return 0; @@ -635,7 +635,7 @@ static void snd_atiixp_xrun_dma(atiixp_t *chip, atiixp_dma_t *dma) { if (! dma->substream || ! dma->running) return; - snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type); + snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type); snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); } @@ -1081,14 +1081,14 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock) ac97.scaps = AC97_SCAP_SKIP_AUDIO; if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { chip->ac97[i] = NULL; /* to be sure */ - snd_printdd("atiixp: codec %d not available for modem\n", i); + snd_printdd("atiixp-modem: codec %d not available for modem\n", i); continue; } codec_count++; } if (! codec_count) { - snd_printk(KERN_ERR "atiixp: no codec available\n"); + snd_printk(KERN_ERR "atiixp-modem: no codec available\n"); return -ENODEV; } @@ -1159,7 +1159,7 @@ static void __devinit snd_atiixp_proc_init(atiixp_t *chip) { snd_info_entry_t *entry; - if (! snd_card_proc_new(chip->card, "atiixp", &entry)) + if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry)) snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read); } @@ -1208,7 +1208,7 @@ static int __devinit snd_atiixp_create(snd_card_t *card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1318,6 +1318,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ATI IXP MC97 controller", + .owner = THIS_MODULE, .id_table = snd_atiixp_ids, .probe = snd_atiixp_probe, .remove = __devexit_p(snd_atiixp_remove), diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index f6236c63aaaa..04b695d6fd48 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -79,19 +79,21 @@ static void vortex_fix_agp_bridge(struct pci_dev *via) static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix) { - struct pci_dev *via; + struct pci_dev *via = NULL; /* autodetect if workarounds are required */ if (fix == 255) { /* VIA KT133 */ - via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL); + via = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_8365_1, NULL); /* VIA Apollo */ if (via == NULL) { - via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL); - } - /* AMD Irongate */ - if (via == NULL) { - via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL); + via = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C598_1, NULL); + /* AMD Irongate */ + if (via == NULL) + via = pci_get_device(PCI_VENDOR_ID_AMD, + PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL); } if (via) { printk(KERN_INFO CARD_NAME ": Activating latency workaround...\n"); @@ -101,13 +103,17 @@ static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix) } else { if (fix & 0x1) vortex_fix_latency(vortex); - if ((fix & 0x2) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL))) + if ((fix & 0x2) && (via = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_8365_1, NULL))) vortex_fix_agp_bridge(via); - if ((fix & 0x4) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL))) + if ((fix & 0x4) && (via = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C598_1, NULL))) vortex_fix_agp_bridge(via); - if ((fix & 0x8) && (via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL))) + if ((fix & 0x8) && (via = pci_get_device(PCI_VENDOR_ID_AMD, + PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL))) vortex_fix_agp_bridge(via); } + pci_dev_put(via); } // component-destructor @@ -150,7 +156,7 @@ snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip) } pci_set_dma_mask(pci, VORTEX_DMA_MASK); - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; @@ -367,6 +373,7 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci) // pci_driver definition static struct pci_driver driver = { .name = CARD_NAME_SHORT, + .owner = THIS_MODULE, .id_table = snd_vortex_ids, .probe = snd_vortex_probe, .remove = __devexit_p(snd_vortex_remove), diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 04dcefd8b8ff..38bd2b5dd434 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -33,7 +33,7 @@ /* hardware definition */ static snd_pcm_hardware_t snd_vortex_playback_hw_adb = { .info = - (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | + (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), .formats = @@ -58,7 +58,7 @@ static snd_pcm_hardware_t snd_vortex_playback_hw_adb = { #ifndef CHIP_AU8820 static snd_pcm_hardware_t snd_vortex_playback_hw_a3d = { .info = - (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | + (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), .formats = @@ -78,7 +78,7 @@ static snd_pcm_hardware_t snd_vortex_playback_hw_a3d = { #endif static snd_pcm_hardware_t snd_vortex_playback_hw_spdif = { .info = - (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | + (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), .formats = @@ -220,8 +220,10 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream, vortex_adb_allocroute(chip, -1, params_channels(hw_params), substream->stream, type); - if (dma < 0) + if (dma < 0) { + spin_unlock_irq(&chip->lock); return dma; + } stream = substream->runtime->private_data = &chip->dma_adb[dma]; stream->substream = substream; /* Setup Buffers. */ diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 72bba7b2d983..d5261bdec583 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1345,7 +1345,7 @@ static int __devinit snd_azf3328_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1511,6 +1511,7 @@ static void __devexit snd_azf3328_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "AZF3328", + .owner = THIS_MODULE, .id_table = snd_azf3328_ids, .probe = snd_azf3328_probe, .remove = __devexit_p(snd_azf3328_remove), diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index c5557eaf3e2e..01d98eeb242e 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -59,16 +59,6 @@ module_param(load_all, bool, 0444); MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards"); -#ifndef PCI_VENDOR_ID_BROOKTREE -#define PCI_VENDOR_ID_BROOKTREE 0x109e -#endif -#ifndef PCI_DEVICE_ID_BROOKTREE_878 -#define PCI_DEVICE_ID_BROOKTREE_878 0x0878 -#endif -#ifndef PCI_DEVICE_ID_BROOKTREE_879 -#define PCI_DEVICE_ID_BROOKTREE_879 0x0879 -#endif - /* register offsets */ #define REG_INT_STAT 0x100 /* interrupt status */ #define REG_INT_MASK 0x104 /* interrupt mask */ @@ -720,7 +710,7 @@ static int __devinit snd_bt87x_create(snd_card_t *card, if (err < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) { pci_disable_device(pci); return -ENOMEM; @@ -771,15 +761,18 @@ static int __devinit snd_bt87x_create(snd_card_t *card, #define BT_DEVICE(chip, subvend, subdev, rate) \ { .vendor = PCI_VENDOR_ID_BROOKTREE, \ - .device = PCI_DEVICE_ID_BROOKTREE_##chip, \ + .device = chip, \ .subvendor = subvend, .subdevice = subdev, \ .driver_data = rate } /* driver_data is the default digital_rate value for that device */ static struct pci_device_id snd_bt87x_ids[] = { - BT_DEVICE(878, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ - BT_DEVICE(879, 0x0070, 0x13eb, 32000), /* Hauppauge WinTV series */ - BT_DEVICE(878, 0x0070, 0xff01, 44100), /* Viewcast Osprey 200 */ + /* Hauppauge WinTV series */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000), + /* Hauppauge WinTV series */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), + /* Viewcast Osprey 200 */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), { } }; MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); @@ -911,6 +904,7 @@ static struct pci_device_id snd_bt87x_default_ids[] = { static struct pci_driver driver = { .name = "Bt87x", + .owner = THIS_MODULE, .id_table = snd_bt87x_ids, .probe = snd_bt87x_probe, .remove = __devexit_p(snd_bt87x_remove), diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 95c289284267..ba07960921d8 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -188,6 +188,14 @@ static ca0106_details_t ca0106_chip_details[] = { .name = "MSI K8N Diamond MB [SB0438]", .gpio_type = 1, .i2c_adc = 1 } , + /* Shuttle XPC SD31P which has an onboard Creative Labs Sound Blaster Live! 24-bit EAX + * high-definition 7.1 audio processor". + * Added using info from andrewvegan in alsa bug #1298 + */ + { .serial = 0x30381297, + .name = "Shuttle XPC SD31P [SD31P]", + .gpio_type = 1, + .i2c_adc = 1 } , { .serial = 0, .name = "AudigyLS [Unknown]" } }; @@ -344,7 +352,7 @@ static int snd_ca0106_pcm_open_playback_channel(snd_pcm_substream_t *substream, snd_pcm_runtime_t *runtime = substream->runtime; int err; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; @@ -411,7 +419,7 @@ static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, i snd_pcm_runtime_t *runtime = substream->runtime; int err; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) { snd_printk("open_capture_channel: failed epcm alloc\n"); return -ENOMEM; @@ -1136,7 +1144,7 @@ static int __devinit snd_ca0106_create(snd_card_t *card, return -ENXIO; } - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1382,6 +1390,7 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids); // pci_driver definition static struct pci_driver driver = { .name = "CA0106", + .owner = THIS_MODULE, .id_table = snd_ca0106_ids, .probe = snd_ca0106_probe, .remove = __devexit_p(snd_ca0106_remove), diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 0e5e9ce0ff28..c10e4a54301b 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -297,7 +297,7 @@ static int snd_ca0106_spdif_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_ca0106_spdif_mask_control = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), .count = 4, .info = snd_ca0106_spdif_info, @@ -306,7 +306,7 @@ static snd_kcontrol_new_t snd_ca0106_spdif_mask_control = static snd_kcontrol_new_t snd_ca0106_spdif_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .count = 4, .info = snd_ca0106_spdif_info, @@ -482,7 +482,7 @@ static int snd_ca0106_volume_put_feedback(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Front Volume", + .name = "Analog Front Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_analog_front, .put = snd_ca0106_volume_put_analog_front @@ -490,7 +490,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front = static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Center/LFE Volume", + .name = "Analog Center/LFE Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_analog_center_lfe, .put = snd_ca0106_volume_put_analog_center_lfe @@ -498,7 +498,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe = static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Side Volume", + .name = "Analog Side Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_analog_unknown, .put = snd_ca0106_volume_put_analog_unknown @@ -506,7 +506,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown = static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Rear Volume", + .name = "Analog Rear Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_analog_rear, .put = snd_ca0106_volume_put_analog_rear @@ -514,7 +514,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear = static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "SPDIF Front Volume", + .name = "SPDIF Front Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_spdif_front, .put = snd_ca0106_volume_put_spdif_front @@ -522,7 +522,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front = static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "SPDIF Center/LFE Volume", + .name = "SPDIF Center/LFE Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_spdif_center_lfe, .put = snd_ca0106_volume_put_spdif_center_lfe @@ -530,7 +530,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe = static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "SPDIF Unknown Volume", + .name = "SPDIF Unknown Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_spdif_unknown, .put = snd_ca0106_volume_put_spdif_unknown @@ -538,7 +538,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown = static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "SPDIF Rear Volume", + .name = "SPDIF Rear Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_spdif_rear, .put = snd_ca0106_volume_put_spdif_rear @@ -547,7 +547,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear = static snd_kcontrol_new_t snd_ca0106_volume_control_feedback = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CAPTURE feedback into PLAYBACK", + .name = "CAPTURE feedback Playback Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_feedback, .put = snd_ca0106_volume_put_feedback diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index f5a4ac1ceef9..1eb3315d136d 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -79,13 +79,6 @@ module_param_array(joystick_port, int, NULL, 0444); MODULE_PARM_DESC(joystick_port, "Joystick port address."); #endif -#ifndef PCI_DEVICE_ID_CMEDIA_CM8738 -#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111 -#endif -#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B -#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112 -#endif - /* * CM8x38 registers definition */ @@ -348,25 +341,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); /* - * pci ids - */ -#ifndef PCI_VENDOR_ID_CMEDIA -#define PCI_VENDOR_ID_CMEDIA 0x13F6 -#endif -#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A -#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100 -#endif -#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B -#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101 -#endif -#ifndef PCI_DEVICE_ID_CMEDIA_CM8738 -#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111 -#endif -#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B -#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112 -#endif - -/* * channels for playback / capture */ #define CM_CH_PLAY 0 @@ -1029,7 +1003,7 @@ static int snd_cmipci_spdif_mask_get(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_cmipci_spdif_mask __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_cmipci_spdif_mask_info, .get = snd_cmipci_spdif_mask_get, @@ -2801,7 +2775,7 @@ static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci, if ((err = pci_enable_device(pci)) < 0) return err; - cm = kcalloc(1, sizeof(*cm), GFP_KERNEL); + cm = kzalloc(sizeof(*cm), GFP_KERNEL); if (cm == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -3063,6 +3037,7 @@ static void __devexit snd_cmipci_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "C-Media PCI", + .owner = THIS_MODULE, .id_table = snd_cmipci_ids, .probe = snd_cmipci_probe, .remove = __devexit_p(snd_cmipci_remove), diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index c7a370d4f923..dc87e0144b5a 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -57,17 +57,6 @@ module_param_array(dual_codec, bool, NULL, 0444); MODULE_PARM_DESC(dual_codec, "Secondary Codec ID (0 = disabled)."); /* - * - */ - -#ifndef PCI_VENDOR_ID_CIRRUS -#define PCI_VENDOR_ID_CIRRUS 0x1013 -#endif -#ifndef PCI_DEVICE_ID_CIRRUS_4281 -#define PCI_DEVICE_ID_CIRRUS_4281 0x6005 -#endif - -/* * Direct registers */ @@ -1394,7 +1383,7 @@ static int __devinit snd_cs4281_create(snd_card_t * card, *rchip = NULL; if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -2119,6 +2108,7 @@ static int cs4281_resume(snd_card_t *card) static struct pci_driver driver = { .name = "CS4281", + .owner = THIS_MODULE, .id_table = snd_cs4281_ids, .probe = snd_cs4281_probe, .remove = __devexit_p(snd_cs4281_remove), diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index db212ecd792a..32b4f8465cef 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c @@ -113,7 +113,7 @@ static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, return err; } #endif - if ((err = snd_cs46xx_mixer(chip)) < 0) { + if ((err = snd_cs46xx_mixer(chip, 2)) < 0) { snd_card_free(card); return err; } @@ -163,6 +163,7 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Sound Fusion CS46xx", + .owner = THIS_MODULE, .id_table = snd_cs46xx_ids, .probe = snd_card_cs46xx_probe, .remove = __devexit_p(snd_card_cs46xx_remove), diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index ff28af1f658e..6e3855b8b33d 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -1243,8 +1243,8 @@ static snd_pcm_hardware_t snd_cs46xx_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ + /*SNDRV_PCM_INFO_RESUME*/), .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE), @@ -1265,8 +1265,8 @@ static snd_pcm_hardware_t snd_cs46xx_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ + /*SNDRV_PCM_INFO_RESUME*/), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, .rate_min = 5500, @@ -1304,7 +1304,7 @@ static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pc cs46xx_pcm_t * cpcm; snd_pcm_runtime_t *runtime = substream->runtime; - cpcm = kcalloc(1, sizeof(*cpcm), GFP_KERNEL); + cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL); if (cpcm == NULL) return -ENOMEM; if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), @@ -2231,7 +2231,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Output Switch", + .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), .info = snd_mixer_boolean_info, .get = snd_cs46xx_iec958_get, .put = snd_cs46xx_iec958_put, @@ -2239,7 +2239,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Input Switch", + .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH), .info = snd_mixer_boolean_info, .get = snd_cs46xx_iec958_get, .put = snd_cs46xx_iec958_put, @@ -2249,7 +2249,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { /* Input IEC958 volume does not work for the moment. (Benny) */ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Input Volume", + .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME), .info = snd_cs46xx_vol_info, .get = snd_cs46xx_vol_iec958_get, .put = snd_cs46xx_vol_iec958_put, @@ -2440,7 +2440,7 @@ static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec) return -ENXIO; } -int __devinit snd_cs46xx_mixer(cs46xx_t *chip) +int __devinit snd_cs46xx_mixer(cs46xx_t *chip, int spdif_device) { snd_card_t *card = chip->card; snd_ctl_elem_id_t id; @@ -2476,6 +2476,8 @@ int __devinit snd_cs46xx_mixer(cs46xx_t *chip) for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) { snd_kcontrol_t *kctl; kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); + if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) + kctl->id.device = spdif_device; if ((err = snd_ctl_add(card, kctl)) < 0) return err; } @@ -3523,17 +3525,6 @@ static void amp_voyetra_4294(cs46xx_t *chip, int change) /* - * piix4 pci ids - */ -#ifndef PCI_VENDOR_ID_INTEL -#define PCI_VENDOR_ID_INTEL 0x8086 -#endif /* PCI_VENDOR_ID_INTEL */ - -#ifndef PCI_DEVICE_ID_INTEL_82371AB_3 -#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 -#endif /* PCI_DEVICE_ID_INTEL_82371AB_3 */ - -/* * Handle the CLKRUN on a thinkpad. We must disable CLKRUN support * whenever we need to beat on the chip. * @@ -3546,7 +3537,7 @@ static void clkrun_hack(cs46xx_t *chip, int change) { u16 control, nval; - if (chip->acpi_dev == NULL) + if (!chip->acpi_port) return; chip->amplifier += change; @@ -3569,15 +3560,20 @@ static void clkrun_hack(cs46xx_t *chip, int change) */ static void clkrun_init(cs46xx_t *chip) { + struct pci_dev *pdev; u8 pp; - chip->acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); - if (chip->acpi_dev == NULL) + chip->acpi_port = 0; + + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_3, NULL); + if (pdev == NULL) return; /* Not a thinkpad thats for sure */ /* Find the control port */ - pci_read_config_byte(chip->acpi_dev, 0x41, &pp); + pci_read_config_byte(pdev, 0x41, &pp); chip->acpi_port = pp << 8; + pci_dev_put(pdev); } @@ -3778,7 +3774,7 @@ int __devinit snd_cs46xx_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index b17142cabead..b0e00f0a7c2f 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c @@ -149,7 +149,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, } } - if ((err = snd_emu10k1_mixer(emu)) < 0) { + if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0) { snd_card_free(card); return err; } @@ -223,6 +223,7 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "EMU10K1_Audigy", + .owner = THIS_MODULE, .id_table = snd_emu10k1_ids, .probe = snd_card_emu10k1_probe, .remove = __devexit_p(snd_card_emu10k1_remove), diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 746b51ef3966..53aeff0b783a 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -579,6 +579,30 @@ static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu) return 0; } +static int __devinit snd_emu10k1_cardbus_init(emu10k1_t * emu) +{ + unsigned long special_port; + unsigned int value; + + /* Special initialisation routine + * before the rest of the IO-Ports become active. + */ + special_port = emu->port + 0x38; + value = inl(special_port); + outl(0x00d00000, special_port); + value = inl(special_port); + outl(0x00d00001, special_port); + value = inl(special_port); + outl(0x00d0005f, special_port); + value = inl(special_port); + outl(0x00d0007f, special_port); + value = inl(special_port); + outl(0x0090007f, special_port); + value = inl(special_port); + + return 0; +} + /* * Create the EMU10K1 instance */ @@ -624,6 +648,16 @@ static emu_chip_details_t emu_chip_details[] = { .ca0108_chip = 1, .spk71 = 1, .ac97_chip = 1} , + /* Audigy 2 ZS Notebook Cardbus card.*/ + /* Tested by James@superbug.co.uk 30th October 2005 */ + /* Not working yet, but progressing. */ + {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, + .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", + .id = "Audigy2", + .emu10k2_chip = 1, + .ca0108_chip = 1, + .ca_cardbus_chip = 1, + .spk71 = 1} , {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .id = "Audigy2", @@ -741,17 +775,27 @@ static emu_chip_details_t emu_chip_details[] = { .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , + /* Tested by Thomas Zehetbauer 27th Aug 2005 */ + {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102, + .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]", + .id = "Live", + .emu10k1_chip = 1, + .ac97_chip = 1, + .sblive51 = 1} , {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, .driver = "EMU10K1", .name = "SB Live 5.1", .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1, .sblive51 = 1} , + /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */ {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, - .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", + .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]", .id = "Live", .emu10k1_chip = 1, - .ac97_chip = 1, + .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum + * share the same IDs! + */ .sblive51 = 1} , {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", @@ -857,7 +901,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - emu = kcalloc(1, sizeof(*emu), GFP_KERNEL); + emu = kzalloc(sizeof(*emu), GFP_KERNEL); if (emu == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1001,6 +1045,11 @@ int __devinit snd_emu10k1_create(snd_card_t * card, snd_emu10k1_free(emu); return err; } + } else if (emu->card_capabilities->ca_cardbus_chip) { + if ((err = snd_emu10k1_cardbus_init(emu)) < 0) { + snd_emu10k1_free(emu); + return err; + } } else { /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version does not support this, it shouldn't do any harm */ diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index e90c5ddd1d17..ad15755a63c3 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -395,7 +395,7 @@ static int snd_emu10k1x_playback_open(snd_pcm_substream_t *substream) if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) return err; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; epcm->emu = chip; @@ -571,7 +571,7 @@ static int snd_emu10k1x_pcm_open_capture(snd_pcm_substream_t *substream) if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) return err; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; @@ -920,7 +920,7 @@ static int __devinit snd_emu10k1x_create(snd_card_t *card, return -ENXIO; } - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1183,7 +1183,7 @@ static int snd_emu10k1x_spdif_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), .count = 3, .info = snd_emu10k1x_spdif_info, @@ -1192,7 +1192,7 @@ static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control = static snd_kcontrol_new_t snd_emu10k1x_spdif_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .count = 3, .info = snd_emu10k1x_spdif_info, @@ -1615,6 +1615,7 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids); // pci_driver definition static struct pci_driver driver = { .name = "EMU10K1X", + .owner = THIS_MODULE, .id_table = snd_emu10k1x_ids, .probe = snd_emu10k1x_probe, .remove = __devexit_p(snd_emu10k1x_remove), diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 0529fb281125..646b5d972e6f 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -470,7 +470,7 @@ static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr { u_int32_t *code; snd_assert(*ptr < 512, return); - code = (u_int32_t *)icode->code + (*ptr) * 2; + code = (u_int32_t __force *)icode->code + (*ptr) * 2; set_bit(*ptr, icode->code_valid); code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff); code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff); @@ -485,7 +485,7 @@ static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned i { u_int32_t *code; snd_assert(*ptr < 1024, return); - code = (u_int32_t *)icode->code + (*ptr) * 2; + code = (u_int32_t __force *)icode->code + (*ptr) * 2; set_bit(*ptr, icode->code_valid); code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff); code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff); @@ -1036,13 +1036,13 @@ static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu) spin_lock_init(&emu->fx8010.irq_lock); INIT_LIST_HEAD(&emu->fx8010.gpr_ctl); - if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL || + if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL || (icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL || (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) { err = -ENOMEM; goto __err; } - gpr_map = (u32 *)icode->gpr_map; + gpr_map = (u32 __force *)icode->gpr_map; icode->tram_data_map = icode->gpr_map + 512; icode->tram_addr_map = icode->tram_data_map + 256; @@ -1159,12 +1159,12 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) /* Optical SPDIF Playback Volume */ A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L); A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R); - snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0); + snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0); gpr += 2; /* Optical SPDIF Capture Volume */ A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L); A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R); - snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0); + snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0); gpr += 2; /* Line2 Playback Volume */ @@ -1389,7 +1389,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000); } } - snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0); + snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0); gpr += 2; A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); @@ -1431,7 +1431,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) __err: kfree(controls); if (icode != NULL) { - kfree((void *)icode->gpr_map); + kfree((void __force *)icode->gpr_map); kfree(icode); } return err; @@ -1503,15 +1503,15 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) spin_lock_init(&emu->fx8010.irq_lock); INIT_LIST_HEAD(&emu->fx8010.gpr_ctl); - if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL) + if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL) return -ENOMEM; if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL || (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL || - (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) { + (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) { err = -ENOMEM; goto __err; } - gpr_map = (u32 *)icode->gpr_map; + gpr_map = (u32 __force *)icode->gpr_map; icode->tram_data_map = icode->gpr_map + 256; icode->tram_addr_map = icode->tram_data_map + 160; @@ -1716,7 +1716,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) /* IEC958 TTL Playback Volume */ for (z = 0; z < 2; z++) VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z); - snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0); + snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0); gpr += 2; /* IEC958 TTL Capture Volume + Switch */ @@ -1724,8 +1724,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z); VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); } - snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0); - snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0); + snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0); + snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0); gpr += 4; } @@ -1750,7 +1750,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) /* IEC958 Optical Playback Volume */ for (z = 0; z < 2; z++) VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z); - snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0); + snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0); gpr += 2; /* IEC958 Optical Capture Volume */ @@ -1758,8 +1758,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z); VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); } - snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0); - snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0); + snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0); + snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0); gpr += 4; } @@ -1784,7 +1784,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) /* IEC958 Coax Playback Volume */ for (z = 0; z < 2; z++) VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z); - snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0); + snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0); gpr += 2; /* IEC958 Coax Capture Volume + Switch */ @@ -1792,8 +1792,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z); VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); } - snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0); - snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0); + snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0); + snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0); gpr += 4; } @@ -1920,7 +1920,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) #endif } - snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0); + snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0); gpr += 2; } @@ -2032,7 +2032,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) kfree(ipcm); kfree(controls); if (icode != NULL) { - kfree((void *)icode->gpr_map); + kfree((void __force *)icode->gpr_map); kfree(icode); } return err; @@ -2217,7 +2217,7 @@ static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigne kfree(ipcm); return res; case SNDRV_EMU10K1_IOCTL_PCM_PEEK: - ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL); + ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL); if (ipcm == NULL) return -ENOMEM; if (copy_from_user(ipcm, argp, sizeof(*ipcm))) { diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 6be82c5fe138..7cc831ccd0cb 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -181,7 +181,7 @@ static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), .count = 4, .info = snd_emu10k1_spdif_info, @@ -190,7 +190,7 @@ static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control = static snd_kcontrol_new_t snd_emu10k1_spdif_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .count = 4, .info = snd_emu10k1_spdif_info, @@ -295,7 +295,7 @@ static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_emu10k1_send_routing_control = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "EMU10K1 PCM Send Routing", .count = 32, .info = snd_emu10k1_send_routing_info, @@ -364,7 +364,7 @@ static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_emu10k1_send_volume_control = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "EMU10K1 PCM Send Volume", .count = 32, .info = snd_emu10k1_send_volume_info, @@ -427,7 +427,7 @@ static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_emu10k1_attn_control = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "EMU10K1 PCM Volume", .count = 32, .info = snd_emu10k1_attn_info, @@ -737,7 +737,8 @@ static int rename_ctl(snd_card_t *card, const char *src, const char *dst) return -ENOENT; } -int __devinit snd_emu10k1_mixer(emu10k1_t *emu) +int __devinit snd_emu10k1_mixer(emu10k1_t *emu, + int pcm_device, int multi_device) { int err, pcm; snd_kcontrol_t *kctl; @@ -809,8 +810,14 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) ac97.private_data = emu; ac97.private_free = snd_emu10k1_mixer_free_ac97; ac97.scaps = AC97_SCAP_NO_SPDIF; - if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) - return err; + if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) { + if (emu->card_capabilities->ac97_chip == 1) + return err; + snd_printd(KERN_INFO "emu10k1: AC97 is optional on this board\n"); + snd_printd(KERN_INFO" Proceeding without ac97 mixers...\n"); + snd_device_free(emu->card, pbus); + goto no_ac97; /* FIXME: get rid of ugly gotos.. */ + } if (emu->audigy) { /* set master volume to 0 dB */ snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000); @@ -835,6 +842,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) for (; *c; c++) remove_ctl(card, *c); } else { + no_ac97: if (emu->card_capabilities->ecard) strcpy(emu->card->mixername, "EMU APS"); else if (emu->audigy) @@ -852,29 +860,35 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL) return -ENOMEM; + kctl->id.device = pcm_device; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL) return -ENOMEM; + kctl->id.device = pcm_device; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL) return -ENOMEM; + kctl->id.device = pcm_device; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL) return -ENOMEM; + kctl->id.device = multi_device; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL) return -ENOMEM; + kctl->id.device = multi_device; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL) return -ENOMEM; + kctl->id.device = multi_device; if ((err = snd_ctl_add(card, kctl))) return err; @@ -924,10 +938,14 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) /* sb live! and audigy */ if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL) return -ENOMEM; + if (!emu->audigy) + kctl->id.device = emu->pcm_efx->device; if ((err = snd_ctl_add(card, kctl))) return err; if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL) return -ENOMEM; + if (!emu->audigy) + kctl->id.device = emu->pcm_efx->device; if ((err = snd_ctl_add(card, kctl))) return err; } diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 520b99af5f55..66ba27afe962 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -1016,7 +1016,7 @@ static int snd_emu10k1_efx_playback_open(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; int i; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1049,7 +1049,7 @@ static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; int i, err; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1094,7 +1094,7 @@ static int snd_emu10k1_capture_open(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; emu10k1_pcm_t *epcm; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1130,7 +1130,7 @@ static int snd_emu10k1_capture_mic_open(snd_pcm_substream_t * substream) emu10k1_pcm_t *epcm; snd_pcm_runtime_t *runtime = substream->runtime; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1170,7 +1170,7 @@ static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream) int nefx = emu->audigy ? 64 : 32; int idx; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1682,6 +1682,7 @@ static void snd_emu10k1_pcm_efx_free(snd_pcm_t *pcm) int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) { snd_pcm_t *pcm; + snd_kcontrol_t *kctl; int err; if (rpcm) @@ -1714,7 +1715,11 @@ int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm emu->efx_voices_mask[0] = 0xffff0000; emu->efx_voices_mask[1] = 0; } - snd_ctl_add(emu->card, snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu)); + kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu); + if (!kctl) + return -ENOMEM; + kctl->id.device = device; + snd_ctl_add(emu->card, kctl); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index a1691330d3b6..d59c7f345ad6 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -178,7 +178,7 @@ static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, in snd_pcm_runtime_t *runtime = substream->runtime; int err; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); //snd_printk("epcm kcalloc: %p\n", epcm); if (epcm == NULL) @@ -214,7 +214,7 @@ static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int snd_pcm_runtime_t *runtime = substream->runtime; int err; - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); //snd_printk("epcm kcalloc: %p\n", epcm); if (epcm == NULL) diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 78a81f3912a1..bef9a59f46d7 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -100,13 +100,6 @@ MODULE_PARM_DESC(joystick, "Enable joystick."); #endif #endif /* SUPPORT_JOYSTICK */ -#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880 -#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 -#endif -#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371 -#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 -#endif - /* ES1371 chip ID */ /* This is a little confusing because all ES1371 compatible chips have the same DEVICE_ID, the only thing differentiating them is the REV_ID field. @@ -1444,7 +1437,7 @@ static int snd_es1371_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t /* spdif controls */ static snd_kcontrol_new_t snd_es1371_mixer_spdif[] __devinitdata = { - ES1371_SPDIF("IEC958 Playback Switch"), + ES1371_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH)), { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1950,7 +1943,7 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, *rensoniq = NULL; if ((err = pci_enable_device(pci)) < 0) return err; - ensoniq = kcalloc(1, sizeof(*ensoniq), GFP_KERNEL); + ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL); if (ensoniq == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -2394,6 +2387,7 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, .id_table = snd_audiopci_ids, .probe = snd_audiopci_probe, .remove = __devexit_p(snd_audiopci_remove), diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index b492777bc30f..17fa80c23870 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -76,13 +76,6 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES1938}," #define SUPPORT_JOYSTICK 1 #endif -#ifndef PCI_VENDOR_ID_ESS -#define PCI_VENDOR_ID_ESS 0x125d -#endif -#ifndef PCI_DEVICE_ID_ESS_ES1938 -#define PCI_DEVICE_ID_ESS_ES1938 0x1969 -#endif - static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ @@ -1501,7 +1494,7 @@ static int __devinit snd_es1938_create(snd_card_t * card, return -ENXIO; } - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1753,6 +1746,7 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ESS ES1938 (Solo-1)", + .owner = THIS_MODULE, .id_table = snd_es1938_ids, .probe = snd_es1938_probe, .remove = __devexit_p(snd_es1938_remove), diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 9d7a28783930..ecdcada90ca2 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -160,25 +160,6 @@ MODULE_PARM_DESC(joystick, "Enable joystick."); #endif -/* PCI Dev ID's */ - -#ifndef PCI_VENDOR_ID_ESS -#define PCI_VENDOR_ID_ESS 0x125D -#endif - -#define PCI_VENDOR_ID_ESS_OLD 0x1285 /* Platform Tech, the people the ESS - was bought form */ - -#ifndef PCI_DEVICE_ID_ESS_M2E -#define PCI_DEVICE_ID_ESS_M2E 0x1978 -#endif -#ifndef PCI_DEVICE_ID_ESS_M2 -#define PCI_DEVICE_ID_ESS_M2 0x1968 -#endif -#ifndef PCI_DEVICE_ID_ESS_M1 -#define PCI_DEVICE_ID_ESS_M1 0x0100 -#endif - #define NR_APUS 64 #define NR_APU_REGS 16 @@ -1596,7 +1577,7 @@ static int snd_es1968_playback_open(snd_pcm_substream_t *substream) if (apu1 < 0) return apu1; - es = kcalloc(1, sizeof(*es), GFP_KERNEL); + es = kzalloc(sizeof(*es), GFP_KERNEL); if (!es) { snd_es1968_free_apu_pair(chip, apu1); return -ENOMEM; @@ -1641,7 +1622,7 @@ static int snd_es1968_capture_open(snd_pcm_substream_t *substream) return apu2; } - es = kcalloc(1, sizeof(*es), GFP_KERNEL); + es = kzalloc(sizeof(*es), GFP_KERNEL); if (!es) { snd_es1968_free_apu_pair(chip, apu1); snd_es1968_free_apu_pair(chip, apu2); @@ -2588,7 +2569,7 @@ static int __devinit snd_es1968_create(snd_card_t * card, return -ENXIO; } - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (! chip) { pci_disable_device(pci); return -ENOMEM; @@ -2782,6 +2763,7 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ES1968 (ESS Maestro)", + .owner = THIS_MODULE, .id_table = snd_es1968_ids, .probe = snd_es1968_probe, .remove = __devexit_p(snd_es1968_remove), diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index ff10e637a95e..e5cfa2a0c246 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1155,10 +1155,10 @@ FM801_SINGLE("FM Playback Switch", FM801_FM_VOL, 15, 1, 1), static snd_kcontrol_new_t snd_fm801_controls_multi[] __devinitdata = { FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0), FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0), -FM801_SINGLE("IEC958 Capture Switch", FM801_I2S_MODE, 8, 1, 0), -FM801_SINGLE("IEC958 Raw Data Playback Switch", FM801_I2S_MODE, 9, 1, 0), -FM801_SINGLE("IEC958 Raw Data Capture Switch", FM801_I2S_MODE, 10, 1, 0), -FM801_SINGLE("IEC958 Playback Switch", FM801_GEN_CTRL, 2, 1, 0), +FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), FM801_I2S_MODE, 8, 1, 0), +FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",PLAYBACK,SWITCH), FM801_I2S_MODE, 9, 1, 0), +FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",CAPTURE,SWITCH), FM801_I2S_MODE, 10, 1, 0), +FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), FM801_GEN_CTRL, 2, 1, 0), }; static void snd_fm801_mixer_free_ac97_bus(ac97_bus_t *bus) @@ -1263,7 +1263,7 @@ static int __devinit snd_fm801_create(snd_card_t * card, *rchip = NULL; if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1462,6 +1462,7 @@ static void __devexit snd_card_fm801_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "FM801", + .owner = THIS_MODULE, .id_table = snd_fm801_ids, .probe = snd_card_fm801_probe, .remove = __devexit_p(snd_card_fm801_remove), diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index bd8cb33c4fb4..ddfb5ff7fb8f 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -1,5 +1,5 @@ snd-hda-intel-objs := hda_intel.o -snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o +snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o ifdef CONFIG_PROC_FS snd-hda-codec-objs += hda_proc.o endif diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e2cf02387289..3815403ed095 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -288,7 +288,7 @@ static int init_unsol_queue(struct hda_bus *bus) { struct hda_bus_unsolicited *unsol; - unsol = kcalloc(1, sizeof(*unsol), GFP_KERNEL); + unsol = kzalloc(sizeof(*unsol), GFP_KERNEL); if (! unsol) { snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); return -ENOMEM; @@ -358,7 +358,7 @@ int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp, if (busp) *busp = NULL; - bus = kcalloc(1, sizeof(*bus), GFP_KERNEL); + bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (bus == NULL) { snd_printk(KERN_ERR "can't allocate struct hda_bus\n"); return -ENOMEM; @@ -432,22 +432,26 @@ void snd_hda_get_codec_name(struct hda_codec *codec, } /* - * look for an AFG node - * - * return 0 if not found + * look for an AFG and MFG nodes */ -static int look_for_afg_node(struct hda_codec *codec) +static void setup_fg_nodes(struct hda_codec *codec) { int i, total_nodes; hda_nid_t nid; total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); for (i = 0; i < total_nodes; i++, nid++) { - if ((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff) == - AC_GRP_AUDIO_FUNCTION) - return nid; + switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) { + case AC_GRP_AUDIO_FUNCTION: + codec->afg = nid; + break; + case AC_GRP_MODEM_FUNCTION: + codec->mfg = nid; + break; + default: + break; + } } - return 0; } /* @@ -489,7 +493,7 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, return -EBUSY; } - codec = kcalloc(1, sizeof(*codec), GFP_KERNEL); + codec = kzalloc(sizeof(*codec), GFP_KERNEL); if (codec == NULL) { snd_printk(KERN_ERR "can't allocate struct hda_codec\n"); return -ENOMEM; @@ -507,10 +511,9 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); - /* FIXME: support for multiple AFGs? */ - codec->afg = look_for_afg_node(codec); - if (! codec->afg) { - snd_printdd("hda_codec: no AFG node found\n"); + setup_fg_nodes(codec); + if (! codec->afg && ! codec->mfg) { + snd_printdd("hda_codec: no AFG or MFG node found\n"); snd_hda_codec_free(codec); return -ENODEV; } @@ -749,12 +752,14 @@ int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t long *valp = ucontrol->value.integer.value; int change = 0; - if (chs & 1) + if (chs & 1) { change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, 0x7f, *valp); + valp++; + } if (chs & 2) change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, - 0x7f, valp[1]); + 0x7f, *valp); return change; } @@ -796,12 +801,15 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t long *valp = ucontrol->value.integer.value; int change = 0; - if (chs & 1) + if (chs & 1) { change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, 0x80, *valp ? 0 : 0x80); + valp++; + } if (chs & 2) change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, - 0x80, valp[1] ? 0 : 0x80); + 0x80, *valp ? 0 : 0x80); + return change; } @@ -1155,8 +1163,16 @@ int snd_hda_build_controls(struct hda_bus *bus) /* * stream formats */ -static unsigned int rate_bits[][3] = { +struct hda_rate_tbl { + unsigned int hz; + unsigned int alsa_bits; + unsigned int hda_fmt; +}; + +static struct hda_rate_tbl rate_bits[] = { /* rate in Hz, ALSA rate bitmask, HDA format value */ + + /* autodetected value used in snd_hda_query_supported_pcm */ { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ @@ -1168,7 +1184,11 @@ static unsigned int rate_bits[][3] = { { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ - { 0 } + + /* not autodetected value */ + { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ + + { 0 } /* terminator */ }; /** @@ -1190,12 +1210,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, int i; unsigned int val = 0; - for (i = 0; rate_bits[i][0]; i++) - if (rate_bits[i][0] == rate) { - val = rate_bits[i][2]; + for (i = 0; rate_bits[i].hz; i++) + if (rate_bits[i].hz == rate) { + val = rate_bits[i].hda_fmt; break; } - if (! rate_bits[i][0]) { + if (! rate_bits[i].hz) { snd_printdd("invalid rate %d\n", rate); return 0; } @@ -1258,9 +1278,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, if (ratesp) { u32 rates = 0; - for (i = 0; rate_bits[i][0]; i++) { + for (i = 0; rate_bits[i].hz; i++) { if (val & (1 << i)) - rates |= rate_bits[i][1]; + rates |= rate_bits[i].alsa_bits; } *ratesp = rates; } @@ -1352,13 +1372,13 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, } rate = format & 0xff00; - for (i = 0; rate_bits[i][0]; i++) - if (rate_bits[i][2] == rate) { + for (i = 0; rate_bits[i].hz; i++) + if (rate_bits[i].hda_fmt == rate) { if (val & (1 << i)) break; return 0; } - if (! rate_bits[i][0]) + if (! rate_bits[i].hz) return 0; stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); @@ -1541,8 +1561,11 @@ int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_c for (c = tbl; c->modelname || c->pci_subvendor; c++) { if (c->pci_subvendor == subsystem_vendor && (! c->pci_subdevice /* all match */|| - (c->pci_subdevice == subsystem_device))) + (c->pci_subdevice == subsystem_device))) { + snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n", + subsystem_vendor, subsystem_device, c->config); return c->config; + } } } return -1; @@ -1803,11 +1826,25 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c cfg->line_out_pins[j] = nid; } - /* Swap surround and CLFE: the association order is front/CLFE/surr/back */ - if (cfg->line_outs >= 3) { + /* Reorder the surround channels + * ALSA sequence is front/surr/clfe/side + * HDA sequence is: + * 4-ch: front/surr => OK as it is + * 6-ch: front/clfe/surr + * 8-ch: front/clfe/side/surr + */ + switch (cfg->line_outs) { + case 3: nid = cfg->line_out_pins[1]; cfg->line_out_pins[1] = cfg->line_out_pins[2]; cfg->line_out_pins[2] = nid; + break; + case 4: + nid = cfg->line_out_pins[1]; + cfg->line_out_pins[1] = cfg->line_out_pins[3]; + cfg->line_out_pins[3] = cfg->line_out_pins[2]; + cfg->line_out_pins[2] = nid; + break; } return 0; diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index dd0d99d2ad27..bb53bcf76742 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -505,6 +505,7 @@ struct hda_pcm_stream { struct hda_pcm { char *name; struct hda_pcm_stream stream[2]; + unsigned int is_modem; /* modem codec? */ }; /* codec information */ @@ -514,6 +515,7 @@ struct hda_codec { struct list_head list; /* list point */ hda_nid_t afg; /* AFG node id */ + hda_nid_t mfg; /* MFG node id */ /* ids */ u32 vendor_id; diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 2d046abb5911..d0eb9f2250aa 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -98,7 +98,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid struct hda_gnode *node; int nconns; - node = kcalloc(1, sizeof(*node), GFP_KERNEL); + node = kzalloc(sizeof(*node), GFP_KERNEL); if (node == NULL) return -ENOMEM; node->nid = nid; @@ -881,7 +881,10 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec) struct hda_gspec *spec; int err; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + if(!codec->afg) + return 0; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) { printk(KERN_ERR "hda_generic: can't allocate spec\n"); return -ENOMEM; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 288ab0764830..6fe696e53ea6 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -62,7 +62,7 @@ MODULE_PARM_DESC(enable, "Enable Intel HD audio interface."); module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param_array(position_fix, int, NULL, 0444); -MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF)."); +MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," @@ -71,7 +71,9 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ESB2}," "{ATI, SB450}," "{VIA, VT8251}," - "{VIA, VT8237A}}"); + "{VIA, VT8237A}," + "{SiS, SIS966}," + "{ULI, M5461}}"); MODULE_DESCRIPTION("Intel HDA driver"); #define SFX "hda-intel: " @@ -141,13 +143,30 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; */ /* max number of SDs */ -#define MAX_ICH6_DEV 8 +/* ICH, ATI and VIA have 4 playback and 4 capture */ +#define ICH6_CAPTURE_INDEX 0 +#define ICH6_NUM_CAPTURE 4 +#define ICH6_PLAYBACK_INDEX 4 +#define ICH6_NUM_PLAYBACK 4 + +/* ULI has 6 playback and 5 capture */ +#define ULI_CAPTURE_INDEX 0 +#define ULI_NUM_CAPTURE 5 +#define ULI_PLAYBACK_INDEX 5 +#define ULI_NUM_PLAYBACK 6 + +/* this number is statically defined for simplicity */ +#define MAX_AZX_DEV 16 + /* max number of fragments - we may use more if allocating more pages for BDL */ -#define AZX_MAX_FRAG (PAGE_SIZE / (MAX_ICH6_DEV * 16)) +#define BDL_SIZE PAGE_ALIGN(8192) +#define AZX_MAX_FRAG (BDL_SIZE / (MAX_AZX_DEV * 16)) /* max buffer size - no h/w limit, you can increase as you like */ #define AZX_MAX_BUF_SIZE (1024*1024*1024) /* max number of PCM devics per card */ -#define AZX_MAX_PCMS 8 +#define AZX_MAX_AUDIO_PCMS 6 +#define AZX_MAX_MODEM_PCMS 2 +#define AZX_MAX_PCMS (AZX_MAX_AUDIO_PCMS + AZX_MAX_MODEM_PCMS) /* RIRB int mask: overrun[2], response[0] */ #define RIRB_INT_RESPONSE 0x01 @@ -194,13 +213,13 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; /* position fix mode */ enum { - POS_FIX_FIFO, + POS_FIX_AUTO, POS_FIX_NONE, - POS_FIX_POSBUF + POS_FIX_POSBUF, + POS_FIX_FIFO, }; /* Defines for ATI HD Audio support in SB450 south bridge */ -#define ATI_SB450_HDAUDIO_PCI_DEVICE_ID 0x437b #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 #define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 @@ -227,6 +246,7 @@ struct snd_azx_dev { unsigned int fragsize; /* size of each period in bytes */ unsigned int frags; /* number for period in the play buffer */ unsigned int fifo_size; /* FIFO size */ + unsigned int last_pos; /* last updated period position */ void __iomem *sd_addr; /* stream descriptor pointer */ @@ -240,6 +260,7 @@ struct snd_azx_dev { unsigned int opened: 1; unsigned int running: 1; + unsigned int period_updating: 1; }; /* CORB/RIRB */ @@ -258,6 +279,14 @@ struct snd_azx { snd_card_t *card; struct pci_dev *pci; + /* chip type specific */ + int driver_type; + int playback_streams; + int playback_index_offset; + int capture_streams; + int capture_index_offset; + int num_streams; + /* pci resources */ unsigned long addr; void __iomem *remap_addr; @@ -267,8 +296,8 @@ struct snd_azx { spinlock_t reg_lock; struct semaphore open_mutex; - /* streams */ - azx_dev_t azx_dev[MAX_ICH6_DEV]; + /* streams (x num_streams) */ + azx_dev_t *azx_dev; /* PCM */ unsigned int pcm_devs; @@ -292,6 +321,23 @@ struct snd_azx { unsigned int initialized: 1; }; +/* driver types */ +enum { + AZX_DRIVER_ICH, + AZX_DRIVER_ATI, + AZX_DRIVER_VIA, + AZX_DRIVER_SIS, + AZX_DRIVER_ULI, +}; + +static char *driver_short_names[] __devinitdata = { + [AZX_DRIVER_ICH] = "HDA Intel", + [AZX_DRIVER_ATI] = "HDA ATI SB", + [AZX_DRIVER_VIA] = "HDA VIA VT82xx", + [AZX_DRIVER_SIS] = "HDA SIS966", + [AZX_DRIVER_ULI] = "HDA ULI M5461" +}; + /* * macros for easy use */ @@ -360,6 +406,8 @@ static void azx_init_cmd_io(azx_t *chip) azx_writel(chip, CORBLBASE, (u32)chip->corb.addr); azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr)); + /* set the corb size to 256 entries (ULI requires explicitly) */ + azx_writeb(chip, CORBSIZE, 0x02); /* set the corb write pointer to 0 */ azx_writew(chip, CORBWP, 0); /* reset the corb hw read pointer */ @@ -373,6 +421,8 @@ static void azx_init_cmd_io(azx_t *chip) azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr)); + /* set the rirb size to 256 entries (ULI requires explicitly) */ + azx_writeb(chip, RIRBSIZE, 0x02); /* reset the rirb hw write pointer */ azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR); /* set N=1, get RIRB response interrupt for new entry */ @@ -596,7 +646,7 @@ static void azx_int_disable(azx_t *chip) int i; /* disable interrupts in stream descriptor */ - for (i = 0; i < MAX_ICH6_DEV; i++) { + for (i = 0; i < chip->num_streams; i++) { azx_dev_t *azx_dev = &chip->azx_dev[i]; azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK); @@ -616,7 +666,7 @@ static void azx_int_clear(azx_t *chip) int i; /* clear stream status */ - for (i = 0; i < MAX_ICH6_DEV; i++) { + for (i = 0; i < chip->num_streams; i++) { azx_dev_t *azx_dev = &chip->azx_dev[i]; azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); } @@ -679,15 +729,12 @@ static void azx_init_chip(azx_t *chip) /* initialize the codec command I/O */ azx_init_cmd_io(chip); - if (chip->position_fix == POS_FIX_POSBUF) { - /* program the position buffer */ - azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); - azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); - } + /* program the position buffer */ + azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); + azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); /* For ATI SB450 azalia HD audio, we need to enable snoop */ - if (chip->pci->vendor == PCI_VENDOR_ID_ATI && - chip->pci->device == ATI_SB450_HDAUDIO_PCI_DEVICE_ID) { + if (chip->driver_type == AZX_DRIVER_ATI) { pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, &ati_misc_cntl2); pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, @@ -714,14 +761,16 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) return IRQ_NONE; } - for (i = 0; i < MAX_ICH6_DEV; i++) { + for (i = 0; i < chip->num_streams; i++) { azx_dev = &chip->azx_dev[i]; if (status & azx_dev->sd_int_sta_mask) { azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); if (azx_dev->substream && azx_dev->running) { + azx_dev->period_updating = 1; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(azx_dev->substream); spin_lock(&chip->reg_lock); + azx_dev->period_updating = 0; } } } @@ -822,11 +871,9 @@ static int azx_setup_controller(azx_t *chip, azx_dev_t *azx_dev) /* upper BDL address */ azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr)); - if (chip->position_fix == POS_FIX_POSBUF) { - /* enable the position buffer */ - if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) - azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); - } + /* enable the position buffer */ + if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) + azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); /* set the interrupt enable bits in the descriptor control register */ azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); @@ -879,9 +926,15 @@ static int __devinit azx_codec_create(azx_t *chip, const char *model) /* assign a stream for the PCM */ static inline azx_dev_t *azx_assign_device(azx_t *chip, int stream) { - int dev, i; - dev = stream == SNDRV_PCM_STREAM_PLAYBACK ? 4 : 0; - for (i = 0; i < 4; i++, dev++) + int dev, i, nums; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + dev = chip->playback_index_offset; + nums = chip->playback_streams; + } else { + dev = chip->capture_index_offset; + nums = chip->capture_streams; + } + for (i = 0; i < nums; i++, dev++) if (! chip->azx_dev[dev].opened) { chip->azx_dev[dev].opened = 1; return &chip->azx_dev[dev]; @@ -899,8 +952,8 @@ static snd_pcm_hardware_t azx_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_PAUSE /*|*/ + /*SNDRV_PCM_INFO_RESUME*/), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, @@ -1028,6 +1081,7 @@ static int azx_pcm_prepare(snd_pcm_substream_t *substream) azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; else azx_dev->fifo_size = 0; + azx_dev->last_pos = 0; return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, azx_dev->format_val, substream); @@ -1049,6 +1103,7 @@ static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd) azx_dev->running = 1; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: azx_stream_stop(chip, azx_dev); azx_dev->running = 0; @@ -1058,6 +1113,7 @@ static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd) } spin_unlock(&chip->reg_lock); if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH || + cmd == SNDRV_PCM_TRIGGER_SUSPEND || cmd == SNDRV_PCM_TRIGGER_STOP) { int timeout = 5000; while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout) @@ -1081,6 +1137,31 @@ static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream) pos = azx_sd_readl(azx_dev, SD_LPIB); if (chip->position_fix == POS_FIX_FIFO) pos += azx_dev->fifo_size; +#if 0 /* disabled temprarily, auto-correction doesn't work well... */ + else if (chip->position_fix == POS_FIX_AUTO && azx_dev->period_updating) { + /* check the validity of DMA position */ + unsigned int diff = 0; + azx_dev->last_pos += azx_dev->fragsize; + if (azx_dev->last_pos > pos) + diff = azx_dev->last_pos - pos; + if (azx_dev->last_pos >= azx_dev->bufsize) { + if (pos < azx_dev->fragsize) + diff = 0; + azx_dev->last_pos = 0; + } + if (diff > 0 && diff <= azx_dev->fifo_size) + pos += azx_dev->fifo_size; + else { + snd_printdd(KERN_INFO "hda_intel: DMA position fix %d, switching to posbuf\n", diff); + chip->position_fix = POS_FIX_POSBUF; + pos = *azx_dev->posbuf; + } + azx_dev->period_updating = 0; + } +#else + else if (chip->position_fix == POS_FIX_AUTO) + pos += azx_dev->fifo_size; +#endif } if (pos >= azx_dev->bufsize) pos = 0; @@ -1136,6 +1217,7 @@ static int __devinit create_codec_pcm(azx_t *chip, struct hda_codec *codec, snd_dma_pci_data(chip->pci), 1024 * 64, 1024 * 128); chip->pcm[pcm_dev] = pcm; + chip->pcm_devs = pcm_dev + 1; return 0; } @@ -1150,12 +1232,33 @@ static int __devinit azx_pcm_create(azx_t *chip) if ((err = snd_hda_build_pcms(chip->bus)) < 0) return err; + /* create audio PCMs */ pcm_dev = 0; list_for_each(p, &chip->bus->codec_list) { codec = list_entry(p, struct hda_codec, list); for (c = 0; c < codec->num_pcms; c++) { + if (codec->pcm_info[c].is_modem) + continue; /* create later */ + if (pcm_dev >= AZX_MAX_AUDIO_PCMS) { + snd_printk(KERN_ERR SFX "Too many audio PCMs\n"); + return -EINVAL; + } + err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); + if (err < 0) + return err; + pcm_dev++; + } + } + + /* create modem PCMs */ + pcm_dev = AZX_MAX_AUDIO_PCMS; + list_for_each(p, &chip->bus->codec_list) { + codec = list_entry(p, struct hda_codec, list); + for (c = 0; c < codec->num_pcms; c++) { + if (! codec->pcm_info[c].is_modem) + continue; /* already created */ if (pcm_dev >= AZX_MAX_PCMS) { - snd_printk(KERN_ERR SFX "Too many PCMs\n"); + snd_printk(KERN_ERR SFX "Too many modem PCMs\n"); return -EINVAL; } err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev); @@ -1186,13 +1289,12 @@ static int __devinit azx_init_stream(azx_t *chip) /* initialize each stream (aka device) * assign the starting bdl address to each stream (device) and initialize */ - for (i = 0; i < MAX_ICH6_DEV; i++) { + for (i = 0; i < chip->num_streams; i++) { unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4); azx_dev_t *azx_dev = &chip->azx_dev[i]; azx_dev->bdl = (u32 *)(chip->bdl.area + off); azx_dev->bdl_addr = chip->bdl.addr + off; - if (chip->position_fix == POS_FIX_POSBUF) - azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8); + azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8); /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ @@ -1245,7 +1347,7 @@ static int azx_free(azx_t *chip) if (chip->initialized) { int i; - for (i = 0; i < MAX_ICH6_DEV; i++) + for (i = 0; i < chip->num_streams; i++) azx_stream_stop(chip, &chip->azx_dev[i]); /* disable interrupts */ @@ -1261,10 +1363,10 @@ static int azx_free(azx_t *chip) /* wait a little for interrupts to finish */ msleep(1); - - iounmap(chip->remap_addr); } + if (chip->remap_addr) + iounmap(chip->remap_addr); if (chip->irq >= 0) free_irq(chip->irq, (void*)chip); @@ -1276,6 +1378,7 @@ static int azx_free(azx_t *chip) snd_dma_free_pages(&chip->posbuf); pci_release_regions(chip->pci); pci_disable_device(chip->pci); + kfree(chip->azx_dev); kfree(chip); return 0; @@ -1290,7 +1393,8 @@ static int azx_dev_free(snd_device_t *device) * constructor */ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, - int posfix, azx_t **rchip) + int posfix, int driver_type, + azx_t **rchip) { azx_t *chip; int err = 0; @@ -1303,7 +1407,7 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (NULL == chip) { snd_printk(KERN_ERR SFX "cannot allocate chip\n"); @@ -1316,9 +1420,20 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, chip->card = card; chip->pci = pci; chip->irq = -1; + chip->driver_type = driver_type; chip->position_fix = posfix; +#if BITS_PER_LONG != 64 + /* Fix up base address on ULI M5461 */ + if (chip->driver_type == AZX_DRIVER_ULI) { + u16 tmp3; + pci_read_config_word(pci, 0x40, &tmp3); + pci_write_config_word(pci, 0x40, tmp3 | 0x10); + pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0); + } +#endif + if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) { kfree(chip); pci_disable_device(pci); @@ -1344,19 +1459,38 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, pci_set_master(pci); synchronize_irq(chip->irq); + switch (chip->driver_type) { + case AZX_DRIVER_ULI: + chip->playback_streams = ULI_NUM_PLAYBACK; + chip->capture_streams = ULI_NUM_CAPTURE; + chip->playback_index_offset = ULI_PLAYBACK_INDEX; + chip->capture_index_offset = ULI_CAPTURE_INDEX; + break; + default: + chip->playback_streams = ICH6_NUM_PLAYBACK; + chip->capture_streams = ICH6_NUM_CAPTURE; + chip->playback_index_offset = ICH6_PLAYBACK_INDEX; + chip->capture_index_offset = ICH6_CAPTURE_INDEX; + break; + } + chip->num_streams = chip->playback_streams + chip->capture_streams; + chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL); + if (! chip->azx_dev) { + snd_printk(KERN_ERR "cannot malloc azx_dev\n"); + goto errout; + } + /* allocate memory for the BDL for each stream */ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - PAGE_SIZE, &chip->bdl)) < 0) { + BDL_SIZE, &chip->bdl)) < 0) { snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); goto errout; } - if (chip->position_fix == POS_FIX_POSBUF) { - /* allocate memory for the position buffer */ - if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) { - snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); - goto errout; - } + /* allocate memory for the position buffer */ + if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), + chip->num_streams * 8, &chip->posbuf)) < 0) { + snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); + goto errout; } /* allocate CORB/RIRB */ if ((err = azx_alloc_cmd_io(chip)) < 0) @@ -1382,6 +1516,10 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, goto errout; } + strcpy(card->driver, "HDA-Intel"); + strcpy(card->shortname, driver_short_names[chip->driver_type]); + sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); + *rchip = chip; return 0; @@ -1410,15 +1548,12 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id * return -ENOMEM; } - if ((err = azx_create(card, pci, position_fix[dev], &chip)) < 0) { + if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data, + &chip)) < 0) { snd_card_free(card); return err; } - strcpy(card->driver, "HDA-Intel"); - strcpy(card->shortname, "HDA Intel"); - sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); - /* create codec instances */ if ((err = azx_codec_create(chip, model[dev])) < 0) { snd_card_free(card); @@ -1459,12 +1594,13 @@ static void __devexit azx_remove(struct pci_dev *pci) /* PCI IDs */ static struct pci_device_id azx_ids[] = { - { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH6 */ - { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH7 */ - { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ESB2 */ - { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ATI SB450 */ - { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* VIA VT8251/VT8237A */ - { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ALI 5461? */ + { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH6 */ + { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH7 */ + { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */ + { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ + { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ + { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ + { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); @@ -1472,6 +1608,7 @@ MODULE_DEVICE_TABLE(pci, azx_ids); /* pci_driver definition */ static struct pci_driver driver = { .name = "HDA Intel", + .owner = THIS_MODULE, .id_table = azx_ids, .probe = azx_probe, .remove = __devexit_p(azx_remove), diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h index a5de684b6944..acaef3c811b8 100644 --- a/sound/pci/hda/hda_patch.h +++ b/sound/pci/hda/hda_patch.h @@ -10,11 +10,14 @@ extern struct hda_codec_preset snd_hda_preset_cmedia[]; extern struct hda_codec_preset snd_hda_preset_analog[]; /* SigmaTel codecs */ extern struct hda_codec_preset snd_hda_preset_sigmatel[]; +/* SiLabs 3054/3055 modem codecs */ +extern struct hda_codec_preset snd_hda_preset_si3054[]; static const struct hda_codec_preset *hda_preset_tables[] = { snd_hda_preset_realtek, snd_hda_preset_cmedia, snd_hda_preset_analog, snd_hda_preset_sigmatel, + snd_hda_preset_si3054, NULL }; diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index de1217bd8e68..08f6a6efc5e6 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -207,6 +207,8 @@ static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer) snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); + if (! codec->afg) + return; snd_iprintf(buffer, "Default PCM: "); print_pcm_caps(buffer, codec, codec->afg); snd_iprintf(buffer, "Default Amp-In caps: "); diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2fd05bb84136..da6874d3988c 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -465,7 +465,7 @@ static int patch_ad1986a(struct hda_codec *codec) { struct ad198x_spec *spec; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -572,7 +572,7 @@ static snd_kcontrol_new_t ad1983_mixers[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Playback Route", + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = ad1983_spdif_route_info, .get = ad1983_spdif_route_get, .put = ad1983_spdif_route_put, @@ -623,7 +623,7 @@ static int patch_ad1983(struct hda_codec *codec) { struct ad198x_spec *spec; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -705,7 +705,7 @@ static snd_kcontrol_new_t ad1981_mixers[] = { /* identical with AD1983 */ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Playback Route", + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = ad1983_spdif_route_info, .get = ad1983_spdif_route_get, .put = ad1983_spdif_route_put, @@ -764,7 +764,7 @@ static int patch_ad1981(struct hda_codec *codec) { struct ad198x_spec *spec; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 86f195f19eef..523c362ec44d 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -647,6 +647,7 @@ static struct hda_board_config cmi9880_cfg_tbl[] = { { .modelname = "min_fp", .config = CMI_MIN_FP }, { .modelname = "full", .config = CMI_FULL }, { .modelname = "full_dig", .config = CMI_FULL_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x813d, .config = CMI_FULL_DIG }, /* ASUS P5AD2 */ { .modelname = "allout", .config = CMI_ALLOUT }, { .modelname = "auto", .config = CMI_AUTO }, {} /* terminator */ @@ -666,7 +667,7 @@ static int patch_cmi9880(struct hda_codec *codec) { struct cmi_spec *spec; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9b8569900787..7327deb6df9f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -687,6 +687,12 @@ static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = { { } /* end */ }; +/* additional mixers to alc880_asus_mixer */ +static snd_kcontrol_new_t alc880_pcbeep_mixer[] = { + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + { } /* end */ +}; /* * build control elements @@ -1379,8 +1385,8 @@ static snd_kcontrol_new_t alc880_test_mixer[] = { HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - ALC_BIND_MUTE("CLFE Playback Volume", 0x0e, 2, HDA_INPUT), - ALC_BIND_MUTE("Side Playback Volume", 0x0f, 2, HDA_INPUT), + ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), + ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), PIN_CTL_TEST("Front Pin Mode", 0x14), PIN_CTL_TEST("Surround Pin Mode", 0x15), PIN_CTL_TEST("CLFE Pin Mode", 0x16), @@ -1403,18 +1409,6 @@ static snd_kcontrol_new_t alc880_test_mixer[] = { HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 2, - .info = alc_mux_enum_info, - .get = alc_mux_enum_get, - .put = alc_mux_enum_put, - }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -1520,10 +1514,12 @@ static struct hda_board_config alc880_cfg_tbl[] = { /* Back 3 jack, front 2 jack (Internal add Aux-In) */ { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST }, { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST }, /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG }, /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, @@ -1574,6 +1570,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG }, { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS }, @@ -1734,7 +1731,7 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, }, [ALC880_UNIWILL_DIG] = { - .mixers = { alc880_asus_mixer }, + .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2086,7 +2083,7 @@ static int patch_alc880(struct hda_codec *codec) int board_config; int i, err; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -2234,7 +2231,7 @@ static snd_kcontrol_new_t alc260_base_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), - ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT), + ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), { @@ -2261,7 +2258,7 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), - ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT), + ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), { @@ -2358,7 +2355,7 @@ static int patch_alc260(struct hda_codec *codec) struct alc_spec *spec; int board_config; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -2492,7 +2489,7 @@ static snd_kcontrol_new_t alc882_base_mixer[] = { HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_OUTPUT), + ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -2608,7 +2605,7 @@ static int patch_alc882(struct hda_codec *codec) { struct alc_spec *spec; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c new file mode 100644 index 000000000000..d014b7bb70df --- /dev/null +++ b/sound/pci/hda/patch_si3054.c @@ -0,0 +1,301 @@ +/* + * Universal Interface for Intel High Definition Audio Codec + * + * HD audio interface patch for Silicon Labs 3054/5 modem codec + * + * Copyright (c) 2005 Sasha Khapyorsky <sashak@smlink.com> + * Takashi Iwai <tiwai@suse.de> + * + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sound/driver.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/pci.h> +#include <sound/core.h> +#include "hda_codec.h" +#include "hda_local.h" + + +/* si3054 verbs */ +#define SI3054_VERB_READ_NODE 0x900 +#define SI3054_VERB_WRITE_NODE 0x100 + +/* si3054 nodes (registers) */ +#define SI3054_EXTENDED_MID 2 +#define SI3054_LINE_RATE 3 +#define SI3054_LINE_LEVEL 4 +#define SI3054_GPIO_CFG 5 +#define SI3054_GPIO_POLARITY 6 +#define SI3054_GPIO_STICKY 7 +#define SI3054_GPIO_WAKEUP 8 +#define SI3054_GPIO_STATUS 9 +#define SI3054_GPIO_CONTROL 10 +#define SI3054_MISC_AFE 11 +#define SI3054_CHIPID 12 +#define SI3054_LINE_CFG1 13 +#define SI3054_LINE_STATUS 14 +#define SI3054_DC_TERMINATION 15 +#define SI3054_LINE_CONFIG 16 +#define SI3054_CALLPROG_ATT 17 +#define SI3054_SQ_CONTROL 18 +#define SI3054_MISC_CONTROL 19 +#define SI3054_RING_CTRL1 20 +#define SI3054_RING_CTRL2 21 + +/* extended MID */ +#define SI3054_MEI_READY 0xf + +/* line level */ +#define SI3054_ATAG_MASK 0x00f0 +#define SI3054_DTAG_MASK 0xf000 + +/* GPIO bits */ +#define SI3054_GPIO_OH 0x0001 +#define SI3054_GPIO_CID 0x0002 + +/* chipid and revisions */ +#define SI3054_CHIPID_CODEC_REV_MASK 0x000f +#define SI3054_CHIPID_DAA_REV_MASK 0x00f0 +#define SI3054_CHIPID_INTERNATIONAL 0x0100 +#define SI3054_CHIPID_DAA_ID 0x0f00 +#define SI3054_CHIPID_CODEC_ID (1<<12) + +/* si3054 codec registers (nodes) access macros */ +#define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0)) +#define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val)) + + +struct si3054_spec { + unsigned international; + struct hda_pcm pcm; +}; + + +/* + * Modem mixer + */ + +#define PRIVATE_VALUE(reg,mask) ((reg<<16)|(mask&0xffff)) +#define PRIVATE_REG(val) ((val>>16)&0xffff) +#define PRIVATE_MASK(val) (val&0xffff) + +static int si3054_switch_info(snd_kcontrol_t *kcontrol, + snd_ctl_elem_info_t *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int si3054_switch_get(snd_kcontrol_t *kcontrol, + snd_ctl_elem_value_t *uvalue) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + u16 reg = PRIVATE_REG(kcontrol->private_value); + u16 mask = PRIVATE_MASK(kcontrol->private_value); + uvalue->value.integer.value[0] = (GET_REG(codec, reg)) & mask ? 1 : 0 ; + return 0; +} + +static int si3054_switch_put(snd_kcontrol_t *kcontrol, + snd_ctl_elem_value_t *uvalue) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + u16 reg = PRIVATE_REG(kcontrol->private_value); + u16 mask = PRIVATE_MASK(kcontrol->private_value); + if (uvalue->value.integer.value[0]) + SET_REG(codec, reg, (GET_REG(codec, reg)) | mask); + else + SET_REG(codec, reg, (GET_REG(codec, reg)) & ~mask); + return 0; +} + +#define SI3054_KCONTROL(kname,reg,mask) { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = kname, \ + .info = si3054_switch_info, \ + .get = si3054_switch_get, \ + .put = si3054_switch_put, \ + .private_value = PRIVATE_VALUE(reg,mask), \ +} + + +static snd_kcontrol_new_t si3054_modem_mixer[] = { + SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH), + SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID), + {} +}; + +static int si3054_build_controls(struct hda_codec *codec) +{ + return snd_hda_add_new_ctls(codec, si3054_modem_mixer); +} + + +/* + * PCM callbacks + */ + +static int si3054_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + snd_pcm_substream_t *substream) +{ + u16 val; + + SET_REG(codec, SI3054_LINE_RATE, substream->runtime->rate); + val = GET_REG(codec, SI3054_LINE_LEVEL); + val &= 0xff << (8 * (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)); + val |= ((stream_tag & 0xf) << 4) << (8 * (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)); + SET_REG(codec, SI3054_LINE_LEVEL, val); + + snd_hda_codec_setup_stream(codec, hinfo->nid, + stream_tag, 0, format); + return 0; +} + +static int si3054_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + snd_pcm_substream_t *substream) +{ + static unsigned int rates[] = { 8000, 9600, 16000 }; + static snd_pcm_hw_constraint_list_t hw_constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + substream->runtime->hw.period_bytes_min = 80; + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); +} + + +static struct hda_pcm_stream si3054_pcm = { + .substreams = 1, + .channels_min = 1, + .channels_max = 1, + .nid = 0x1, + .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_KNOT, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .maxbps = 16, + .ops = { + .open = si3054_pcm_open, + .prepare = si3054_pcm_prepare, + }, +}; + + +static int si3054_build_pcms(struct hda_codec *codec) +{ + struct si3054_spec *spec = codec->spec; + struct hda_pcm *info = &spec->pcm; + si3054_pcm.nid = codec->mfg; + codec->num_pcms = 1; + codec->pcm_info = info; + info->name = "Si3054 Modem"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; + info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; + info->is_modem = 1; + return 0; +} + + +/* + * Init part + */ + +static int si3054_init(struct hda_codec *codec) +{ + struct si3054_spec *spec = codec->spec; + unsigned wait_count; + u16 val; + + snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0); + snd_hda_codec_write(codec, codec->mfg, 0, AC_VERB_SET_STREAM_FORMAT, 0); + SET_REG(codec, SI3054_LINE_RATE, 9600); + SET_REG(codec, SI3054_LINE_LEVEL, SI3054_DTAG_MASK|SI3054_ATAG_MASK); + SET_REG(codec, SI3054_EXTENDED_MID, 0); + + wait_count = 10; + do { + msleep(2); + val = GET_REG(codec, SI3054_EXTENDED_MID); + } while ((val & SI3054_MEI_READY) != SI3054_MEI_READY && wait_count--); + + if((val&SI3054_MEI_READY) != SI3054_MEI_READY) { + snd_printk(KERN_ERR "si3054: cannot initialize. EXT MID = %04x\n", val); + return -EACCES; + } + + SET_REG(codec, SI3054_GPIO_POLARITY, 0xffff); + SET_REG(codec, SI3054_GPIO_CFG, 0x0); + SET_REG(codec, SI3054_MISC_AFE, 0); + SET_REG(codec, SI3054_LINE_CFG1,0x200); + + if((GET_REG(codec,SI3054_LINE_STATUS) & (1<<6)) == 0) { + snd_printd("Link Frame Detect(FDT) is not ready (line status: %04x)\n", + GET_REG(codec,SI3054_LINE_STATUS)); + } + + spec->international = GET_REG(codec, SI3054_CHIPID) & SI3054_CHIPID_INTERNATIONAL; + + return 0; +} + +static void si3054_free(struct hda_codec *codec) +{ + kfree(codec->spec); +} + + +/* + */ + +static struct hda_codec_ops si3054_patch_ops = { + .build_controls = si3054_build_controls, + .build_pcms = si3054_build_pcms, + .init = si3054_init, + .free = si3054_free, +#ifdef CONFIG_PM + //.suspend = si3054_suspend, + .resume = si3054_init, +#endif +}; + +static int patch_si3054(struct hda_codec *codec) +{ + struct si3054_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + codec->spec = spec; + codec->patch_ops = si3054_patch_ops; + return 0; +} + +/* + * patch entries + */ +struct hda_codec_preset snd_hda_preset_si3054[] = { + { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, + {} +}; + diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 9d503da7320d..33a8adaea768 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -919,7 +919,7 @@ static int patch_stac9200(struct hda_codec *codec) struct sigmatel_spec *spec; int err; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -957,7 +957,7 @@ static int patch_stac922x(struct hda_codec *codec) struct sigmatel_spec *spec; int err; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 4405d96cbedf..2e0a31613ee6 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -1796,7 +1796,7 @@ static int __devinit aureon_init(ice1712_t *ice) } /* to remeber the register values of CS8415 */ - ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL); + ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL); if (! ice->akm) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index eb20f73be61a..39fbe662965d 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -618,15 +618,15 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice) */ static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_select __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); +ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); static snd_kcontrol_new_t snd_ice1712_delta1010lt_wordclock_select __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0); +ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0); static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_status __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); +ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); static snd_kcontrol_new_t snd_ice1712_deltadio2496_spdif_in_select __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); +ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); static snd_kcontrol_new_t snd_ice1712_delta_spdif_in_status __devinitdata = -ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); +ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice) diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index a2545a5b26c4..a6d98013c331 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -100,12 +100,6 @@ MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec r module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); -#ifndef PCI_VENDOR_ID_ICE -#define PCI_VENDOR_ID_ICE 0x1412 -#endif -#ifndef PCI_DEVICE_ID_ICE_1712 -#define PCI_DEVICE_ID_ICE_1712 0x1712 -#endif static struct pci_device_id snd_ice1712_ids[] = { { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */ @@ -1422,7 +1416,7 @@ static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_switch __devinitdata static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Multi Capture Switch", + .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), .info = snd_ice1712_pro_mixer_switch_info, .get = snd_ice1712_pro_mixer_switch_get, .put = snd_ice1712_pro_mixer_switch_put, @@ -1441,7 +1435,7 @@ static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_volume __devinitdata static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Multi Capture Volume", + .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), .info = snd_ice1712_pro_mixer_volume_info, .get = snd_ice1712_pro_mixer_volume_get, .put = snd_ice1712_pro_mixer_volume_put, @@ -1715,7 +1709,7 @@ static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_ice1712_spdif_info, .get = snd_ice1712_spdif_maskc_get, @@ -1724,7 +1718,7 @@ static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata = static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), .info = snd_ice1712_spdif_info, .get = snd_ice1712_spdif_maskp_get, @@ -2203,7 +2197,7 @@ static snd_kcontrol_new_t snd_ice1712_mixer_pro_analog_route __devinitdata = { static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Playback Route", + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = snd_ice1712_pro_route_info, .get = snd_ice1712_pro_route_spdif_get, .put = snd_ice1712_pro_route_spdif_put, @@ -2535,7 +2529,7 @@ static int __devinit snd_ice1712_create(snd_card_t * card, return -ENXIO; } - ice = kcalloc(1, sizeof(*ice), GFP_KERNEL); + ice = kzalloc(sizeof(*ice), GFP_KERNEL); if (ice == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -2741,6 +2735,7 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ICE1712", + .owner = THIS_MODULE, .id_table = snd_ice1712_ids, .probe = snd_ice1712_probe, .remove = __devexit_p(snd_ice1712_remove), diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 79b5f12e06fc..c3ce8f93740b 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -83,12 +83,6 @@ MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard."); module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); -#ifndef PCI_VENDOR_ID_ICE -#define PCI_VENDOR_ID_ICE 0x1412 -#endif -#ifndef PCI_DEVICE_ID_VT1724 -#define PCI_DEVICE_ID_VT1724 0x1724 -#endif /* Both VT1720 and VT1724 have the same PCI IDs */ static struct pci_device_id snd_vt1724_ids[] = { @@ -1414,7 +1408,7 @@ static int snd_vt1724_spdif_maskp_get(snd_kcontrol_t * kcontrol, static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_vt1724_spdif_info, .get = snd_vt1724_spdif_maskc_get, @@ -1423,7 +1417,7 @@ static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata = static snd_kcontrol_new_t snd_vt1724_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), .info = snd_vt1724_spdif_info, .get = snd_vt1724_spdif_maskp_get, @@ -1466,7 +1460,7 @@ static snd_kcontrol_new_t snd_vt1724_spdif_switch __devinitdata = .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* FIXME: the following conflict with IEC958 Playback Route */ // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), - .name = "IEC958 Output Switch", + .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), .info = snd_vt1724_spdif_sw_info, .get = snd_vt1724_spdif_sw_get, .put = snd_vt1724_spdif_sw_put @@ -2130,7 +2124,7 @@ static int __devinit snd_vt1724_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - ice = kcalloc(1, sizeof(*ice), GFP_KERNEL); + ice = kzalloc(sizeof(*ice), GFP_KERNEL); if (ice == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -2321,6 +2315,7 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "ICE1724", + .owner = THIS_MODULE, .id_table = snd_vt1724_ids, .probe = snd_vt1724_probe, .remove = __devexit_p(snd_vt1724_remove), diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 3fb297b969cd..2437876a44e4 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -182,7 +182,7 @@ static int __devinit juli_init(ice1712_t *ice) ice->num_total_dacs = 2; ice->num_total_adcs = 2; - ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL); + ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL); if (! ak) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 5bf734b04fa0..dcf1e8ca3f66 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -122,7 +122,7 @@ static int __devinit phase22_init(ice1712_t *ice) } // Initialize analog chips - ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL); + ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL); if (! ak) return -ENOMEM; ice->akm_codecs = 1; @@ -386,7 +386,7 @@ static int __devinit phase28_init(ice1712_t *ice) ice->num_total_adcs = 2; // Initialize analog chips - ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL); + ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL); if (!ak) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 25f827d8fbd9..a5f852b1f575 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -781,7 +781,7 @@ static int __devinit pontis_init(ice1712_t *ice) ice->num_total_adcs = 2; /* to remeber the register values */ - ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL); + ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL); if (! ice->akm) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index d7af3e474432..1a96198a17ae 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -69,6 +69,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; static char *ac97_quirk[SNDRV_CARDS]; +static int buggy_semaphore[SNDRV_CARDS]; static int buggy_irq[SNDRV_CARDS]; static int xbox[SNDRV_CARDS]; @@ -86,6 +87,8 @@ module_param_array(ac97_clock, int, NULL, 0444); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect)."); module_param_array(ac97_quirk, charp, NULL, 0444); MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); +module_param_array(buggy_semaphore, bool, NULL, 0444); +MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores."); module_param_array(buggy_irq, bool, NULL, 0444); MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); module_param_array(xbox, bool, NULL, 0444); @@ -94,62 +97,6 @@ MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 c /* * Direct registers */ - -#ifndef PCI_DEVICE_ID_INTEL_82801 -#define PCI_DEVICE_ID_INTEL_82801 0x2415 -#endif -#ifndef PCI_DEVICE_ID_INTEL_82901 -#define PCI_DEVICE_ID_INTEL_82901 0x2425 -#endif -#ifndef PCI_DEVICE_ID_INTEL_82801BA -#define PCI_DEVICE_ID_INTEL_82801BA 0x2445 -#endif -#ifndef PCI_DEVICE_ID_INTEL_440MX -#define PCI_DEVICE_ID_INTEL_440MX 0x7195 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH3 -#define PCI_DEVICE_ID_INTEL_ICH3 0x2485 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH4 -#define PCI_DEVICE_ID_INTEL_ICH4 0x24c5 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH5 -#define PCI_DEVICE_ID_INTEL_ICH5 0x24d5 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ESB_5 -#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH6_18 -#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH7_20 -#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de -#endif -#ifndef PCI_DEVICE_ID_INTEL_ESB2_14 -#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698 -#endif -#ifndef PCI_DEVICE_ID_SI_7012 -#define PCI_DEVICE_ID_SI_7012 0x7012 -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_MCP_AUDIO -#define PCI_DEVICE_ID_NVIDIA_MCP_AUDIO 0x01b1 -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_CK804_AUDIO -#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO -#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_CK8_AUDIO -#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO -#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO -#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea -#endif - enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE }; #define ICHREG(x) ICH_REG_##x @@ -389,6 +336,7 @@ typedef struct { struct ac97_pcm *pcm; int pcm_open_flag; unsigned int page_attr_changed: 1; + unsigned int suspended: 1; } ichdev_t; typedef struct _snd_intel8x0 intel8x0_t; @@ -422,6 +370,7 @@ struct _snd_intel8x0 { unsigned fix_nocache: 1; /* workaround for 440MX */ unsigned buggy_irq: 1; /* workaround for buggy mobos */ unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ + unsigned buggy_semaphore: 1; /* workaround for buggy codec semaphore */ int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ unsigned int sdm_saved; /* SDM reg value */ @@ -576,6 +525,9 @@ static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec) if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0) return -EIO; + if (chip->buggy_semaphore) + return 0; /* just ignore ... */ + /* Anyone holding a semaphore for 1 msec should be shot... */ time = 100; do { @@ -862,12 +814,16 @@ static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd) unsigned long port = ichdev->reg_offset; switch (cmd) { - case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: + ichdev->suspended = 0; + /* fallthru */ + case SNDRV_PCM_TRIGGER_START: val = ICH_IOCE | ICH_STARTBM; break; - case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: + ichdev->suspended = 1; + /* fallthru */ + case SNDRV_PCM_TRIGGER_STOP: val = 0; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: @@ -899,9 +855,11 @@ static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd) val = igetdword(chip, ICHREG(ALI_DMACR)); switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + ichdev->suspended = 0; + /* fallthru */ case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* clear FIFO for synchronization of channels */ fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]); @@ -913,9 +871,11 @@ static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd) val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */ iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */ break; + case SNDRV_PCM_TRIGGER_SUSPEND: + ichdev->suspended = 1; + /* fallthru */ case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_SUSPEND: iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */ iputbyte(chip, port + ICH_REG_OFF_CR, 0); while (igetbyte(chip, port + ICH_REG_OFF_CR)) @@ -994,6 +954,8 @@ static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip, { unsigned int cnt; int dbl = runtime->rate > 48000; + + spin_lock_irq(&chip->reg_lock); switch (chip->device_type) { case DEVICE_ALI: cnt = igetdword(chip, ICHREG(ALI_SCR)); @@ -1037,6 +999,7 @@ static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip, iputdword(chip, ICHREG(GLOB_CNT), cnt); break; } + spin_unlock_irq(&chip->reg_lock); } static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) @@ -1048,15 +1011,12 @@ static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) ichdev->physbuf = runtime->dma_addr; ichdev->size = snd_pcm_lib_buffer_bytes(substream); ichdev->fragsize = snd_pcm_lib_period_bytes(substream); - spin_lock_irq(&chip->reg_lock); if (ichdev->ichd == ICHD_PCMOUT) { snd_intel8x0_setup_pcm_out(chip, runtime); - if (chip->device_type == DEVICE_INTEL_ICH4) { + if (chip->device_type == DEVICE_INTEL_ICH4) ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; - } } snd_intel8x0_setup_periods(chip, ichdev); - spin_unlock_irq(&chip->reg_lock); return 0; } @@ -1750,6 +1710,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .type = AC97_TUNE_ALC_JACK }, { + .subvendor = 0x1014, + .subdevice = 0x0267, + .name = "IBM NetVista A30p", /* AD1981B */ + .type = AC97_TUNE_HP_ONLY + }, + { .subvendor = 0x1028, .subdevice = 0x00d8, .name = "Dell Precision 530", /* AD1885 */ @@ -1817,6 +1783,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { }, { .subvendor = 0x103c, + .subdevice = 0x0934, + .name = "HP nx8220", + .type = AC97_TUNE_MUTE_LED + }, + { + .subvendor = 0x103c, + .subdevice = 0x099c, + .name = "HP nx6110", /* AD1981B */ + .type = AC97_TUNE_HP_ONLY + }, + { + .subvendor = 0x103c, .subdevice = 0x129d, .name = "HP xw8000", .type = AC97_TUNE_HP_ONLY @@ -1870,6 +1848,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .type = AC97_TUNE_HP_ONLY }, { + .subvendor = 0x10cf, + .subdevice = 0x12ec, + .name = "Fujitsu-Siemens 4010", + .type = AC97_TUNE_HP_ONLY + }, + { .subvendor = 0x10f1, .subdevice = 0x2665, .name = "Fujitsu-Siemens Celsius", /* AD1981? */ @@ -2424,6 +2408,20 @@ static int intel8x0_resume(snd_card_t *card) } } + /* resume status */ + for (i = 0; i < chip->bdbars_count; i++) { + ichdev_t *ichdev = &chip->ichd[i]; + unsigned long port = ichdev->reg_offset; + if (! ichdev->substream || ! ichdev->suspended) + continue; + if (ichdev->ichd == ICHD_PCMOUT) + snd_intel8x0_setup_pcm_out(chip, ichdev->substream->runtime); + iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr); + iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi); + iputbyte(chip, port + ICH_REG_OFF_CIV, ichdev->civ); + iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); + } + return 0; } #endif /* CONFIG_PM */ @@ -2558,6 +2556,7 @@ struct ich_reg_info { static int __devinit snd_intel8x0_create(snd_card_t * card, struct pci_dev *pci, unsigned long device_type, + int buggy_sem, intel8x0_t ** r_intel8x0) { intel8x0_t *chip; @@ -2605,7 +2604,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -2615,6 +2614,7 @@ static int __devinit snd_intel8x0_create(snd_card_t * card, chip->card = card; chip->pci = pci; chip->irq = -1; + chip->buggy_semaphore = buggy_sem; if (pci->vendor == PCI_VENDOR_ID_INTEL && pci->device == PCI_DEVICE_ID_INTEL_440MX) @@ -2754,19 +2754,19 @@ static struct shortname_table { unsigned int id; const char *s; } shortnames[] __devinitdata = { - { PCI_DEVICE_ID_INTEL_82801, "Intel 82801AA-ICH" }, - { PCI_DEVICE_ID_INTEL_82901, "Intel 82901AB-ICH0" }, - { PCI_DEVICE_ID_INTEL_82801BA, "Intel 82801BA-ICH2" }, + { PCI_DEVICE_ID_INTEL_82801AA_5, "Intel 82801AA-ICH" }, + { PCI_DEVICE_ID_INTEL_82801AB_5, "Intel 82901AB-ICH0" }, + { PCI_DEVICE_ID_INTEL_82801BA_4, "Intel 82801BA-ICH2" }, { PCI_DEVICE_ID_INTEL_440MX, "Intel 440MX" }, - { PCI_DEVICE_ID_INTEL_ICH3, "Intel 82801CA-ICH3" }, - { PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" }, - { PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" }, + { PCI_DEVICE_ID_INTEL_82801CA_5, "Intel 82801CA-ICH3" }, + { PCI_DEVICE_ID_INTEL_82801DB_5, "Intel 82801DB-ICH4" }, + { PCI_DEVICE_ID_INTEL_82801EB_5, "Intel ICH5" }, { PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" }, { PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" }, { PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" }, { PCI_DEVICE_ID_INTEL_ESB2_14, "Intel ESB2" }, { PCI_DEVICE_ID_SI_7012, "SiS SI7012" }, - { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" }, + { PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO, "NVidia nForce" }, { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" }, { PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia nForce3" }, { PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO, "NVidia CK8S" }, @@ -2819,7 +2819,8 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, } } - if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) { + if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, + buggy_semaphore[dev], &chip)) < 0) { snd_card_free(card); return err; } @@ -2863,6 +2864,7 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Intel ICH", + .owner = THIS_MODULE, .id_table = snd_intel8x0_ids, .probe = snd_intel8x0_probe, .remove = __devexit_p(snd_intel8x0_remove), diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index bb758c77d211..9e2060d56c24 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -73,51 +73,6 @@ MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect)."); /* * Direct registers */ - -#ifndef PCI_DEVICE_ID_INTEL_82801_6 -#define PCI_DEVICE_ID_INTEL_82801_6 0x2416 -#endif -#ifndef PCI_DEVICE_ID_INTEL_82901_6 -#define PCI_DEVICE_ID_INTEL_82901_6 0x2426 -#endif -#ifndef PCI_DEVICE_ID_INTEL_82801BA_6 -#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2446 -#endif -#ifndef PCI_DEVICE_ID_INTEL_440MX_6 -#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH3_6 -#define PCI_DEVICE_ID_INTEL_ICH3_6 0x2486 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH4_6 -#define PCI_DEVICE_ID_INTEL_ICH4_6 0x24c6 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH5_6 -#define PCI_DEVICE_ID_INTEL_ICH5_6 0x24d6 -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH6_6 -#define PCI_DEVICE_ID_INTEL_ICH6_6 0x266d -#endif -#ifndef PCI_DEVICE_ID_INTEL_ICH7_6 -#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27dd -#endif -#ifndef PCI_DEVICE_ID_SI_7013 -#define PCI_DEVICE_ID_SI_7013 0x7013 -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_MCP_MODEM -#define PCI_DEVICE_ID_NVIDIA_MCP_MODEM 0x01c1 -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_MODEM -#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069 -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM -#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089 -#endif -#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_MODEM -#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9 -#endif - - enum { DEVICE_INTEL, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE }; #define ICHREG(x) ICH_REG_##x @@ -1158,7 +1113,7 @@ static int __devinit snd_intel8x0m_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1283,18 +1238,18 @@ static struct shortname_table { unsigned int id; const char *s; } shortnames[] __devinitdata = { - { PCI_DEVICE_ID_INTEL_82801_6, "Intel 82801AA-ICH" }, - { PCI_DEVICE_ID_INTEL_82901_6, "Intel 82901AB-ICH0" }, + { PCI_DEVICE_ID_INTEL_82801AA_6, "Intel 82801AA-ICH" }, + { PCI_DEVICE_ID_INTEL_82801AB_6, "Intel 82901AB-ICH0" }, { PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" }, { PCI_DEVICE_ID_INTEL_440MX_6, "Intel 440MX" }, - { PCI_DEVICE_ID_INTEL_ICH3_6, "Intel 82801CA-ICH3" }, - { PCI_DEVICE_ID_INTEL_ICH4_6, "Intel 82801DB-ICH4" }, - { PCI_DEVICE_ID_INTEL_ICH5_6, "Intel ICH5" }, - { PCI_DEVICE_ID_INTEL_ICH6_6, "Intel ICH6" }, - { PCI_DEVICE_ID_INTEL_ICH7_6, "Intel ICH7" }, + { PCI_DEVICE_ID_INTEL_82801CA_6, "Intel 82801CA-ICH3" }, + { PCI_DEVICE_ID_INTEL_82801DB_6, "Intel 82801DB-ICH4" }, + { PCI_DEVICE_ID_INTEL_82801EB_6, "Intel ICH5" }, + { PCI_DEVICE_ID_INTEL_ICH6_17, "Intel ICH6" }, + { PCI_DEVICE_ID_INTEL_ICH7_19, "Intel ICH7" }, { 0x7446, "AMD AMD768" }, { PCI_DEVICE_ID_SI_7013, "SiS SI7013" }, - { PCI_DEVICE_ID_NVIDIA_MCP_MODEM, "NVidia nForce" }, + { PCI_DEVICE_ID_NVIDIA_MCP1_MODEM, "NVidia nForce" }, { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" }, { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" }, { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" }, @@ -1371,6 +1326,7 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Intel ICH Modem", + .owner = THIS_MODULE, .id_table = snd_intel8x0m_ids, .probe = snd_intel8x0m_probe, .remove = __devexit_p(snd_intel8x0m_remove), diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 79d8eda54f0d..5561fd4091e8 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -442,7 +442,7 @@ static char* stateName[] = { "Setup for play", "Playing", "Monitor mode on", - "Calibrating" + "Calibrating", "Invalid" }; @@ -2067,7 +2067,7 @@ static int snd_korg1212_control_sync_put(snd_kcontrol_t * kcontrol, snd_ctl_elem }, \ { \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \ - .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = c_name " Monitor Phase Invert", \ .info = snd_korg1212_control_phase_info, \ .get = snd_korg1212_control_phase_get, \ @@ -2082,7 +2082,7 @@ static snd_kcontrol_new_t snd_korg1212_controls[] = { MON_MIXER(4, "ADAT-5"), MON_MIXER(5, "ADAT-6"), MON_MIXER(6, "ADAT-7"), MON_MIXER(7, "ADAT-8"), { .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Sync Source", .info = snd_korg1212_control_sync_info, .get = snd_korg1212_control_sync_get, @@ -2220,7 +2220,7 @@ static int __devinit snd_korg1212_create(snd_card_t * card, struct pci_dev *pci, if ((err = pci_enable_device(pci)) < 0) return err; - korg1212 = kcalloc(1, sizeof(*korg1212), GFP_KERNEL); + korg1212 = kzalloc(sizeof(*korg1212), GFP_KERNEL); if (korg1212 == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -2534,6 +2534,7 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "korg1212", + .owner = THIS_MODULE, .id_table = snd_korg1212_ids, .probe = snd_korg1212_probe, .remove = __devexit_p(snd_korg1212_remove), diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 39b5e7db1543..2693b6f731f3 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -872,35 +872,6 @@ struct snd_m3 { /* * pci ids */ - -#ifndef PCI_VENDOR_ID_ESS -#define PCI_VENDOR_ID_ESS 0x125D -#endif -#ifndef PCI_DEVICE_ID_ESS_ALLEGRO_1 -#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988 -#endif -#ifndef PCI_DEVICE_ID_ESS_ALLEGRO -#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989 -#endif -#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2LE -#define PCI_DEVICE_ID_ESS_CANYON3D_2LE 0x1990 -#endif -#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2 -#define PCI_DEVICE_ID_ESS_CANYON3D_2 0x1992 -#endif -#ifndef PCI_DEVICE_ID_ESS_MAESTRO3 -#define PCI_DEVICE_ID_ESS_MAESTRO3 0x1998 -#endif -#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_1 -#define PCI_DEVICE_ID_ESS_MAESTRO3_1 0x1999 -#endif -#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_HW -#define PCI_DEVICE_ID_ESS_MAESTRO3_HW 0x199a -#endif -#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_2 -#define PCI_DEVICE_ID_ESS_MAESTRO3_2 0x199b -#endif - static struct pci_device_id snd_m3_ids[] = { {PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0}, @@ -2689,7 +2660,7 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, return -ENXIO; } - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -2890,6 +2861,7 @@ static void __devexit snd_m3_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Maestro3", + .owner = THIS_MODULE, .id_table = snd_m3_ids, .probe = snd_m3_probe, .remove = __devexit_p(snd_m3_remove), diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 6c868d913634..1a62c7f6c52b 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1004,7 +1004,7 @@ static int __devinit snd_mixart_create(mixart_mgr_t *mgr, snd_card_t *card, int .dev_free = snd_mixart_chip_dev_free, }; - mgr->chip[idx] = chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (! chip) { snd_printk(KERN_ERR "cannot allocate chip\n"); return -ENOMEM; @@ -1292,7 +1292,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, /* */ - mgr = kcalloc(1, sizeof(*mgr), GFP_KERNEL); + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); if (! mgr) { pci_disable_device(pci); return -ENOMEM; @@ -1424,6 +1424,7 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Digigram miXart", + .owner = THIS_MODULE, .id_table = snd_mixart_ids, .probe = snd_mixart_probe, .remove = __devexit_p(snd_mixart_remove), diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 7eb20b8f89f6..5c55a3b1d121 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -189,6 +189,7 @@ struct snd_nm256_stream { nm256_t *chip; snd_pcm_substream_t *substream; int running; + int suspended; u32 buf; /* offset from chip->buffer */ int bufsize; /* buffer size in bytes */ @@ -231,8 +232,10 @@ struct snd_nm256 { int mixer_status_mask; /* bit mask to test the mixer status */ int irq; + int irq_acks; irqreturn_t (*interrupt)(int, void *, struct pt_regs *); int badintrcount; /* counter to check bogus interrupts */ + struct semaphore irq_mutex; nm256_stream_t streams[2]; @@ -256,21 +259,6 @@ struct snd_nm256 { /* * PCI ids */ - -#ifndef PCI_VENDOR_ID_NEOMAGIC -#define PCI_VENDOR_ID_NEOMEGIC 0x10c8 -#endif -#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO -#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 -#endif -#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO -#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 -#endif -#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO -#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016 -#endif - - static struct pci_device_id snd_nm256_ids[] = { {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -464,6 +452,37 @@ snd_nm256_set_format(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *subs } } +/* acquire interrupt */ +static int snd_nm256_acquire_irq(nm256_t *chip) +{ + down(&chip->irq_mutex); + if (chip->irq < 0) { + if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, + chip->card->driver, (void*)chip)) { + snd_printk("unable to grab IRQ %d\n", chip->pci->irq); + up(&chip->irq_mutex); + return -EBUSY; + } + chip->irq = chip->pci->irq; + } + chip->irq_acks++; + up(&chip->irq_mutex); + return 0; +} + +/* release interrupt */ +static void snd_nm256_release_irq(nm256_t *chip) +{ + down(&chip->irq_mutex); + if (chip->irq_acks > 0) + chip->irq_acks--; + if (chip->irq_acks == 0 && chip->irq >= 0) { + free_irq(chip->irq, (void*)chip); + chip->irq = -1; + } + up(&chip->irq_mutex); +} + /* * start / stop */ @@ -538,15 +557,19 @@ snd_nm256_playback_trigger(snd_pcm_substream_t *substream, int cmd) spin_lock(&chip->reg_lock); switch (cmd) { - case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: + s->suspended = 0; + /* fallthru */ + case SNDRV_PCM_TRIGGER_START: if (! s->running) { snd_nm256_playback_start(chip, s, substream); s->running = 1; } break; - case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: + s->suspended = 1; + /* fallthru */ + case SNDRV_PCM_TRIGGER_STOP: if (s->running) { snd_nm256_playback_stop(chip); s->running = 0; @@ -802,7 +825,7 @@ static void snd_nm256_setup_stream(nm256_t *chip, nm256_stream_t *s, runtime->hw = *hw_ptr; runtime->hw.buffer_bytes_max = s->bufsize; runtime->hw.period_bytes_max = s->bufsize / 2; - runtime->dma_area = (void*) s->bufptr; + runtime->dma_area = (void __force *) s->bufptr; runtime->dma_addr = s->bufptr_addr; runtime->dma_bytes = s->bufsize; runtime->private_data = s; @@ -818,6 +841,8 @@ snd_nm256_playback_open(snd_pcm_substream_t *substream) { nm256_t *chip = snd_pcm_substream_chip(substream); + if (snd_nm256_acquire_irq(chip) < 0) + return -EBUSY; snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK], substream, &snd_nm256_playback); return 0; @@ -828,6 +853,8 @@ snd_nm256_capture_open(snd_pcm_substream_t *substream) { nm256_t *chip = snd_pcm_substream_chip(substream); + if (snd_nm256_acquire_irq(chip) < 0) + return -EBUSY; snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_CAPTURE], substream, &snd_nm256_capture); return 0; @@ -839,6 +866,9 @@ snd_nm256_capture_open(snd_pcm_substream_t *substream) static int snd_nm256_playback_close(snd_pcm_substream_t *substream) { + nm256_t *chip = snd_pcm_substream_chip(substream); + + snd_nm256_release_irq(chip); return 0; } @@ -846,6 +876,9 @@ snd_nm256_playback_close(snd_pcm_substream_t *substream) static int snd_nm256_capture_close(snd_pcm_substream_t *substream) { + nm256_t *chip = snd_pcm_substream_chip(substream); + + snd_nm256_release_irq(chip); return 0; } @@ -915,18 +948,16 @@ snd_nm256_pcm(nm256_t *chip, int device) static void snd_nm256_init_chip(nm256_t *chip) { - spin_lock_irq(&chip->reg_lock); /* Reset everything. */ snd_nm256_writeb(chip, 0x0, 0x11); snd_nm256_writew(chip, 0x214, 0); /* stop sounds.. */ //snd_nm256_playback_stop(chip); //snd_nm256_capture_stop(chip); - spin_unlock_irq(&chip->reg_lock); } -static inline void +static irqreturn_t snd_nm256_intr_check(nm256_t *chip) { if (chip->badintrcount++ > 1000) { @@ -947,7 +978,9 @@ snd_nm256_intr_check(nm256_t *chip) if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running) snd_nm256_capture_stop(chip); chip->badintrcount = 0; + return IRQ_HANDLED; } + return IRQ_NONE; } /* @@ -969,10 +1002,8 @@ snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy) status = snd_nm256_readw(chip, NM_INT_REG); /* Not ours. */ - if (status == 0) { - snd_nm256_intr_check(chip); - return IRQ_NONE; - } + if (status == 0) + return snd_nm256_intr_check(chip); chip->badintrcount = 0; @@ -1036,10 +1067,8 @@ snd_nm256_interrupt_zx(int irq, void *dev_id, struct pt_regs *dummy) status = snd_nm256_readl(chip, NM_INT_REG); /* Not ours. */ - if (status == 0) { - snd_nm256_intr_check(chip); - return IRQ_NONE; - } + if (status == 0) + return snd_nm256_intr_check(chip); chip->badintrcount = 0; @@ -1192,7 +1221,7 @@ snd_nm256_mixer(nm256_t *chip) AC97_PC_BEEP, AC97_PHONE, AC97_MIC, AC97_LINE, AC97_CD, AC97_VIDEO, AC97_AUX, AC97_PCM, AC97_REC_SEL, AC97_REC_GAIN, AC97_GENERAL_PURPOSE, AC97_3D_CONTROL, - AC97_EXTENDED_ID, + /*AC97_EXTENDED_ID,*/ AC97_VENDOR_ID1, AC97_VENDOR_ID2, -1 }; @@ -1206,6 +1235,7 @@ snd_nm256_mixer(nm256_t *chip) for (i = 0; mixer_regs[i] >= 0; i++) set_bit(mixer_regs[i], ac97.reg_accessed); ac97.private_data = chip; + pbus->no_vra = 1; err = snd_ac97_mixer(pbus, &ac97, &chip->ac97); if (err < 0) return err; @@ -1281,6 +1311,7 @@ static int nm256_suspend(snd_card_t *card, pm_message_t state) static int nm256_resume(snd_card_t *card) { nm256_t *chip = card->pm_private_data; + int i; /* Perform a full reset on the hardware */ pci_enable_device(chip->pci); @@ -1289,6 +1320,15 @@ static int nm256_resume(snd_card_t *card) /* restore ac97 */ snd_ac97_resume(chip->ac97); + for (i = 0; i < 2; i++) { + nm256_stream_t *s = &chip->streams[i]; + if (s->substream && s->suspended) { + spin_lock_irq(&chip->reg_lock); + snd_nm256_set_format(chip, s, s->substream); + spin_unlock_irq(&chip->reg_lock); + } + } + return 0; } #endif /* CONFIG_PM */ @@ -1349,7 +1389,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1360,6 +1400,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, chip->use_cache = usecache; spin_lock_init(&chip->reg_lock); chip->irq = -1; + init_MUTEX(&chip->irq_mutex); chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = play_bufsize; chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capt_bufsize; @@ -1470,15 +1511,6 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, chip->coeff_buf[SNDRV_PCM_STREAM_CAPTURE] = addr; } - /* acquire interrupt */ - if (request_irq(pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, - card->driver, (void*)chip)) { - err = -EBUSY; - snd_printk("unable to grab IRQ %d\n", pci->irq); - goto __error; - } - chip->irq = pci->irq; - /* Fixed setting. */ chip->mixer_base = NM_MIXER_OFFSET; @@ -1636,6 +1668,7 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "NeoMagic 256", + .owner = THIS_MODULE, .id_table = snd_nm256_ids, .probe = snd_nm256_probe, .remove = __devexit_p(snd_nm256_remove), diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index b7b554df6705..cd313af6ebcf 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -192,20 +192,6 @@ MODULE_SUPPORTED_DEVICE("{{RME,Digi32}," "{RME,Digi32/8}," "{RME,Digi32 PRO}}"); #define RME32_PRO_REVISION_WITH_8414 150 -/* PCI vendor/device ID's */ -#ifndef PCI_VENDOR_ID_XILINX_RME -# define PCI_VENDOR_ID_XILINX_RME 0xea60 -#endif -#ifndef PCI_DEVICE_ID_DIGI32 -# define PCI_DEVICE_ID_DIGI32 0x9896 -#endif -#ifndef PCI_DEVICE_ID_DIGI32_PRO -# define PCI_DEVICE_ID_DIGI32_PRO 0x9897 -#endif -#ifndef PCI_DEVICE_ID_DIGI32_8 -# define PCI_DEVICE_ID_DIGI32_8 0x9898 -#endif - typedef struct snd_rme32 { spinlock_t lock; int irq; @@ -242,11 +228,11 @@ typedef struct snd_rme32 { } rme32_t; static struct pci_device_id snd_rme32_ids[] = { - {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32, + {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, - {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_8, + {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, - {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_PRO, + {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, {0,} }; @@ -254,7 +240,7 @@ static struct pci_device_id snd_rme32_ids[] = { MODULE_DEVICE_TABLE(pci, snd_rme32_ids); #define RME32_ISWORKING(rme32) ((rme32)->wcreg & RME32_WCR_START) -#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414) +#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414) static int snd_rme32_playback_prepare(snd_pcm_substream_t * substream); @@ -541,21 +527,21 @@ static int snd_rme32_playback_setrate(rme32_t * rme32, int rate) RME32_WCR_FREQ_1; break; case 64000: - if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO) + if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO) return -EINVAL; rme32->wcreg |= RME32_WCR_DS_BM; rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) & ~RME32_WCR_FREQ_1; break; case 88200: - if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO) + if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO) return -EINVAL; rme32->wcreg |= RME32_WCR_DS_BM; rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_1) & ~RME32_WCR_FREQ_0; break; case 96000: - if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO) + if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO) return -EINVAL; rme32->wcreg |= RME32_WCR_DS_BM; rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) | @@ -692,7 +678,8 @@ snd_rme32_playback_hw_params(snd_pcm_substream_t * substream, if (err < 0) return err; } else { - runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER); + runtime->dma_area = (void __force *)(rme32->iobase + + RME32_IO_DATA_BUFFER); runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER; runtime->dma_bytes = RME32_BUFFER_SIZE; } @@ -746,7 +733,8 @@ snd_rme32_capture_hw_params(snd_pcm_substream_t * substream, if (err < 0) return err; } else { - runtime->dma_area = (void *)rme32->iobase + RME32_IO_DATA_BUFFER; + runtime->dma_area = (void __force *)rme32->iobase + + RME32_IO_DATA_BUFFER; runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER; runtime->dma_bytes = RME32_BUFFER_SIZE; } @@ -893,7 +881,7 @@ static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream) runtime->hw = snd_rme32_spdif_fd_info; else runtime->hw = snd_rme32_spdif_info; - if (rme32->pci->device == PCI_DEVICE_ID_DIGI32_PRO) { + if (rme32->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO) { runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; runtime->hw.rate_max = 96000; } @@ -1420,8 +1408,8 @@ static int __devinit snd_rme32_create(rme32_t * rme32) } /* set up ALSA pcm device for ADAT */ - if ((pci->device == PCI_DEVICE_ID_DIGI32) || - (pci->device == PCI_DEVICE_ID_DIGI32_PRO)) { + if ((pci->device == PCI_DEVICE_ID_RME_DIGI32) || + (pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO)) { /* ADAT is not available on DIGI32 and DIGI32 Pro */ rme32->adat_pcm = NULL; } @@ -1651,11 +1639,11 @@ snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32_8: uinfo->value.enumerated.items = 3; break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: uinfo->value.enumerated.items = 4; break; default: @@ -1682,11 +1670,11 @@ snd_rme32_get_inputtype_control(snd_kcontrol_t * kcontrol, ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32); switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32_8: items = 3; break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: items = 4; break; default: @@ -1709,11 +1697,11 @@ snd_rme32_put_inputtype_control(snd_kcontrol_t * kcontrol, int change, items = 3; switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32_8: items = 3; break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: items = 4; break; default: @@ -1900,7 +1888,7 @@ static snd_kcontrol_new_t snd_rme32_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), .info = snd_rme32_control_spdif_mask_info, .get = snd_rme32_control_spdif_mask_get, @@ -1908,7 +1896,7 @@ static snd_kcontrol_new_t snd_rme32_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), .info = snd_rme32_control_spdif_mask_info, .get = snd_rme32_control_spdif_mask_get, @@ -1994,13 +1982,13 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) strcpy(card->driver, "Digi32"); switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32: strcpy(card->shortname, "RME Digi32"); break; - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32_8: strcpy(card->shortname, "RME Digi32/8"); break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: strcpy(card->shortname, "RME Digi32 PRO"); break; } @@ -2024,6 +2012,7 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "RME Digi32", + .owner = THIS_MODULE, .id_table = snd_rme32_ids, .probe = snd_rme32_probe, .remove = __devexit_p(snd_rme32_remove), diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 10c4f45a913c..c495cae78dbf 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -200,25 +200,6 @@ MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard."); #define RME96_AD1852_VOL_BITS 14 #define RME96_AD1855_VOL_BITS 10 -/* - * PCI vendor/device ids, could in the future be defined in <linux/pci.h>, - * therefore #ifndef is used. - */ -#ifndef PCI_VENDOR_ID_XILINX -#define PCI_VENDOR_ID_XILINX 0x10ee -#endif -#ifndef PCI_DEVICE_ID_DIGI96 -#define PCI_DEVICE_ID_DIGI96 0x3fc0 -#endif -#ifndef PCI_DEVICE_ID_DIGI96_8 -#define PCI_DEVICE_ID_DIGI96_8 0x3fc1 -#endif -#ifndef PCI_DEVICE_ID_DIGI96_8_PRO -#define PCI_DEVICE_ID_DIGI96_8_PRO 0x3fc2 -#endif -#ifndef PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST -#define PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST 0x3fc3 -#endif typedef struct snd_rme96 { spinlock_t lock; @@ -252,13 +233,13 @@ typedef struct snd_rme96 { } rme96_t; static struct pci_device_id snd_rme96_ids[] = { - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PRO, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, { 0, } }; @@ -267,12 +248,12 @@ MODULE_DEVICE_TABLE(pci, snd_rme96_ids); #define RME96_ISPLAYING(rme96) ((rme96)->wcreg & RME96_WCR_START) #define RME96_ISRECORDING(rme96) ((rme96)->wcreg & RME96_WCR_START_2) -#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST) -#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO || \ - (rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST) +#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST) +#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO || \ + (rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST) #define RME96_DAC_IS_1852(rme96) (RME96_HAS_ANALOG_OUT(rme96) && (rme96)->rev >= 4) -#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \ - ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO && (rme96)->rev == 2)) +#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \ + ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO && (rme96)->rev == 2)) #define RME96_185X_MAX_OUT(rme96) ((1 << (RME96_DAC_IS_1852(rme96) ? RME96_AD1852_VOL_BITS : RME96_AD1855_VOL_BITS)) - 1) static int @@ -849,9 +830,9 @@ snd_rme96_setinputtype(rme96_t *rme96, RME96_WCR_INP_1; break; case RME96_INPUT_XLR: - if ((rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && - rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PRO) || - (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && + if ((rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && + rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PRO) || + (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4)) { /* Only Digi96/8 PRO and Digi96/8 PAD supports XLR */ @@ -985,7 +966,8 @@ snd_rme96_playback_hw_params(snd_pcm_substream_t *substream, snd_pcm_runtime_t *runtime = substream->runtime; int err, rate, dummy; - runtime->dma_area = (void *)(rme96->iobase + RME96_IO_PLAY_BUFFER); + runtime->dma_area = (void __force *)(rme96->iobase + + RME96_IO_PLAY_BUFFER); runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER; runtime->dma_bytes = RME96_BUFFER_SIZE; @@ -1037,7 +1019,8 @@ snd_rme96_capture_hw_params(snd_pcm_substream_t *substream, snd_pcm_runtime_t *runtime = substream->runtime; int err, isadat, rate; - runtime->dma_area = (void *)(rme96->iobase + RME96_IO_REC_BUFFER); + runtime->dma_area = (void __force *)(rme96->iobase + + RME96_IO_REC_BUFFER); runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER; runtime->dma_bytes = RME96_BUFFER_SIZE; @@ -1615,7 +1598,7 @@ snd_rme96_create(rme96_t *rme96) rme96->spdif_pcm->info_flags = 0; /* set up ALSA pcm device for ADAT */ - if (pci->device == PCI_DEVICE_ID_DIGI96) { + if (pci->device == PCI_DEVICE_ID_RME_DIGI96) { /* ADAT is not available on the base model */ rme96->adat_pcm = NULL; } else { @@ -1875,14 +1858,14 @@ snd_rme96_info_inputtype_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96_8: uinfo->value.enumerated.items = 3; break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: uinfo->value.enumerated.items = 4; break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: if (rme96->rev > 4) { /* PST */ uinfo->value.enumerated.items = 4; @@ -1912,14 +1895,14 @@ snd_rme96_get_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96); switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96_8: items = 3; break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: items = 4; break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: if (rme96->rev > 4) { /* for handling PST case, (INPUT_ANALOG is moved to INPUT_XLR */ if (ucontrol->value.enumerated.item[0] == RME96_INPUT_ANALOG) { @@ -1949,14 +1932,14 @@ snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t int change, items = 3; switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96_8: items = 3; break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: items = 4; break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: if (rme96->rev > 4) { items = 4; } else { @@ -1970,7 +1953,7 @@ snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t val = ucontrol->value.enumerated.item[0] % items; /* special case for PST */ - if (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && rme96->rev > 4) { + if (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4) { if (val == RME96_INPUT_XLR) { val = RME96_INPUT_ANALOG; } @@ -2266,7 +2249,7 @@ static snd_kcontrol_new_t snd_rme96_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_rme96_control_spdif_mask_info, .get = snd_rme96_control_spdif_mask_get, @@ -2276,7 +2259,7 @@ static snd_kcontrol_new_t snd_rme96_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), .info = snd_rme96_control_spdif_mask_info, .get = snd_rme96_control_spdif_mask_get, @@ -2392,16 +2375,16 @@ snd_rme96_probe(struct pci_dev *pci, strcpy(card->driver, "Digi96"); switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96: strcpy(card->shortname, "RME Digi96"); break; - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96_8: strcpy(card->shortname, "RME Digi96/8"); break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: strcpy(card->shortname, "RME Digi96/8 PRO"); break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: pci_read_config_byte(rme96->pci, 8, &val); if (val < 5) { strcpy(card->shortname, "RME Digi96/8 PAD"); @@ -2430,6 +2413,7 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "RME Digi96", + .owner = THIS_MODULE, .id_table = snd_rme96_ids, .probe = snd_rme96_probe, .remove = __devexit_p(snd_rme96_remove), diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 796621de5009..52525eb198c7 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -370,13 +370,6 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," #define UNITY_GAIN 32768 #define MINUS_INFINITY_GAIN 0 -#ifndef PCI_VENDOR_ID_XILINX -#define PCI_VENDOR_ID_XILINX 0x10ee -#endif -#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP -#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 -#endif - /* the size of a substream (1 mono data stream) */ #define HDSP_CHANNEL_BUFFER_SAMPLES (16*1024) @@ -1524,7 +1517,7 @@ static int snd_hdsp_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_el } #define HDSP_SPDIF_IN(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_spdif_in, \ @@ -1584,7 +1577,7 @@ static int snd_hdsp_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t } #define HDSP_SPDIF_OUT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_hdsp_info_spdif_bits, \ .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out } @@ -1638,7 +1631,7 @@ static int snd_hdsp_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ } #define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_hdsp_info_spdif_bits, \ .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional } @@ -1683,7 +1676,7 @@ static int snd_hdsp_put_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_el } #define HDSP_SPDIF_EMPHASIS(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_hdsp_info_spdif_bits, \ .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis } @@ -1728,7 +1721,7 @@ static int snd_hdsp_put_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_v } #define HDSP_SPDIF_NON_AUDIO(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_hdsp_info_spdif_bits, \ .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio } @@ -1773,7 +1766,7 @@ static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_v } #define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1834,7 +1827,7 @@ static int snd_hdsp_get_spdif_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_ele } #define HDSP_SYSTEM_SAMPLE_RATE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1858,7 +1851,7 @@ static int snd_hdsp_get_system_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_el } #define HDSP_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1918,7 +1911,7 @@ static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_ } #define HDSP_SYSTEM_CLOCK_MODE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1958,7 +1951,7 @@ static int snd_hdsp_get_system_clock_mode(snd_kcontrol_t * kcontrol, snd_ctl_ele } #define HDSP_CLOCK_SOURCE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_clock_source, \ @@ -2124,7 +2117,7 @@ static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_ele } #define HDSP_DA_GAIN(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_da_gain, \ @@ -2210,7 +2203,7 @@ static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t } #define HDSP_AD_GAIN(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_ad_gain, \ @@ -2296,7 +2289,7 @@ static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t } #define HDSP_PHONE_GAIN(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_phone_gain, \ @@ -2382,7 +2375,7 @@ static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value } #define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_xlr_breakout_cable, \ @@ -2447,7 +2440,7 @@ static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_el Switching this on desactivates external ADAT */ #define HDSP_AEB(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_aeb, \ @@ -2508,7 +2501,7 @@ static int snd_hdsp_put_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uc } #define HDSP_PREF_SYNC_REF(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_pref_sync_ref, \ @@ -2641,7 +2634,7 @@ static int snd_hdsp_put_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_va } #define HDSP_AUTOSYNC_REF(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -2697,7 +2690,7 @@ static int snd_hdsp_get_autosync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_val } #define HDSP_LINE_OUT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_line_out, \ @@ -2757,7 +2750,7 @@ static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t } #define HDSP_PRECISE_POINTER(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_precise_pointer, \ @@ -2811,7 +2804,7 @@ static int snd_hdsp_put_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_ } #define HDSP_USE_MIDI_TASKLET(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ .name = xname, \ .index = xindex, \ .info = snd_hdsp_info_use_midi_tasklet, \ @@ -2868,6 +2861,7 @@ static int snd_hdsp_put_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ .name = xname, \ .index = xindex, \ + .device = 0, \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ .info = snd_hdsp_info_mixer, \ @@ -2939,7 +2933,7 @@ static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * } #define HDSP_WC_SYNC_CHECK(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ @@ -2983,7 +2977,7 @@ static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_va } #define HDSP_SPDIF_SYNC_CHECK(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ @@ -3015,7 +3009,7 @@ static int snd_hdsp_get_spdif_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem } #define HDSP_ADATSYNC_SYNC_CHECK(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ @@ -3046,7 +3040,7 @@ static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_e } #define HDSP_ADAT_SYNC_CHECK \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ .info = snd_hdsp_info_sync_check, \ .get = snd_hdsp_get_adat_sync_check \ @@ -3119,7 +3113,7 @@ static snd_kcontrol_new_t snd_hdsp_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_hdsp_control_spdif_mask_info, .get = snd_hdsp_control_spdif_mask_get, @@ -3129,7 +3123,7 @@ static snd_kcontrol_new_t snd_hdsp_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), .info = snd_hdsp_control_spdif_mask_info, .get = snd_hdsp_control_spdif_mask_get, @@ -3146,8 +3140,6 @@ HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), /* 'Sample Clock Source' complies with the alsa control naming scheme */ HDSP_CLOCK_SOURCE("Sample Clock Source", 0), { - /* FIXME: should be PCM or MIXER? */ - /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Sample Clock Source Locking", .info = snd_hdsp_info_clock_source_lock, @@ -4900,6 +4892,7 @@ static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp) } if (!(hdsp->state & HDSP_InitializationComplete)) { + strcpy(card->shortname, "Hammerfall DSP"); sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name, hdsp->port, hdsp->irq); @@ -5223,6 +5216,7 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "RME Hammerfall DSP", + .owner = THIS_MODULE, .id_table = snd_hdsp_ids, .probe = snd_hdsp_probe, .remove = __devexit_p(snd_hdsp_remove), diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 9e86d0eb41ce..fc3f3283ff37 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -65,7 +65,7 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards."); module_param_array(precise_ptr, bool, NULL, 0444); -MODULE_PARM_DESC(precise_ptr, "Enable precise pointer, or disable."); +MODULE_PARM_DESC(precise_ptr, "Enable or disable precise pointer."); module_param_array(line_outs_monitor, bool, NULL, 0444); MODULE_PARM_DESC(line_outs_monitor, @@ -301,18 +301,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define UNITY_GAIN 32768 /* = 65536/2 */ #define MINUS_INFINITY_GAIN 0 -/* PCI info */ -#ifndef PCI_VENDOR_ID_XILINX -#define PCI_VENDOR_ID_XILINX 0x10ee -#endif -#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP -#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 -#endif -#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI -#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6 -#endif - - /* Number of channels for different Speed Modes */ #define MADI_SS_CHANNELS 64 #define MADI_DS_CHANNELS 32 @@ -1104,14 +1092,14 @@ static int snd_hdspm_midi_output_close(snd_rawmidi_substream_t * substream) return 0; } -snd_rawmidi_ops_t snd_hdspm_midi_output = +static snd_rawmidi_ops_t snd_hdspm_midi_output = { .open = snd_hdspm_midi_output_open, .close = snd_hdspm_midi_output_close, .trigger = snd_hdspm_midi_output_trigger, }; -snd_rawmidi_ops_t snd_hdspm_midi_input = +static snd_rawmidi_ops_t snd_hdspm_midi_input = { .open = snd_hdspm_midi_input_open, .close = snd_hdspm_midi_input_close, @@ -1168,7 +1156,7 @@ static void hdspm_midi_tasklet(unsigned long arg) /* get the system sample rate which is set */ #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1195,7 +1183,7 @@ static int snd_hdspm_get_system_sample_rate(snd_kcontrol_t * kcontrol, } #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1264,7 +1252,7 @@ static int snd_hdspm_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, } #define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1310,7 +1298,7 @@ static int snd_hdspm_get_system_clock_mode(snd_kcontrol_t * kcontrol, } #define HDSPM_CLOCK_SOURCE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_clock_source, \ @@ -1457,7 +1445,7 @@ static int snd_hdspm_put_clock_source(snd_kcontrol_t * kcontrol, } #define HDSPM_PREF_SYNC_REF(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_pref_sync_ref, \ @@ -1547,7 +1535,7 @@ static int snd_hdspm_put_pref_sync_ref(snd_kcontrol_t * kcontrol, } #define HDSPM_AUTOSYNC_REF(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ, \ @@ -1604,7 +1592,7 @@ static int snd_hdspm_get_autosync_ref(snd_kcontrol_t * kcontrol, } #define HDSPM_LINE_OUT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_line_out, \ @@ -1668,7 +1656,7 @@ static int snd_hdspm_put_line_out(snd_kcontrol_t * kcontrol, } #define HDSPM_TX_64(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_tx_64, \ @@ -1731,7 +1719,7 @@ static int snd_hdspm_put_tx_64(snd_kcontrol_t * kcontrol, } #define HDSPM_C_TMS(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_c_tms, \ @@ -1794,7 +1782,7 @@ static int snd_hdspm_put_c_tms(snd_kcontrol_t * kcontrol, } #define HDSPM_SAFE_MODE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_safe_mode, \ @@ -1857,7 +1845,7 @@ static int snd_hdspm_put_safe_mode(snd_kcontrol_t * kcontrol, } #define HDSPM_INPUT_SELECT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_input_select, \ @@ -1941,6 +1929,7 @@ static int snd_hdspm_put_input_select(snd_kcontrol_t * kcontrol, { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ .name = xname, \ .index = xindex, \ + .device = 0, \ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ .info = snd_hdspm_info_mixer, \ @@ -2124,7 +2113,7 @@ static int snd_hdspm_put_playback_mixer(snd_kcontrol_t * kcontrol, } #define HDSPM_WC_SYNC_CHECK(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ @@ -2170,7 +2159,7 @@ static int snd_hdspm_get_wc_sync_check(snd_kcontrol_t * kcontrol, #define HDSPM_MADI_SYNC_CHECK(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ @@ -3651,6 +3640,7 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "RME Hammerfall DSP MADI", + .owner = THIS_MODULE, .id_table = snd_hdspm_ids, .probe = snd_hdspm_probe, .remove = __devexit_p(snd_hdspm_remove), diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 1bc9d0df8516..b600f45e1834 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -120,13 +120,6 @@ MODULE_SUPPORTED_DEVICE("{{RME,Hammerfall}," #define RME9652_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME9652_buf_pos)) -#ifndef PCI_VENDOR_ID_XILINX -#define PCI_VENDOR_ID_XILINX 0x10ee -#endif -#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL -#define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4 -#endif - /* amount of io space we remap for register access. i'm not sure we even need this much, but 1K is nice round number :) */ @@ -893,7 +886,7 @@ static int snd_rme9652_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl } #define RME9652_ADAT1_IN(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_adat1_in, \ .get = snd_rme9652_get_adat1_in, \ .put = snd_rme9652_put_adat1_in } @@ -971,7 +964,7 @@ static int snd_rme9652_put_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu } #define RME9652_SPDIF_IN(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_spdif_in, \ .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in } @@ -1042,7 +1035,7 @@ static int snd_rme9652_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu } #define RME9652_SPDIF_OUT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_spdif_out, \ .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out } @@ -1110,7 +1103,7 @@ static int snd_rme9652_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_val } #define RME9652_SYNC_MODE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_sync_mode, \ .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode } @@ -1195,7 +1188,7 @@ static int snd_rme9652_put_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_val } #define RME9652_SYNC_PREF(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_sync_pref, \ .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref } @@ -1340,7 +1333,7 @@ static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t } #define RME9652_PASSTHRU(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_passthru, \ .put = snd_rme9652_put_passthru, \ .get = snd_rme9652_get_passthru } @@ -1386,7 +1379,7 @@ static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu /* Read-only switches */ #define RME9652_SPDIF_RATE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ .info = snd_rme9652_info_spdif_rate, \ .get = snd_rme9652_get_spdif_rate } @@ -1411,7 +1404,7 @@ static int snd_rme9652_get_spdif_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_va } #define RME9652_ADAT_SYNC(xname, xindex, xidx) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ .info = snd_rme9652_info_adat_sync, \ .get = snd_rme9652_get_adat_sync, .private_value = xidx } @@ -1447,7 +1440,7 @@ static int snd_rme9652_get_adat_sync(snd_kcontrol_t * kcontrol, snd_ctl_elem_val } #define RME9652_TC_VALID(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ .info = snd_rme9652_info_tc_valid, \ .get = snd_rme9652_get_tc_valid } @@ -1545,7 +1538,7 @@ static snd_kcontrol_new_t snd_rme9652_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_rme9652_control_spdif_mask_info, .get = snd_rme9652_control_spdif_mask_get, @@ -1555,7 +1548,7 @@ static snd_kcontrol_new_t snd_rme9652_controls[] = { }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), .info = snd_rme9652_control_spdif_mask_info, .get = snd_rme9652_control_spdif_mask_get, @@ -1568,7 +1561,7 @@ RME9652_SPDIF_OUT("IEC958 Output also on ADAT1", 0), RME9652_SYNC_MODE("Sync Mode", 0), RME9652_SYNC_PREF("Preferred Sync Source", 0), { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channels Thru", .index = 0, .info = snd_rme9652_info_thru, @@ -2661,6 +2654,7 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "RME Digi9652 (Hammerfall)", + .owner = THIS_MODULE, .id_table = snd_rme9652_ids, .probe = snd_rme9652_probe, .remove = __devexit_p(snd_rme9652_remove), diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 60ecb2bdb65e..1f6c2bfd43fd 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -50,13 +50,6 @@ MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}"); #define SUPPORT_JOYSTICK 1 #endif -#ifndef PCI_VENDOR_ID_S3 -#define PCI_VENDOR_ID_S3 0x5333 -#endif -#ifndef PCI_DEVICE_ID_S3_SONICVIBES -#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 -#endif - static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ @@ -1257,7 +1250,7 @@ static int __devinit snd_sonicvibes_create(snd_card_t * card, return -ENXIO; } - sonic = kcalloc(1, sizeof(*sonic), GFP_KERNEL); + sonic = kzalloc(sizeof(*sonic), GFP_KERNEL); if (sonic == NULL) { pci_disable_device(pci); return -ENOMEM; @@ -1515,6 +1508,7 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "S3 SonicVibes", + .owner = THIS_MODULE, .id_table = snd_sonic_ids, .probe = snd_sonic_probe, .remove = __devexit_p(snd_sonic_remove), diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index 940d531575c0..a8ca8e17853f 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -177,6 +177,7 @@ static void __devexit snd_trident_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Trident4DWaveAudio", + .owner = THIS_MODULE, .id_table = snd_trident_ids, .probe = snd_trident_probe, .remove = __devexit_p(snd_trident_remove), diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 29d89bfba0a4..777da9a7298b 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -1689,7 +1689,7 @@ static snd_pcm_hardware_t snd_trident_playback = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, @@ -1714,7 +1714,7 @@ static snd_pcm_hardware_t snd_trident_capture = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, @@ -1739,7 +1739,7 @@ static snd_pcm_hardware_t snd_trident_foldback = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, @@ -1763,7 +1763,7 @@ static snd_pcm_hardware_t snd_trident_spdif = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000), @@ -1784,7 +1784,7 @@ static snd_pcm_hardware_t snd_trident_spdif_7018 = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, @@ -2960,7 +2960,7 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device .read = snd_trident_codec_read, }; - uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL); + uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); if (!uctl) return -ENOMEM; @@ -3546,7 +3546,7 @@ int __devinit snd_trident_create(snd_card_t * card, return -ENXIO; } - trident = kcalloc(1, sizeof(*trident), GFP_KERNEL); + trident = kzalloc(sizeof(*trident), GFP_KERNEL); if (trident == NULL) { pci_disable_device(pci); return -ENOMEM; diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 4889600387c8..3c0205b91e10 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -104,14 +104,6 @@ module_param_array(dxs_support, int, NULL, 0444); MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)"); -/* pci ids */ -#ifndef PCI_DEVICE_ID_VIA_82C686_5 -#define PCI_DEVICE_ID_VIA_82C686_5 0x3058 -#endif -#ifndef PCI_DEVICE_ID_VIA_8233_5 -#define PCI_DEVICE_ID_VIA_8233_5 0x3059 -#endif - /* revision numbers for via686 */ #define VIA_REV_686_A 0x10 #define VIA_REV_686_B 0x11 @@ -663,10 +655,12 @@ static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd) val = 0; switch (cmd) { case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: val |= VIA_REG_CTRL_START; viadev->running = 1; break; case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: val = VIA_REG_CTRL_TERMINATE; viadev->running = 0; break; @@ -929,12 +923,12 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream) if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0) return rate_changed; - if (rate_changed) { + if (rate_changed) snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, chip->no_vra ? 48000 : runtime->rate); - snd_ac97_set_rate(chip->ac97, AC97_SPDIF, - chip->no_vra ? 48000 : runtime->rate); - } + if (chip->spdif_on && viadev->reg_offset == 0x30) + snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); + if (runtime->rate == 48000) rbits = 0xfffff; else @@ -1035,7 +1029,7 @@ static snd_pcm_hardware_t snd_via82xx_hw = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | + /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, @@ -1484,7 +1478,7 @@ static int snd_via8233_dxs3_spdif_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val } static snd_kcontrol_new_t snd_via8233_dxs3_spdif_control __devinitdata = { - .name = "IEC958 Output Switch", + .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .info = snd_via8233_dxs3_spdif_info, .get = snd_via8233_dxs3_spdif_get, @@ -1933,11 +1927,12 @@ static int snd_via82xx_chip_init(via82xx_t *chip) * DXS channels don't work properly with VRA if MC97 is disabled. */ struct pci_dev *pci; - pci = pci_find_device(0x1106, 0x3068, NULL); /* MC97 */ + pci = pci_get_device(0x1106, 0x3068, NULL); /* MC97 */ if (pci) { unsigned char data; pci_read_config_byte(pci, 0x44, &data); pci_write_config_byte(pci, 0x44, data | 0x40); + pci_dev_put(pci); } } @@ -2063,7 +2058,7 @@ static int __devinit snd_via82xx_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) { + if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) { pci_disable_device(pci); return -ENOMEM; } @@ -2152,10 +2147,13 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x1019, .subdevice = 0x0996, .action = VIA_DXS_48K }, { .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */ { .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */ + { .subvendor = 0x1019, .subdevice = 0xa101, .action = VIA_DXS_SRC }, { .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */ + { .subvendor = 0x1025, .subdevice = 0x0046, .action = VIA_DXS_SRC }, /* Acer Aspire 1524 WLMi */ { .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ { .subvendor = 0x1043, .subdevice = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ { .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ + { .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */ { .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */ { .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ { .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */ @@ -2168,10 +2166,12 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .subvendor = 0x1297, .subdevice = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */ { .subvendor = 0x1458, .subdevice = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */ { .subvendor = 0x1462, .subdevice = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */ + { .subvendor = 0x1462, .subdevice = 0x0430, .action = VIA_DXS_SRC }, /* MSI 7142 (K8MM-V) */ { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */ { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ + { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */ { .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */ { .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */ { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ @@ -2345,6 +2345,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "VIA 82xx Audio", + .owner = THIS_MODULE, .id_table = snd_via82xx_ids, .probe = snd_via82xx_probe, .remove = __devexit_p(snd_via82xx_remove), diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 4a9779cc9733..7eac6f6ac737 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -521,6 +521,7 @@ static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_SUSPEND: val |= VIA_REG_CTRL_START; viadev->running = 1; break; @@ -697,7 +698,7 @@ static snd_pcm_hardware_t snd_via82xx_hw = .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | + /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT, @@ -1082,7 +1083,7 @@ static int __devinit snd_via82xx_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) { + if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) { pci_disable_device(pci); return -ENOMEM; } @@ -1206,6 +1207,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "VIA 82xx Modem", + .owner = THIS_MODULE, .id_table = snd_via82xx_modem_ids, .probe = snd_via82xx_probe, .remove = __devexit_p(snd_via82xx_remove), diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index dca6bd2c7580..2a7ad9dec021 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c @@ -252,6 +252,7 @@ static void __devexit snd_vx222_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Digigram VX222", + .owner = THIS_MODULE, .id_table = snd_vx222_ids, .probe = snd_vx222_probe, .remove = __devexit_p(snd_vx222_remove), diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 5b5b624b47d0..2e69abe51aa9 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -352,6 +352,7 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci) static struct pci_driver driver = { .name = "Yamaha DS-XG PCI", + .owner = THIS_MODULE, .id_table = snd_ymfpci_ids, .probe = snd_card_ymfpci_probe, .remove = __devexit_p(snd_card_ymfpci_remove), diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index d54f88a1b525..27fa523639ae 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -321,6 +321,26 @@ static void snd_ymfpci_pcm_interrupt(ymfpci_t *chip, ymfpci_voice_t *voice) snd_pcm_period_elapsed(ypcm->substream); spin_lock(&chip->reg_lock); } + + if (unlikely(ypcm->update_pcm_vol)) { + unsigned int subs = ypcm->substream->number; + unsigned int next_bank = 1 - chip->active_bank; + snd_ymfpci_playback_bank_t *bank; + u32 volume; + + bank = &voice->bank[next_bank]; + volume = cpu_to_le32(chip->pcm_mixer[subs].left << 15); + bank->left_gain_end = volume; + if (ypcm->output_rear) + bank->eff2_gain_end = volume; + if (ypcm->voices[1]) + bank = &ypcm->voices[1]->bank[next_bank]; + volume = cpu_to_le32(chip->pcm_mixer[subs].right << 15); + bank->right_gain_end = volume; + if (ypcm->output_rear) + bank->eff3_gain_end = volume; + ypcm->update_pcm_vol--; + } } spin_unlock(&chip->reg_lock); } @@ -451,87 +471,74 @@ static int snd_ymfpci_pcm_voice_alloc(ymfpci_pcm_t *ypcm, int voices) return 0; } -static void snd_ymfpci_pcm_init_voice(ymfpci_voice_t *voice, int stereo, - int rate, int w_16, unsigned long addr, - unsigned int end, - int output_front, int output_rear) +static void snd_ymfpci_pcm_init_voice(ymfpci_pcm_t *ypcm, unsigned int voiceidx, + snd_pcm_runtime_t *runtime, + int has_pcm_volume) { + ymfpci_voice_t *voice = ypcm->voices[voiceidx]; u32 format; - u32 delta = snd_ymfpci_calc_delta(rate); - u32 lpfQ = snd_ymfpci_calc_lpfQ(rate); - u32 lpfK = snd_ymfpci_calc_lpfK(rate); + u32 delta = snd_ymfpci_calc_delta(runtime->rate); + u32 lpfQ = snd_ymfpci_calc_lpfQ(runtime->rate); + u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate); snd_ymfpci_playback_bank_t *bank; unsigned int nbank; + u32 vol_left, vol_right; + u8 use_left, use_right; snd_assert(voice != NULL, return); - format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000); + if (runtime->channels == 1) { + use_left = 1; + use_right = 1; + } else { + use_left = (voiceidx & 1) == 0; + use_right = !use_left; + } + if (has_pcm_volume) { + vol_left = cpu_to_le32(ypcm->chip->pcm_mixer + [ypcm->substream->number].left << 15); + vol_right = cpu_to_le32(ypcm->chip->pcm_mixer + [ypcm->substream->number].right << 15); + } else { + vol_left = cpu_to_le32(0x40000000); + vol_right = cpu_to_le32(0x40000000); + } + format = runtime->channels == 2 ? 0x00010000 : 0; + if (snd_pcm_format_width(runtime->format) == 8) + format |= 0x80000000; + if (runtime->channels == 2 && (voiceidx & 1) != 0) + format |= 1; for (nbank = 0; nbank < 2; nbank++) { bank = &voice->bank[nbank]; + memset(bank, 0, sizeof(*bank)); bank->format = cpu_to_le32(format); - bank->loop_default = 0; - bank->base = cpu_to_le32(addr); - bank->loop_start = 0; - bank->loop_end = cpu_to_le32(end); - bank->loop_frac = 0; - bank->eg_gain_end = cpu_to_le32(0x40000000); + bank->base = cpu_to_le32(runtime->dma_addr); + bank->loop_end = cpu_to_le32(ypcm->buffer_size); bank->lpfQ = cpu_to_le32(lpfQ); - bank->status = 0; - bank->num_of_frames = 0; - bank->loop_count = 0; - bank->start = 0; - bank->start_frac = 0; bank->delta = bank->delta_end = cpu_to_le32(delta); bank->lpfK = bank->lpfK_end = cpu_to_le32(lpfK); - bank->eg_gain = cpu_to_le32(0x40000000); - bank->lpfD1 = - bank->lpfD2 = 0; - - bank->left_gain = - bank->right_gain = - bank->left_gain_end = - bank->right_gain_end = - bank->eff1_gain = - bank->eff2_gain = - bank->eff3_gain = - bank->eff1_gain_end = - bank->eff2_gain_end = - bank->eff3_gain_end = 0; - - if (!stereo) { - if (output_front) { - bank->left_gain = + bank->eg_gain = + bank->eg_gain_end = cpu_to_le32(0x40000000); + + if (ypcm->output_front) { + if (use_left) { + bank->left_gain = + bank->left_gain_end = vol_left; + } + if (use_right) { bank->right_gain = - bank->left_gain_end = - bank->right_gain_end = cpu_to_le32(0x40000000); + bank->right_gain_end = vol_right; } - if (output_rear) { + } + if (ypcm->output_rear) { + if (use_left) { bank->eff2_gain = - bank->eff2_gain_end = - bank->eff3_gain = - bank->eff3_gain_end = cpu_to_le32(0x40000000); - } - } else { - if (output_front) { - if ((voice->number & 1) == 0) { - bank->left_gain = - bank->left_gain_end = cpu_to_le32(0x40000000); - } else { - bank->format |= cpu_to_le32(1); - bank->right_gain = - bank->right_gain_end = cpu_to_le32(0x40000000); - } + bank->eff2_gain_end = vol_left; } - if (output_rear) { - if ((voice->number & 1) == 0) { - bank->eff3_gain = - bank->eff3_gain_end = cpu_to_le32(0x40000000); - } else { - bank->format |= cpu_to_le32(1); - bank->eff2_gain = - bank->eff2_gain_end = cpu_to_le32(0x40000000); - } + if (use_right) { + bank->eff3_gain = + bank->eff3_gain_end = vol_right; } } } @@ -613,7 +620,7 @@ static int snd_ymfpci_playback_hw_free(snd_pcm_substream_t * substream) static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) { - // ymfpci_t *chip = snd_pcm_substream_chip(substream); + ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm = runtime->private_data; unsigned int nvoice; @@ -623,14 +630,8 @@ static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) ypcm->period_pos = 0; ypcm->last_pos = 0; for (nvoice = 0; nvoice < runtime->channels; nvoice++) - snd_ymfpci_pcm_init_voice(ypcm->voices[nvoice], - runtime->channels == 2, - runtime->rate, - snd_pcm_format_width(runtime->format) == 16, - runtime->dma_addr, - ypcm->buffer_size, - ypcm->output_front, - ypcm->output_rear); + snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, + substream->pcm == chip->pcm); return 0; } @@ -838,7 +839,7 @@ static int snd_ymfpci_playback_open_1(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; - ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL); + ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); if (ypcm == NULL) return -ENOMEM; ypcm->chip = chip; @@ -882,6 +883,7 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; + snd_kcontrol_t *kctl; int err; if ((err = snd_ymfpci_playback_open_1(substream)) < 0) @@ -895,6 +897,10 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) chip->rear_opened++; } spin_unlock_irq(&chip->reg_lock); + + kctl = chip->pcm_mixer[substream->number].ctl; + kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return 0; } @@ -951,7 +957,7 @@ static int snd_ymfpci_capture_open(snd_pcm_substream_t * substream, snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; - ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL); + ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); if (ypcm == NULL) return -ENOMEM; ypcm->chip = chip; @@ -987,6 +993,7 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) { ymfpci_t *chip = snd_pcm_substream_chip(substream); ymfpci_pcm_t *ypcm = substream->runtime->private_data; + snd_kcontrol_t *kctl; spin_lock_irq(&chip->reg_lock); if (ypcm->output_rear && chip->rear_opened > 0) { @@ -994,6 +1001,9 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) ymfpci_close_extension(chip); } spin_unlock_irq(&chip->reg_lock); + kctl = chip->pcm_mixer[substream->number].ctl; + kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return snd_ymfpci_playback_close_1(substream); } @@ -1665,6 +1675,66 @@ static snd_kcontrol_new_t snd_ymfpci_rear_shared __devinitdata = { .private_value = 2, }; +/* + * PCM voice volume + */ + +static int snd_ymfpci_pcm_vol_info(snd_kcontrol_t *kcontrol, + snd_ctl_elem_info_t *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0x8000; + return 0; +} + +static int snd_ymfpci_pcm_vol_get(snd_kcontrol_t *kcontrol, + snd_ctl_elem_value_t *ucontrol) +{ + ymfpci_t *chip = snd_kcontrol_chip(kcontrol); + unsigned int subs = kcontrol->id.subdevice; + + ucontrol->value.integer.value[0] = chip->pcm_mixer[subs].left; + ucontrol->value.integer.value[1] = chip->pcm_mixer[subs].right; + return 0; +} + +static int snd_ymfpci_pcm_vol_put(snd_kcontrol_t *kcontrol, + snd_ctl_elem_value_t *ucontrol) +{ + ymfpci_t *chip = snd_kcontrol_chip(kcontrol); + unsigned int subs = kcontrol->id.subdevice; + snd_pcm_substream_t *substream; + unsigned long flags; + + if (ucontrol->value.integer.value[0] != chip->pcm_mixer[subs].left || + ucontrol->value.integer.value[1] != chip->pcm_mixer[subs].right) { + chip->pcm_mixer[subs].left = ucontrol->value.integer.value[0]; + chip->pcm_mixer[subs].right = ucontrol->value.integer.value[1]; + + substream = (snd_pcm_substream_t *)kcontrol->private_value; + spin_lock_irqsave(&chip->voice_lock, flags); + if (substream->runtime && substream->runtime->private_data) { + ymfpci_pcm_t *ypcm = substream->runtime->private_data; + ypcm->update_pcm_vol = 2; + } + spin_unlock_irqrestore(&chip->voice_lock, flags); + return 1; + } + return 0; +} + +static snd_kcontrol_new_t snd_ymfpci_pcm_volume __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "PCM Playback Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_INACTIVE, + .info = snd_ymfpci_pcm_vol_info, + .get = snd_ymfpci_pcm_vol_get, + .put = snd_ymfpci_pcm_vol_put, +}; + /* * Mixer routines @@ -1686,6 +1756,7 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) { ac97_template_t ac97; snd_kcontrol_t *kctl; + snd_pcm_substream_t *substream; unsigned int idx; int err; static ac97_bus_ops_t ops = { @@ -1739,6 +1810,23 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) return err; } + /* per-voice volume */ + substream = chip->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + for (idx = 0; idx < 32; ++idx) { + kctl = snd_ctl_new1(&snd_ymfpci_pcm_volume, chip); + if (!kctl) + return -ENOMEM; + kctl->id.device = chip->pcm->device; + kctl->id.subdevice = idx; + kctl->private_value = (unsigned long)substream; + if ((err = snd_ctl_add(chip->card, kctl)) < 0) + return err; + chip->pcm_mixer[idx].left = 0x8000; + chip->pcm_mixer[idx].right = 0x8000; + chip->pcm_mixer[idx].ctl = kctl; + substream = substream->next; + } + return 0; } @@ -2182,7 +2270,7 @@ int __devinit snd_ymfpci_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; |