From b272cc769ac22014c0c60f2ebac46a2ae01300bf Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 27 Oct 2011 16:27:33 +0800 Subject: ASoC: wm8940: Fix mask for setting BCLKDIV According to the datasheet: BCLK is controlled by BIT[4:2] of WM8940_CLOCK(06h) register. Signed-off-by: Chris Paulson-Ellis Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/wm8940.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index dc5cb315085..de9ec9b8b7d 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -621,7 +621,7 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai, switch (div_id) { case WM8940_BCLKDIV: - reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFEF3; + reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3; ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2)); break; case WM8940_MCLKDIV: -- cgit v1.2.3-18-g5258 From b01a3d69f85c0af0934451e0f5457f2f6e7f3e63 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 27 Oct 2011 16:35:49 +0800 Subject: ASoC: tlv320aic23: Clear TLV320AIC23_MS_MASTER bit for slave mode According to the datasheet: Digital Audio Interface Format (07h) register: BIT6: Master/slave mode 0: Slave 1: Master Current code sets TLV320AIC23_MS_MASTER bit for master mode, but does not clear it for slave mode. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic23.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index ab27dbcd126..336de8f69a0 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -430,6 +430,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, iface_reg |= TLV320AIC23_MS_MASTER; break; case SND_SOC_DAIFMT_CBS_CFS: + iface_reg &= ~TLV320AIC23_MS_MASTER; break; default: return -EINVAL; -- cgit v1.2.3-18-g5258 From 68e47981437686e58de1edc616d6c3043e01f07e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 27 Oct 2011 16:38:42 +0800 Subject: ASoC: tlv320aic3x: Clear BIT_CLK_MASTER and WORD_CLK_MASTER bits for for slave mode According to the datasheet: Page0 / Register8: Audio Serial Data interface Control Register A BIT 7: Bit Clock Directional Control 0: Bit clock is an input (slave mode) 1: Bit clock is an output (master mode) BIT 6: Word Clock Directional Control 0: Word clock is an input (slave mode) 1: Word clock is an output (master mode) Current code sets BIT_CLK_MASTER and WORD_CLK_MASTER bits for master mode, but does not clear these bits for slave mode. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 7a49390bc30..87d5ef188e2 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1023,6 +1023,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, break; case SND_SOC_DAIFMT_CBS_CFS: aic3x->master = 0; + iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER); break; default: return -EINVAL; -- cgit v1.2.3-18-g5258 From f7b2bb8549e352353427d0f8913c96914dd0baab Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 28 Oct 2011 09:46:01 +0300 Subject: ALSA: hwdep: silence integer overflow warning Smatch complains that if device is INT_MAX then device + 1 can overflow. It just means we would have an annoying loop while we check all the devices from -2147483648 to SNDRV_MINOR_HWDEPS. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/core/hwdep.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index a70ee7f1ed9..031e215b6dd 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -272,7 +272,14 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)arg)) return -EFAULT; mutex_lock(®ister_mutex); - device = device < 0 ? 0 : device + 1; + + if (device < 0) + device = 0; + else if (device < SNDRV_MINOR_HWDEPS) + device++; + else + device = SNDRV_MINOR_HWDEPS; + while (device < SNDRV_MINOR_HWDEPS) { if (snd_hwdep_search(card, device)) break; -- cgit v1.2.3-18-g5258 From 9e6ff52088433e02426f860b0d40a5a0d4c8eb92 Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Thu, 27 Oct 2011 21:57:52 +0200 Subject: ALSA: hdspm - Fix MADI channel format in the status ioctl SNDRV_HDSPM_IOCTL_GET_STATUS is supposed to query the current card status, so we have to return what we receive on the MADI wire (RX), not what we transmit (TX) to others. The latter is a config item to be queried via SNDRV_HDSPM_IOCTL_GET_CONFIG. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 6e2f7ef7ddb..60a0b7de8e5 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -6253,7 +6253,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, status.card_specific.madi.madi_input = (statusregister & HDSPM_AB_int) ? 1 : 0; status.card_specific.madi.channel_format = - (statusregister & HDSPM_TX_64ch) ? 1 : 0; + (statusregister & HDSPM_RX_64ch) ? 1 : 0; /* TODO: Mac driver sets it when f_s>48kHz */ status.card_specific.madi.frame_format = 0; -- cgit v1.2.3-18-g5258 From a3466865681b7fe262a46c8f9d95126b38999d7f Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Thu, 27 Oct 2011 21:57:53 +0200 Subject: ALSA: hdsp - Correct HDSP_VERSION_BIT constant, thus partly fixing RPM detection HDSP_VERSION_BIT has to be ORed with HDSP_S_LOAD. This fixes the detection of at least some RME RPM boxes. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 1c6d1e1c27c..f7422029225 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -151,7 +151,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); #define HDSP_PROGRAM 0x020 #define HDSP_CONFIG_MODE_0 0x040 #define HDSP_CONFIG_MODE_1 0x080 -#define HDSP_VERSION_BIT 0x100 +#define HDSP_VERSION_BIT (0x100 | HDSP_S_LOAD) #define HDSP_BIGENDIAN_MODE 0x200 #define HDSP_RD_MULTIPLE 0x400 #define HDSP_9652_ENABLE_MIXER 0x800 -- cgit v1.2.3-18-g5258 From c09403dcc5698abf214329fbbf3cf8dbb5558bea Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Thu, 27 Oct 2011 21:57:54 +0200 Subject: ALSA: hdspm - Enable all firmware ranges for PCI MADI/AES cards From the Windows INF file, we know the firmware ranges for all RME cards. For PCIe, a single revision ID per device (RayDAT, MADI, AIO, AES) is used. Contrary, the older PCI versions use ranges, that is, one revision ID per firmware version. Instead of listing all possible revisions individually, match the range. This commit enables all MADI and AES PCI versions ever shipped. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 60a0b7de8e5..15a6c3b9bc9 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -520,16 +520,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) -/* revisions >= 230 indicate AES32 card */ -#define HDSPM_MADI_ANCIENT_REV 204 -#define HDSPM_MADI_OLD_REV 207 -#define HDSPM_MADI_REV 210 #define HDSPM_RAYDAT_REV 211 #define HDSPM_AIO_REV 212 #define HDSPM_MADIFACE_REV 213 -#define HDSPM_AES_REV 240 -#define HDSPM_AES32_REV 234 -#define HDSPM_AES32_OLD_REV 233 /* speed factor modes */ #define HDSPM_SPEED_SINGLE 0 @@ -6503,13 +6496,6 @@ static int __devinit snd_hdspm_create(struct snd_card *card, strcpy(card->driver, "HDSPM"); switch (hdspm->firmware_rev) { - case HDSPM_MADI_REV: - case HDSPM_MADI_OLD_REV: - case HDSPM_MADI_ANCIENT_REV: - hdspm->io_type = MADI; - hdspm->card_name = "RME MADI"; - hdspm->midiPorts = 3; - break; case HDSPM_RAYDAT_REV: hdspm->io_type = RayDAT; hdspm->card_name = "RME RayDAT"; @@ -6525,17 +6511,25 @@ static int __devinit snd_hdspm_create(struct snd_card *card, hdspm->card_name = "RME MADIface"; hdspm->midiPorts = 1; break; - case HDSPM_AES_REV: - case HDSPM_AES32_REV: - case HDSPM_AES32_OLD_REV: - hdspm->io_type = AES32; - hdspm->card_name = "RME AES32"; - hdspm->midiPorts = 2; - break; default: - snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n", + if ((hdspm->firmware_rev == 0xf0) || + ((hdspm->firmware_rev >= 0xe6) && + (hdspm->firmware_rev <= 0xea))) { + hdspm->io_type = AES32; + hdspm->card_name = "RME AES32"; + hdspm->midiPorts = 2; + } else if ((hdspm->firmware_rev == 0xd5) || + ((hdspm->firmware_rev >= 0xc8) && + (hdspm->firmware_rev <= 0xcf))) { + hdspm->io_type = MADI; + hdspm->card_name = "RME MADI"; + hdspm->midiPorts = 3; + } else { + snd_printk(KERN_ERR + "HDSPM: unknown firmware revision %x\n", hdspm->firmware_rev); - return -ENODEV; + return -ENODEV; + } } err = pci_enable_device(pci); -- cgit v1.2.3-18-g5258 From 228cf79376f13b98f2e1ac10586311312757675c Mon Sep 17 00:00:00 2001 From: Konstantin Ozerkov Date: Wed, 26 Oct 2011 19:11:01 +0400 Subject: ALSA: intel8x0: Improve performance in virtual environment v3: detection code is x86 and KVM specific, hide it under ifdef v2: add detection for virtual environments (KVM and Parallels) This patch is intended to improve performance in virtualized environments like Parallels Desktop or KVM/VirtualBox/QEMU (virtual ICH/AC97 audio). I/O access is very time-expensive operation in virtual world: VCPU can be rescheduled and in the worst case we get more than 10ms delay on each I/O access. In the virtual environment loop exit rule (old_civ == current_civ && old_picb == current_picb) is never satisfied, because old_picb is never the same as current_picb due to delay inspired by reading current_civ. As a result loop ended by timeout and we get 10x more I/O operations. Experimental data from Prallels Desktop 7, RHEL6 guest (I/O ops per second): Original code: In Port Counter Callback f014 41550 fffff00000179d00 ac97_bm_read_civ+0x000 f018 41387 fffff0000017a580 ac97_bm_read_picb+0x000 With patch: In Port Counter Callback f014 4090 fffff00000179d00 ac97_bm_read_civ+0x000 f018 1964 fffff0000017a580 ac97_bm_read_picb+0x000 Signed-off-by: Konstantin Ozerkov Signed-off-by: Denis V. Lunev Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 6a5b387b97f..6dc302c3eb9 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -42,6 +42,12 @@ #include #include +#ifdef CONFIG_KVM_GUEST +#include +#else +#define kvm_para_available() (0) +#endif + MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455"); MODULE_LICENSE("GPL"); @@ -77,6 +83,7 @@ static int buggy_semaphore; static int buggy_irq = -1; /* auto-check */ static int xbox; static int spdif_aclink = -1; +static int inside_vm = -1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); @@ -94,6 +101,8 @@ module_param(xbox, bool, 0444); MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); module_param(spdif_aclink, int, 0444); MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); +module_param(inside_vm, bool, 0444); +MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization."); /* just for backward compatibility */ static int enable; @@ -400,6 +409,7 @@ struct intel8x0 { 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 */ + unsigned inside_vm: 1; /* enable VM optimization */ int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ unsigned int sdm_saved; /* SDM reg value */ @@ -1065,8 +1075,11 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs udelay(10); continue; } - if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && - ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) + if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) + continue; + if (chip->inside_vm) + break; + if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) break; } while (timeout--); ptr = ichdev->last_pos; @@ -2984,6 +2997,10 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, if (xbox) chip->xbox = 1; + chip->inside_vm = inside_vm; + if (inside_vm) + printk(KERN_INFO "intel8x0: enable KVM optimization\n"); + if (pci->vendor == PCI_VENDOR_ID_INTEL && pci->device == PCI_DEVICE_ID_INTEL_440MX) chip->fix_nocache = 1; /* enable workaround */ @@ -3226,6 +3243,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, buggy_irq = 0; } + if (inside_vm < 0) { + /* detect KVM and Parallels virtual environments */ + inside_vm = kvm_para_available(); +#if defined(__i386__) || defined(__x86_64__) + inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); +#endif + } + if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) { snd_card_free(card); -- cgit v1.2.3-18-g5258 From 04c57163c8edfbc50e022737014069998ba4fc5f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 28 Oct 2011 11:08:01 +0800 Subject: ASoC: wm8711: Fix wrong mask for setting input audio data bit length select The Input Audio Data Bit Length Select is controlled by BIT[3:2] of WM8711_IFACE(07h) register. Current code incorrectly masks BIT[1:0] which is for Audio Data Format Select. Signed-off-by: Axel Lin Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8711.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 8d0347cf0e9..8ba49d867ac 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -151,7 +151,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); - u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; + u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3; int i = get_coeff(wm8711->sysclk, params_rate(params)); u16 srate = (coeff_div[i].sr << 2) | (coeff_div[i].bosr << 1) | coeff_div[i].usb; -- cgit v1.2.3-18-g5258 From d558cfc30064a97c2c65dbd2b3a4f5a1dea7ec1b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 28 Oct 2011 15:17:56 +0800 Subject: ASoC: Leave input audio data bit length settings untouched in wm8711_set_dai_fmt Current implementation in wm8711_set_dai_fmt always clear BIT[3:2] (the Input Audio Data Bit Length Select) of WM8711_IFACE(07h) register. Input Audio Data Bit Length Select bits are set by wm8711_hw_params, we should leave BIT[3:2] untouched in wm8711_set_dai_fmt. Signed-off-by: Axel Lin Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8711.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 8ba49d867ac..076bdb9930a 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -232,7 +232,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = 0; + u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c; /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -- cgit v1.2.3-18-g5258 From 5a7c5f26df3c0122814dfa1c13ef6dfbdbffdb86 Mon Sep 17 00:00:00 2001 From: Hong Xu Date: Fri, 28 Oct 2011 15:36:39 +0800 Subject: ASoC: WM8904: Set `invert' bit for Capture Switch Set `invert' bit for Capture Switch. Otherwise analogue is muted when Capture Switch is ON. Signed-off-by: Hong Xu Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8904.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 9fc8f4c0a9a..285ef87e670 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -867,7 +867,7 @@ SOC_ENUM("Right Capture Mode", rin_mode), SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0, WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0), SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, - WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0), + WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 1), SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), SOC_ENUM("High Pass Filter Mode", hpf_mode), -- cgit v1.2.3-18-g5258 From 64964e82644e9f809dc83019186c21ed5b70aa56 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 31 Oct 2011 19:02:13 +0000 Subject: ASoC: Fix return value of wm5100_gpio_direction_out() We can't just pass back the return value of snd_soc_update_bits() as it will be 1 if a bit changed rather than zero. Signed-off-by: Mark Brown --- sound/soc/codecs/wm5100.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 5d88c99aaea..42d9039a49e 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2361,13 +2361,17 @@ static int wm5100_gpio_direction_out(struct gpio_chip *chip, { struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); struct snd_soc_codec *codec = wm5100->codec; - int val; + int val, ret; val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT); - return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, - WM5100_GP1_FN_MASK | WM5100_GP1_DIR | - WM5100_GP1_LVL, val); + ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, + WM5100_GP1_FN_MASK | WM5100_GP1_DIR | + WM5100_GP1_LVL, val); + if (ret < 0) + return ret; + else + return 0; } static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset) -- cgit v1.2.3-18-g5258 From 359f90982cba0ba8db39b683de05dcb2de64b979 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 1 Nov 2011 09:40:07 +0100 Subject: ALSA: hda_hwdep: Fix possible buffer overflow If a line in the firmware file is larger than the given buffer size (and so the firmware file size), size is set to a value larger than the actual buffer size. This results in an overflow in the buffer passed. Signed-off-by: Alexander Stein Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_hwdep.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 72e5885007c..7e7d0788ddc 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -756,8 +756,6 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw) } if (!fw->size) return 0; - if (size < fw->size) - size = fw->size; for (len = 0; len < fw->size; len++) { if (!*p) -- cgit v1.2.3-18-g5258 From 700cc5c94fad6c3f15bacb0d99d9c474aed13c82 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 1 Nov 2011 10:40:50 +0100 Subject: ALSA: intel8x0 - Fix inclusion of kvm_para.h should be included instead of Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 6dc302c3eb9..45b2055f5a7 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -43,7 +43,7 @@ #include #ifdef CONFIG_KVM_GUEST -#include +#include #else #define kvm_para_available() (0) #endif -- cgit v1.2.3-18-g5258 From 4f4488abc97c1c27ff029f887944e6a6da1f5733 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 1 Nov 2011 13:36:10 +0000 Subject: ASoC: Ensure WM8962 PLL registers are reset The WM8962 has a separate software reset for the PLL registers. Ensure that these are reset also on startup. Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8962.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index f60dfa16545..32d931f1122 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -1961,7 +1961,13 @@ static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int re static int wm8962_reset(struct snd_soc_codec *codec) { - return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); + int ret; + + ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); + if (ret != 0) + return ret; + + return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0); } static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); -- cgit v1.2.3-18-g5258 From 2af8de8c39cf58e5a5e40a9d5d71332da98e6ba7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 1 Nov 2011 13:53:37 +0000 Subject: ASoC: Ensure the WM8962 oscillator and PLLs start up disabled Since there is no current software control for these they would otherwise be left enabled, consuming power. Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8962.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 32d931f1122..a0c895b2d53 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -4035,6 +4035,11 @@ static int wm8962_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_CLKREG_OVD, WM8962_CLKREG_OVD); + /* Ensure that the oscillator and PLLs are disabled */ + snd_soc_update_bits(codec, WM8962_PLL2, + WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, + 0); + regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); if (pdata) { -- cgit v1.2.3-18-g5258 From 0b7dd6ad92b6cace35dc5d06d6e236c2751c85dc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 1 Nov 2011 13:53:54 +0000 Subject: ASoC: Ensure we always delay for WM8962 FLL when starting from SYSCLK Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8962.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index a0c895b2d53..91d3c6dbeba 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2366,15 +2366,14 @@ static int sysclk_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, WM8962_FLL_ENA); - if (wm8962->irq) { - timeout = msecs_to_jiffies(5); - timeout = wait_for_completion_timeout(&wm8962->fll_lock, - timeout); - - if (timeout == 0) - dev_err(codec->dev, - "Timed out starting FLL\n"); - } + + timeout = msecs_to_jiffies(5); + timeout = wait_for_completion_timeout(&wm8962->fll_lock, + timeout); + + if (wm8962->irq && timeout == 0) + dev_err(codec->dev, + "Timed out starting FLL\n"); } break; -- cgit v1.2.3-18-g5258 From 08a1f5eb435640741c7b7d10fb339425dff786bb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Nov 2011 07:44:11 +0100 Subject: ALSA: hda - Check NO_PRESENCE pincfg default bit HD-audio spec defines a bit in pin default configuration for indicating that the pin isn't used for jack-detection although the codec is capable of it. Better to check this bit as well in jack_is_detectable() helper function. Reported-by: Raymond Yau Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_local.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 81e12c0ed0a..79f49e2e8cb 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -442,6 +442,8 @@ struct auto_pin_cfg { (cfg & AC_DEFCFG_SEQUENCE) #define get_defcfg_device(cfg) \ ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) +#define get_defcfg_misc(cfg) \ + ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) /* bit-flags for snd_hda_parse_pin_def_config() behavior */ #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ @@ -509,6 +511,8 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && + !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & + AC_DEFCFG_MISC_NO_PRESENCE)) && (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); } -- cgit v1.2.3-18-g5258 From 35c11777b906042eca9e6f1c03e464726c7faa07 Mon Sep 17 00:00:00 2001 From: Charles Chin Date: Wed, 2 Nov 2011 07:53:30 +0100 Subject: ALSA: hda - Disable power-widget control for IDT 92HD83/93 as default The power-widget control in patch_stac92hd83xxx() never worked properly, thus it's safer to turn it off as default for now. Signed-off-by: Charles Chin Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 59a52a430f2..e826ff75548 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5629,26 +5629,8 @@ again: stac92xx_set_config_regs(codec, stac92hd83xxx_brd_tbl[spec->board_config]); - switch (codec->vendor_id) { - case 0x111d76d1: - case 0x111d76d9: - case 0x111d76df: - case 0x111d76e5: - case 0x111d7666: - case 0x111d7667: - case 0x111d7668: - case 0x111d7669: - case 0x111d76e3: - case 0x111d7604: - case 0x111d76d4: - case 0x111d7605: - case 0x111d76d5: - case 0x111d76e7: - if (spec->board_config == STAC_92HD83XXX_PWR_REF) - break; + if (spec->board_config != STAC_92HD83XXX_PWR_REF) spec->num_pwrs = 0; - break; - } codec->patch_ops = stac92xx_patch_ops; -- cgit v1.2.3-18-g5258 From ad5d8755116b431f0709c745ee17cb567a478d43 Mon Sep 17 00:00:00 2001 From: Charles Chin Date: Wed, 2 Nov 2011 07:56:58 +0100 Subject: ALSA: hda - Add support for 92HD65 / 92HD66 family of codecs These codecs have SPDIF-in, which is new to the 92HD83xxx compatible families, so a bit of logic is added to support them. Signed-off-by: Charles Chin Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e826ff75548..5961e727b2c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5657,7 +5657,11 @@ again: } #endif - err = stac92xx_parse_auto_config(codec, 0x1d, 0); + /* 92HD65/66 series has S/PDIF-IN */ + if (codec->vendor_id >= 0x111d76e8 && codec->vendor_id <= 0x111d76f3) + err = stac92xx_parse_auto_config(codec, 0x1d, 0x22); + else + err = stac92xx_parse_auto_config(codec, 0x1d, 0); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6547,6 +6551,18 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx}, + { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx}, {} /* terminator */ }; -- cgit v1.2.3-18-g5258 From 1fa1757366783fb52e6e85c2d735db49b818d382 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Nov 2011 21:30:51 +0100 Subject: ALSA: hda/realtek - Don't create alt-stream for capture when unnecessary When the driver finds multiple ADCs, it tries to create an alternative capture PCM stream. However, these secondary ADCs might be useless or in uncontrolled paths in some cases, e.g. when auto-mic or dynamic ADC-switching is enabled. Also, when only a single capture source is available, the multi-streams don't make sense, too. With this patch, the driver checks such condition and skips the alt stream appropriately. Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8f93b97559a..4468cb7ea68 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2270,6 +2270,7 @@ static int alc_build_pcms(struct hda_codec *codec) struct alc_spec *spec = codec->spec; struct hda_pcm *info = spec->pcm_rec; const struct hda_pcm_stream *p; + bool have_multi_adcs; int i; codec->num_pcms = 1; @@ -2348,8 +2349,11 @@ static int alc_build_pcms(struct hda_codec *codec) /* If the use of more than one ADC is requested for the current * model, configure a second analog capture-only PCM. */ + have_multi_adcs = (spec->num_adc_nids > 1) && + !spec->dyn_adc_switch && !spec->auto_mic && + (!spec->input_mux || spec->input_mux->num_items > 1); /* Additional Analaog capture for index #2 */ - if (spec->alt_dac_nid || spec->num_adc_nids > 1) { + if (spec->alt_dac_nid || have_multi_adcs) { codec->num_pcms = 3; info = spec->pcm_rec + 2; info->name = spec->stream_name_analog; @@ -2365,7 +2369,7 @@ static int alc_build_pcms(struct hda_codec *codec) alc_pcm_null_stream; info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; } - if (spec->num_adc_nids > 1) { + if (have_multi_adcs) { p = spec->stream_analog_alt_capture; if (!p) p = &alc_pcm_analog_alt_capture; -- cgit v1.2.3-18-g5258 From 112daa7a4c09059ae93e1a3de42e874c13a30728 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Nov 2011 21:40:06 +0100 Subject: ALSA: hda - Remove unused variables Just clean-up what GCC caught. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 5 +---- sound/pci/hda/patch_realtek.c | 3 --- sound/pci/hda/patch_via.c | 5 ----- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 342540128fb..aac3bfacda3 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1006,7 +1006,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) unsigned int caps, config; int pin_idx; struct hdmi_spec_per_pin *per_pin; - struct hdmi_eld *eld; int err; caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP); @@ -1023,7 +1022,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) pin_idx = spec->num_pins; per_pin = &spec->pins[pin_idx]; - eld = &per_pin->sink_eld; per_pin->pin_nid = pin_nid; @@ -1576,7 +1574,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { int chs; - unsigned int dataDCC1, dataDCC2, channel_id; + unsigned int dataDCC2, channel_id; int i; struct hdmi_spec *spec = codec->spec; struct hda_spdif_out *spdif = @@ -1586,7 +1584,6 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, chs = substream->runtime->channels; - dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; dataDCC2 = 0x2; /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4468cb7ea68..9543bc8aaef 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2661,7 +2661,6 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) hda_nid_t *adc_nids = spec->private_adc_nids; hda_nid_t *cap_nids = spec->private_capsrc_nids; int max_nums = ARRAY_SIZE(spec->private_adc_nids); - bool indep_capsrc = false; int i, nums = 0; nid = codec->start_nid; @@ -2683,13 +2682,11 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) break; if (type == AC_WID_AUD_SEL) { cap_nids[nums] = src; - indep_capsrc = true; break; } n = snd_hda_get_conn_list(codec, src, &list); if (n > 1) { cap_nids[nums] = src; - indep_capsrc = true; break; } else if (n != 1) break; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 417d62ad3b9..0b020a93a8e 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -3700,13 +3700,8 @@ static const struct hda_verb vt1812_init_verbs[] = { static void set_widgets_power_state_vt1812(struct hda_codec *codec) { struct via_spec *spec = codec->spec; - int imux_is_smixer = - snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; unsigned int parm; unsigned int present; - /* MUX10 (1eh) = stereo mixer */ - imux_is_smixer = - snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; /* inputs */ /* PW 5/6/7 (29h/2ah/2bh) */ parm = AC_PWRST_D3; -- cgit v1.2.3-18-g5258 From 9009b0e41c1e81e1a30acdb5d4ffbb6dc5e1345f Mon Sep 17 00:00:00 2001 From: Charles Chin Date: Thu, 3 Nov 2011 10:27:27 +0100 Subject: ALSA: hda/sigmatel - Automatically retrieve digital I/O widgets Revise stac92xx_parse_auto_config to automatically scan for digital input and output converters. Signed-off-by: Charles Chin Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 5961e727b2c..de4c36027cb 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3791,9 +3791,10 @@ static int is_dual_headphones(struct hda_codec *codec) } -static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) +static int stac92xx_parse_auto_config(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; + hda_nid_t dig_out = 0, dig_in = 0; int hp_swap = 0; int i, err; @@ -3976,6 +3977,22 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (spec->multiout.max_channels > 2) spec->surr_switch = 1; + /* find digital out and in converters */ + for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) { + unsigned int wid_caps = get_wcaps(codec, i); + if (wid_caps & AC_WCAP_DIGITAL) { + switch (get_wcaps_type(wid_caps)) { + case AC_WID_AUD_OUT: + if (!dig_out) + dig_out = i; + break; + case AC_WID_AUD_IN: + if (!dig_in) + dig_in = i; + break; + } + } + } if (spec->autocfg.dig_outs) spec->multiout.dig_out_nid = dig_out; if (dig_in && spec->autocfg.dig_in_pin) @@ -5279,7 +5296,7 @@ static int patch_stac925x(struct hda_codec *codec) spec->capvols = stac925x_capvols; spec->capsws = stac925x_capsws; - err = stac92xx_parse_auto_config(codec, 0x8, 0x7); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -5420,7 +5437,7 @@ again: spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); spec->pwr_nids = stac92hd73xx_pwr_nids; - err = stac92xx_parse_auto_config(codec, 0x25, 0x27); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { @@ -5657,11 +5674,7 @@ again: } #endif - /* 92HD65/66 series has S/PDIF-IN */ - if (codec->vendor_id >= 0x111d76e8 && codec->vendor_id <= 0x111d76f3) - err = stac92xx_parse_auto_config(codec, 0x1d, 0x22); - else - err = stac92xx_parse_auto_config(codec, 0x1d, 0); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -5982,7 +5995,7 @@ again: spec->multiout.dac_nids = spec->dac_nids; - err = stac92xx_parse_auto_config(codec, 0x21, 0); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6091,7 +6104,7 @@ static int patch_stac922x(struct hda_codec *codec) spec->multiout.dac_nids = spec->dac_nids; - err = stac92xx_parse_auto_config(codec, 0x08, 0x09); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6216,7 +6229,7 @@ static int patch_stac927x(struct hda_codec *codec) spec->aloopback_shift = 0; spec->eapd_switch = 1; - err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6341,7 +6354,7 @@ static int patch_stac9205(struct hda_codec *codec) break; } - err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); + err = stac92xx_parse_auto_config(codec); if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " @@ -6446,7 +6459,7 @@ static int patch_stac9872(struct hda_codec *codec) spec->capvols = stac9872_capvols; spec->capsws = stac9872_capsws; - err = stac92xx_parse_auto_config(codec, 0x10, 0x12); + err = stac92xx_parse_auto_config(codec); if (err < 0) { stac92xx_free(codec); return -EINVAL; -- cgit v1.2.3-18-g5258 From 51e4152a969aa6d2306492ebf143932dcb535c9b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 3 Nov 2011 16:54:06 +0100 Subject: ALSA: hda/realtek - Skip invalid digital out pins Some BIOS report invalid pins as digital output pins. The driver checks the connection but it doesn't do it fully correctly, and it leaves some undefined value as the audio-out widget, which makes the driver spewing warnings. This patch fixes the issue. Reference: https://bugzilla.novell.com/show_bug.cgi?id=727348 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9543bc8aaef..80d6add8a62 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1604,27 +1604,29 @@ static void alc_auto_init_digital(struct hda_codec *codec) static void alc_auto_parse_digital(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - int i, err; + int i, err, nums; hda_nid_t dig_nid; /* support multiple SPDIFs; the secondary is set up as a slave */ + nums = 0; for (i = 0; i < spec->autocfg.dig_outs; i++) { hda_nid_t conn[4]; err = snd_hda_get_connections(codec, spec->autocfg.dig_out_pins[i], conn, ARRAY_SIZE(conn)); - if (err < 0) + if (err <= 0) continue; dig_nid = conn[0]; /* assume the first element is audio-out */ - if (!i) { + if (!nums) { spec->multiout.dig_out_nid = dig_nid; spec->dig_out_type = spec->autocfg.dig_out_type[0]; } else { spec->multiout.slave_dig_outs = spec->slave_dig_outs; - if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) + if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) break; - spec->slave_dig_outs[i - 1] = dig_nid; + spec->slave_dig_outs[nums - 1] = dig_nid; } + nums++; } if (spec->autocfg.dig_in_pin) { -- cgit v1.2.3-18-g5258