From e15c1c1f3f903f679c9782b540f9d52c80c99610 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 28 Nov 2009 18:12:06 +0100 Subject: pcmcia: remove unused IRQ_FIRST_SHARED Komuro pointed out that IRQ_FIRST_SHARED is not used at all in the PCMCIA subsystem, so remove it. Also, remove two bogus assignments. CC: Karsten Keil CC: netdev@vger.kernel.org CC: alsa-devel@alsa-project.org CC: Komuro Signed-off-by: Dominik Brodowski --- sound/pcmcia/pdaudiocf/pdaudiocf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 7717e01fc071..edaa729126bb 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -143,7 +143,8 @@ static int snd_pdacf_probe(struct pcmcia_device *link) link->io.NumPorts1 = 16; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; - // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; + /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */ + /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; */ link->irq.Handler = pdacf_interrupt; link->conf.Attributes = CONF_ENABLE_IRQ; -- cgit From 5a65edbc12b6b34ef912114f1fc8215786f85b25 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 4 Nov 2009 16:10:51 +0000 Subject: mfd: Convert wm8350 IRQ handlers to irq_handler_t This is done as simple code transformation, the semantics of the IRQ API provided by the core are are still very different to those of genirq (mainly with regard to masking). Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- sound/soc/codecs/wm8350.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index f82125d9e85a..17a327d67fd5 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1340,9 +1340,10 @@ static int wm8350_resume(struct platform_device *pdev) return 0; } -static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data) +static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) { struct wm8350_data *priv = data; + struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report; int mask; @@ -1365,7 +1366,7 @@ static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data) if (!jack->jack) { dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); - return; + return IRQ_NONE; } /* Debounce */ @@ -1378,6 +1379,8 @@ static void wm8350_hp_jack_handler(struct wm8350 *wm8350, int irq, void *data) report = 0; snd_soc_jack_report(jack->jack, report, jack->report); + + return IRQ_HANDLED; } /** @@ -1421,7 +1424,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); /* Sync status */ - wm8350_hp_jack_handler(wm8350, irq, priv); + wm8350_hp_jack_handler(irq, priv); wm8350_unmask_irq(wm8350, irq); @@ -1485,9 +1488,11 @@ static int wm8350_probe(struct platform_device *pdev) wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, - wm8350_hp_jack_handler, priv); + wm8350_hp_jack_handler, 0, "Left jack detect", + priv); wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, - wm8350_hp_jack_handler, priv); + wm8350_hp_jack_handler, 0, "Right jack detect", + priv); ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { -- cgit From 6a6127462eb9096419fd4b3115ec5971d83a600f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 4 Nov 2009 16:10:52 +0000 Subject: mfd: Mask and unmask wm8350 IRQs on request and free Bring the WM8350 IRQ API more in line with the generic IRQ API by masking and unmasking interrupts as they are requested and freed. This is mostly just a case of deleting the mask and unmask calls from the individual drivers. The RTC driver is changed to mask the periodic IRQ after requesting it rather than only unmasking the alarm IRQ. If the periodic IRQ fires in the period where it is reqested then there will be a spurious notification but there should be no serious consequences from this. The CODEC drive is changed to explicitly disable headphone jack detection prior to requesting the IRQs. This will avoid the IRQ firing with no jack set up. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- sound/soc/codecs/wm8350.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 17a327d67fd5..ebbf11b653a4 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1426,8 +1426,6 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, /* Sync status */ wm8350_hp_jack_handler(irq, priv); - wm8350_unmask_irq(wm8350, irq); - return 0; } EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); @@ -1485,8 +1483,10 @@ static int wm8350_probe(struct platform_device *pdev) wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, WM8350_OUT2_VU | WM8350_OUT2R_MUTE); - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); + /* Make sure jack detect is disabled to start off with */ + wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, + WM8350_JDL_ENA | WM8350_JDR_ENA); + wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, wm8350_hp_jack_handler, 0, "Left jack detect", priv); @@ -1521,8 +1521,6 @@ static int wm8350_remove(struct platform_device *pdev) WM8350_JDL_ENA | WM8350_JDR_ENA); wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); - wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); -- cgit From b07682b6056eb6701f8cb86aa5800e6f2ea7919b Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Sun, 13 Dec 2009 20:05:51 +0100 Subject: mfd: Rename twl4030* driver files to enable re-use The upcoming TWL6030 is companion chip for OMAP4 like the current TWL4030 for OMAP3. The common modules like RTC, Regulator creates opportunity to re-use the most of the code from twl4030. This patch renames few common drivers twl4030* files to twl* to enable the code re-use. Signed-off-by: Rajendra Nayak Signed-off-by: Balaji T K Signed-off-by: Santosh Shilimkar Acked-by: Kevin Hilman Signed-off-by: Samuel Ortiz --- sound/soc/codecs/twl4030.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 5f1681f6ca76..c3a6ceb542cb 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include -- cgit From fc7b92fca4e546184557f1c53f84ad57c66b7695 Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Sun, 13 Dec 2009 21:23:33 +0100 Subject: mfd: Rename all twl4030_i2c* This patch renames function names like twl4030_i2c_write_u8, twl4030_i2c_read_u8 to twl_i2c_write_u8, twl_i2c_read_u8 and also common variable in twl-core.c Signed-off-by: Rajendra Nayak Signed-off-by: Balaji T K Signed-off-by: Santosh Shilimkar Acked-by: Kevin Hilman Signed-off-by: Samuel Ortiz --- sound/soc/codecs/twl4030.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index c3a6ceb542cb..2a27f7b56726 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -175,7 +175,7 @@ static int twl4030_write(struct snd_soc_codec *codec, { twl4030_write_reg_cache(codec, reg, value); if (likely(reg < TWL4030_REG_SW_SHADOW)) - return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, + return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); else return 0; @@ -261,7 +261,7 @@ static void twl4030_power_up(struct snd_soc_codec *codec) do { /* this takes a little while, so don't slam i2c */ udelay(2000); - twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, TWL4030_REG_ANAMICL); } while ((i++ < 100) && ((byte & TWL4030_CNCL_OFFSET_START) == @@ -542,7 +542,7 @@ static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ break; \ case SND_SOC_DAPM_POST_PMD: \ reg_val = twl4030_read_reg_cache(w->codec, reg); \ - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ reg_val & (~mask), \ reg); \ break; \ @@ -679,7 +679,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / twl4030->sysclk) + 1); /* Bypass the reg_cache to mute the headset */ - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), TWL4030_REG_HS_GAIN_SET); -- cgit From 950200e2ff11daae1c5d9426703bdd494603f38b Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 13 Dec 2009 14:11:02 -0500 Subject: ALSA: hda: Use ALC260_WILL quirk for another Acer model (0x1025007f) BugLink: https://bugs.launchpad.net/bugs/418627 The original reporter states that this quirk is necessary to obtain reasonable gain for playback. Without it, sound is inaudible. Tested with playback (spkr and hp) and capture. Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index deecdd2d5d37..c9e860709747 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6248,6 +6248,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), + SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), -- cgit From 01f5966d2f36f08eb6604665eade69c9f38ffaed Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 13 Dec 2009 16:22:58 -0500 Subject: ALSA: hda: Fix max PCM level to 0 dB for AD1981_HP BugLink: https://bugs.launchpad.net/bugs/461062 The original reporter states that PCM maxes at +12 dB and results in very bad distortion. Cap PCM at 0 dB to resolve this symptom. Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 447eda1f6770..1a36137e13ec 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1789,6 +1789,14 @@ static int patch_ad1981(struct hda_codec *codec) codec->patch_ops.init = ad1981_hp_init; codec->patch_ops.unsol_event = ad1981_hp_unsol_event; + /* set the upper-limit for mixer amp to 0dB for avoiding the + * possible damage by overloading + */ + snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, + (0x17 << AC_AMPCAP_OFFSET_SHIFT) | + (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (1 << AC_AMPCAP_MUTE_SHIFT)); break; case AD1981_THINKPAD: spec->mixers[0] = ad1981_thinkpad_mixers; -- cgit From 0d64b568fcd48b133721c1d322e7c51d85eb12df Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 12:42:56 +0100 Subject: ALSA: sound/isa/gus: Correct code taking the size of a pointer sizeof(share_id) is just the size of the pointer. On the other hand, block->share_id is an array, so its size seems more appropriate. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai --- sound/isa/gus/gus_mem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c index 661205c4dcea..af888a022fc0 100644 --- a/sound/isa/gus/gus_mem.c +++ b/sound/isa/gus/gus_mem.c @@ -127,7 +127,8 @@ static struct snd_gf1_mem_block *snd_gf1_mem_share(struct snd_gf1_mem * alloc, !share_id[2] && !share_id[3]) return NULL; for (block = alloc->first; block; block = block->next) - if (!memcmp(share_id, block->share_id, sizeof(share_id))) + if (!memcmp(share_id, block->share_id, + sizeof(block->share_id))) return block; return NULL; } -- cgit From 6dd7dc767e35cfbb38f8c63a50b1c27acad25920 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 14 Dec 2009 11:27:11 +0100 Subject: ALSA: hda - Add PCI IDs for Nvidia G2xx-series Signed-off-by: Stefan Ringel Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e54420e691ae..9b56f937913e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2713,6 +2713,9 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA }, -- cgit From bc2580061e42c323d7777029f01318f395edac0d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Dec 2009 12:43:15 +0100 Subject: ASoC: Correct code taking the size of a pointer sizeof(codec->reg_cache) is just the size of the pointer. Elsewhere in the file, codec->reg_cache is used with sizeof(wm8900_reg_defaults), so the code is changed to do the same here. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression *x; expression f; type T; @@ *f(...,(T)x,...) // Signed-off-by: Julia Lawall Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8900.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index c9438dd62df3..dbc368c08263 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -199,7 +199,7 @@ static void wm8900_reset(struct snd_soc_codec *codec) snd_soc_write(codec, WM8900_REG_RESET, 0); memcpy(codec->reg_cache, wm8900_reg_defaults, - sizeof(codec->reg_cache)); + sizeof(wm8900_reg_defaults)); } static int wm8900_hp_event(struct snd_soc_dapm_widget *w, -- cgit From f74890277a196949e4004fe2955e1d4fb3930f98 Mon Sep 17 00:00:00 2001 From: Steve Soule Date: Mon, 14 Dec 2009 11:06:03 -0700 Subject: ALSA: ac97_codec - increase timeout for analog sections to 5 second I have a Soundblaster 16PCI. For many years, alsa has had a bug where not all of the card's controls are detected (many alsa versions, many kernel versions). In particular, Master Playback Volume is usually not detected, and so I get no sound or extremely faint sound. The problem has always been inconsistent: sometimes all of the controls are detected correctly, and sometimes a partial set is detected. It works correctly about 10% of the time. Finally, I got around to tracking down the problem. When the driver fails, it prints the kernel message "AC'97 0 analog subsections not ready". This message is generated from the function snd_ac97_mixer() in ac97_codec.c. The message indicates that the card failed to come back after reset within the time limit. The time limit is 120 milliseconds. I tried increasing the time limit to 1 second, and found that this made the driver work about 70% of the time. I tried increasing it to 5 seconds, and it now seems to work 100% of the time. I expect that this change would be completely harmless for existing cards that work, and would only introduce additional delay for cards that do not work. ALSA bug#4032. Signed-off-by: Steve Soule Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 20cb60afb200..c11920623009 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2122,7 +2122,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, } /* nothing should be in powerdown mode */ snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0); - end_time = jiffies + msecs_to_jiffies(120); + end_time = jiffies + msecs_to_jiffies(5000); do { if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) goto __ready_ok; -- cgit From 1cf86f6f9b000e98c1b7f866f99633ae67464e2f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 15 Dec 2009 15:54:21 +0900 Subject: ASoC: ak4642: Add default return value in ak4642_modinit If ak4642 driver was compiled without I2C configs, ak4642_modinit return value will become un-stable. This patch modify this bug Reported-by: Magnus Damm Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ak4642.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index b69861d52161..3ef16bbc8c83 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -470,7 +470,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642); static int __init ak4642_modinit(void) { - int ret; + int ret = 0; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&ak4642_i2c_driver); #endif -- cgit From 471452104b8520337ae2fb48c4e61cd4896e025d Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 14 Dec 2009 18:00:08 -0800 Subject: const: constify remaining dev_pm_ops Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/arm/pxa2xx-ac97.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec.h | 2 +- sound/soc/soc-core.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index b4b48afb6de6..5d9411839cd7 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -159,7 +159,7 @@ static int pxa2xx_ac97_resume(struct device *dev) return ret; } -static struct dev_pm_ops pxa2xx_ac97_pm_ops = { +static const struct dev_pm_ops pxa2xx_ac97_pm_ops = { .suspend = pxa2xx_ac97_suspend, .resume = pxa2xx_ac97_resume, }; diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c index d441c3b64631..4984754f3298 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec.c @@ -312,7 +312,7 @@ int simtec_audio_resume(struct device *dev) return 0; } -struct dev_pm_ops simtec_audio_pmops = { +const struct dev_pm_ops simtec_audio_pmops = { .resume = simtec_audio_resume, }; EXPORT_SYMBOL_GPL(simtec_audio_pmops); diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h index 2714203af161..e18faee30cce 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.h +++ b/sound/soc/s3c24xx/s3c24xx_simtec.h @@ -15,7 +15,7 @@ extern int simtec_audio_core_probe(struct platform_device *pdev, extern int simtec_audio_remove(struct platform_device *pdev); #ifdef CONFIG_PM -extern struct dev_pm_ops simtec_audio_pmops; +extern const struct dev_pm_ops simtec_audio_pmops; #define simtec_audio_pm &simtec_audio_pmops #else #define simtec_audio_pm NULL diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ef8f28284cb9..0a6440c6f54a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1236,7 +1236,7 @@ static int soc_poweroff(struct device *dev) return 0; } -static struct dev_pm_ops soc_pm_ops = { +static const struct dev_pm_ops soc_pm_ops = { .suspend = soc_suspend, .resume = soc_resume, .poweroff = soc_poweroff, -- cgit From 3c55494670745e523f69b56edb66ca0b50a470c2 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 14 Dec 2009 18:00:36 -0800 Subject: ALSA: cs5535audio: free OLPC quirks from reliance on MGEODE_LX cpu optimization Previously, OLPC support for the mic extensions was only enabled in the ALSA driver if CONFIG_OLPC and CONFIG_MGEODE_LX were both set. This was because the old geode GPIO code was written in a manner that assumed CONFIG_MGEODE_LX. With the new cs553x-gpio driver, this is no longer the case; as such, we can drop the requirement on CONFIG_MGEODE_LX and instead include a requirement on GPIOLIB. We use the generic GPIO API rather than the cs553x-specific API. Signed-off-by: Andres Salomon Cc: Takashi Iwai Cc: Jordan Crouse Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/pci/cs5535audio/Makefile | 2 -- sound/pci/cs5535audio/cs5535audio.c | 1 + sound/pci/cs5535audio/cs5535audio.h | 4 +++- sound/pci/cs5535audio/cs5535audio_olpc.c | 26 +++++++++++++++++++------- 4 files changed, 23 insertions(+), 10 deletions(-) (limited to 'sound') diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile index fda7a94c992f..ccc642269b9e 100644 --- a/sound/pci/cs5535audio/Makefile +++ b/sound/pci/cs5535audio/Makefile @@ -4,9 +4,7 @@ snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o -ifdef CONFIG_MGEODE_LX snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o -endif # Toplevel Module Dependency obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index 05f56e04849b..91e7faf69bbb 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -389,6 +389,7 @@ probefail_out: static void __devexit snd_cs5535audio_remove(struct pci_dev *pci) { + olpc_quirks_cleanup(); snd_card_free(pci_get_drvdata(pci)); pci_set_drvdata(pci, NULL); } diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h index 7a298ac662e3..51966d782a3c 100644 --- a/sound/pci/cs5535audio/cs5535audio.h +++ b/sound/pci/cs5535audio/cs5535audio.h @@ -99,10 +99,11 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state); int snd_cs5535audio_resume(struct pci_dev *pci); #endif -#if defined(CONFIG_OLPC) && defined(CONFIG_MGEODE_LX) +#ifdef CONFIG_OLPC void __devinit olpc_prequirks(struct snd_card *card, struct snd_ac97_template *ac97); int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97); +void __devexit olpc_quirks_cleanup(void); void olpc_analog_input(struct snd_ac97 *ac97, int on); void olpc_mic_bias(struct snd_ac97 *ac97, int on); @@ -128,6 +129,7 @@ static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97) { return 0; } +static inline void olpc_quirks_cleanup(void) { } static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { } static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { } static inline void olpc_capture_open(struct snd_ac97 *ac97) { } diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c index 5c6814335cd7..50da49be9ae5 100644 --- a/sound/pci/cs5535audio/cs5535audio_olpc.c +++ b/sound/pci/cs5535audio/cs5535audio_olpc.c @@ -13,10 +13,13 @@ #include #include #include +#include #include #include "cs5535audio.h" +#define DRV_NAME "cs5535audio-olpc" + /* * OLPC has an additional feature on top of the regular AD1888 codec features. * It has an Analog Input mode that is switched into (after disabling the @@ -38,10 +41,7 @@ void olpc_analog_input(struct snd_ac97 *ac97, int on) } /* set Analog Input through GPIO */ - if (on) - geode_gpio_set(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL); - else - geode_gpio_clear(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL); + gpio_set_value(OLPC_GPIO_MIC_AC, on); } /* @@ -73,8 +73,7 @@ static int olpc_dc_info(struct snd_kcontrol *kctl, static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v) { - v->value.integer.value[0] = geode_gpio_isset(OLPC_GPIO_MIC_AC, - GPIO_OUTPUT_VAL); + v->value.integer.value[0] = gpio_get_value(OLPC_GPIO_MIC_AC); return 0; } @@ -153,6 +152,12 @@ int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97) if (!machine_is_olpc()) return 0; + if (gpio_request(OLPC_GPIO_MIC_AC, DRV_NAME)) { + printk(KERN_ERR DRV_NAME ": unable to allocate MIC GPIO\n"); + return -EIO; + } + gpio_direction_output(OLPC_GPIO_MIC_AC, 0); + /* drop the original AD1888 HPF control */ memset(&elem, 0, sizeof(elem)); elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER; @@ -169,11 +174,18 @@ int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97) for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) { err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i], ac97->private_data)); - if (err < 0) + if (err < 0) { + gpio_free(OLPC_GPIO_MIC_AC); return err; + } } /* turn off the mic by default */ olpc_mic_bias(ac97, 0); return 0; } + +void __devexit olpc_quirks_cleanup(void) +{ + gpio_free(OLPC_GPIO_MIC_AC); +} -- cgit From e7d2860b690d4f3bed6824757c540579638e3d1e Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Mon, 14 Dec 2009 18:01:06 -0800 Subject: tree-wide: convert open calls to remove spaces to skip_spaces() lib function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes use of skip_spaces() defined in lib/string.c for removing leading spaces from strings all over the tree. It decreases lib.a code size by 47 bytes and reuses the function tree-wide: text data bss dec hex filename 64688 584 592 65864 10148 (TOTALS-BEFORE) 64641 584 592 65817 10119 (TOTALS-AFTER) Also, while at it, if we see (*str && isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space". Julia Lawall tried the semantic patch (http://coccinelle.lip6.fr) below, and found occurrences of this pattern on 3 more files: drivers/leds/led-class.c drivers/leds/ledtrig-timer.c drivers/video/output.c @@ expression str; @@ ( // ignore skip_spaces cases while (*str && isspace(*str)) { \(str++;\|++str;\) } | - *str && isspace(*str) ) Signed-off-by: André Goddard Rosa Cc: Julia Lawall Cc: Martin Schwidefsky Cc: Jeff Dike Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Cc: Richard Purdie Cc: Neil Brown Cc: Kyle McMartin Cc: Henrique de Moraes Holschuh Cc: David Howells Cc: Cc: Samuel Ortiz Cc: Patrick McHardy Cc: Takashi Iwai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/pci/hda/hda_hwdep.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index d24328661c6a..40ccb419b6e9 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include "hda_codec.h" @@ -428,8 +429,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf) char *key, *val; struct hda_hint *hint; - while (isspace(*buf)) - buf++; + buf = skip_spaces(buf); if (!*buf || *buf == '#' || *buf == '\n') return 0; if (*buf == '=') @@ -444,8 +444,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf) return -EINVAL; } *val++ = 0; - while (isspace(*val)) - val++; + val = skip_spaces(val); remove_trail_spaces(key); remove_trail_spaces(val); hint = get_hint(codec, key); -- cgit From 75b46c1321785c29cfbc4f839b6dc031428734ad Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Tue, 15 Dec 2009 20:53:44 -0500 Subject: ASoC: Fix disable of SPDIF on STAC9766 codec Change code so that switching to playing music through the analog output disables SPDIF out instead of disabling it when stream ends. Signed-off-by: Jon Smirl Acked-by: Mark Brown --- sound/soc/codecs/stac9766.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index bbc72c2ddfca..81b8c9dfe7fc 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -191,6 +191,7 @@ static int ac97_analog_prepare(struct snd_pcm_substream *substream, vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); vra |= 0x1; /* enable variable rate audio */ + vra &= ~0x4; /* disable SPDIF output */ stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); @@ -221,22 +222,6 @@ static int ac97_digital_prepare(struct snd_pcm_substream *substream, return stac9766_ac97_write(codec, reg, runtime->rate); } -static int ac97_digital_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned short vra; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); - vra &= !0x04; - stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); - break; - } - return 0; -} - static int stac9766_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -315,7 +300,6 @@ static struct snd_soc_dai_ops stac9766_dai_ops_analog = { static struct snd_soc_dai_ops stac9766_dai_ops_digital = { .prepare = ac97_digital_prepare, - .trigger = ac97_digital_trigger, }; struct snd_soc_dai stac9766_dai[] = { -- cgit From ebeb53e1e1f11a51d8a93843a437f516e3528bfa Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Tue, 15 Dec 2009 20:09:02 +0530 Subject: mfd: twl: fix twl4030 rename for remaining driver, board files Recent drivers/mfd/twl4030* renames to twl broke compile for various boards as the series was missing a patch to change the board-*.c files. This patch renames include twl4030.h to include twl.h and also renames twl4030_i2c_ routines. Signed-off-by: Balaji T K Acked-by: Mark Brown Reviewed-by: Felipe Balbi Cc: Samuel Ortiz Signed-off-by: Tony Lindgren --- sound/soc/omap/sdp3430.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index c071f9603a38..3c85c0f92823 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -321,11 +321,11 @@ static int __init sdp3430_soc_init(void) *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */ /* Set TWL4030 GPIO6 as EXTMUTE signal */ - twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux, + twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux, TWL4030_INTBR_PMBR1); pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03); pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02); - twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux, + twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux, TWL4030_INTBR_PMBR1); ret = platform_device_add(sdp3430_snd_device); -- cgit From 2fbe74b90bafebce615466b4c20f96b0465df1ae Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 16 Dec 2009 16:54:43 +0100 Subject: sound/oss/pss: Fix test of unsigned in pss_reset_dsp() and pss_download_boot() limit and jiffies are unsigned so the test did not work. Signed-off-by: Roel Kluin Signed-off-by: Takashi Iwai --- sound/oss/pss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/oss/pss.c b/sound/oss/pss.c index 83f5ee236b12..e19dd5dcc2de 100644 --- a/sound/oss/pss.c +++ b/sound/oss/pss.c @@ -269,7 +269,7 @@ static int pss_reset_dsp(pss_confdata * devc) unsigned long i, limit = jiffies + HZ/10; outw(0x2000, REG(PSS_CONTROL)); - for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) + for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++) inw(REG(PSS_CONTROL)); outw(0x0000, REG(PSS_CONTROL)); return 1; @@ -369,11 +369,11 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size outw(0, REG(PSS_DATA)); limit = jiffies + HZ/10; - for (i = 0; i < 32768 && (limit - jiffies >= 0); i++) + for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++) val = inw(REG(PSS_STATUS)); limit = jiffies + HZ/10; - for (i = 0; i < 32768 && (limit-jiffies >= 0); i++) + for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++) { val = inw(REG(PSS_STATUS)); if (val & 0x4000) -- cgit From ebb83eeb6469bedda83b4dc6f23ddf93eb32b347 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 17 Dec 2009 12:23:00 +0100 Subject: ALSA: hda - More ALC663 fixes and support of compatible chips 1. Add more ASUS NB model. 2. Fixed alc663_m51va_setup M51VA has Digital Mic that NID is 0x12. The record source index is 0x9 for ALC663. So, to modify the alc663_m51va_setup function to index 0x9 and add analog Mic aupport function alc663_mode1_setup. 3. Add ASUS mode7 and mode8 modules for ALC663 Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 306 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 282 insertions(+), 24 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c9e860709747..287bb6019df9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -131,8 +131,8 @@ enum { enum { ALC269_BASIC, ALC269_QUANTA_FL1, - ALC269_ASUS_EEEPC_P703, - ALC269_ASUS_EEEPC_P901, + ALC269_ASUS_AMIC, + ALC269_ASUS_DMIC, ALC269_FUJITSU, ALC269_LIFEBOOK, ALC269_AUTO, @@ -188,6 +188,8 @@ enum { ALC663_ASUS_MODE4, ALC663_ASUS_MODE5, ALC663_ASUS_MODE6, + ALC663_ASUS_MODE7, + ALC663_ASUS_MODE8, ALC272_DELL, ALC272_DELL_ZM1, ALC272_SAMSUNG_NC10, @@ -13232,10 +13234,12 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = { /* toggle speaker-output according to the hp-jack state */ static void alc269_speaker_automute(struct hda_codec *codec) { + struct alc_spec *spec = codec->spec; + unsigned int nid = spec->autocfg.hp_pins[0]; unsigned int present; unsigned char bits; - present = snd_hda_jack_detect(codec, 0x15); + present = snd_hda_jack_detect(codec, nid); bits = present ? AMP_IN_MUTE(0) : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -13460,8 +13464,8 @@ static void alc269_auto_init(struct hda_codec *codec) static const char *alc269_models[ALC269_MODEL_LAST] = { [ALC269_BASIC] = "basic", [ALC269_QUANTA_FL1] = "quanta", - [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", - [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", + [ALC269_ASUS_AMIC] = "asus-amic", + [ALC269_ASUS_DMIC] = "asus-dmic", [ALC269_FUJITSU] = "fujitsu", [ALC269_LIFEBOOK] = "lifebook", [ALC269_AUTO] = "auto", @@ -13470,18 +13474,41 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { static struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", - ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703), - SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703), + ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC), + SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC), + SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", - ALC269_ASUS_EEEPC_P901), + ALC269_ASUS_DMIC), SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", - ALC269_ASUS_EEEPC_P901), - SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901), + ALC269_ASUS_DMIC), + SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC), + SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC), SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), {} @@ -13511,7 +13538,7 @@ static struct alc_config_preset alc269_presets[] = { .setup = alc269_quanta_fl1_setup, .init_hook = alc269_quanta_fl1_init_hook, }, - [ALC269_ASUS_EEEPC_P703] = { + [ALC269_ASUS_AMIC] = { .mixers = { alc269_eeepc_mixer }, .cap_mixer = alc269_epc_capture_mixer, .init_verbs = { alc269_init_verbs, @@ -13525,7 +13552,7 @@ static struct alc_config_preset alc269_presets[] = { .setup = alc269_eeepc_amic_setup, .init_hook = alc269_eeepc_inithook, }, - [ALC269_ASUS_EEEPC_P901] = { + [ALC269_ASUS_DMIC] = { .mixers = { alc269_eeepc_mixer }, .cap_mixer = alc269_epc_capture_mixer, .init_verbs = { alc269_init_verbs, @@ -16160,6 +16187,52 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = { { } /* end */ }; +static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct snd_kcontrol_new alc663_mode7_mixer[] = { + HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), + HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), + HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc663_mode8_mixer[] = { + HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), + HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), + HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + { } /* end */ +}; + + static struct snd_kcontrol_new alc662_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -16447,6 +16520,45 @@ static struct hda_verb alc272_dell_init_verbs[] = { {} }; +static struct hda_verb alc663_mode7_init_verbs[] = { + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, + {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_mode8_init_verbs[] = { + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), @@ -16626,6 +16738,54 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) } } +static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) +{ + unsigned int present1, present2; + + present1 = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + present2 = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + + if (present1 || present2) { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + } else { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + +static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) +{ + unsigned int present1, present2; + + present1 = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + present2 = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + + if (present1 || present2) { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + } else { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + snd_hda_codec_write_cache(codec, 0x17, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + static void alc663_m51va_unsol_event(struct hda_codec *codec, unsigned int res) { @@ -16645,7 +16805,7 @@ static void alc663_m51va_setup(struct hda_codec *codec) spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; - spec->int_mic.mux_idx = 1; + spec->int_mic.mux_idx = 9; spec->auto_mic = 1; } @@ -16657,7 +16817,17 @@ static void alc663_m51va_inithook(struct hda_codec *codec) /* ***************** Mode1 ******************************/ #define alc663_mode1_unsol_event alc663_m51va_unsol_event -#define alc663_mode1_setup alc663_m51va_setup + +static void alc663_mode1_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; +} + #define alc663_mode1_inithook alc663_m51va_inithook /* ***************** Mode2 ******************************/ @@ -16674,7 +16844,7 @@ static void alc662_mode2_unsol_event(struct hda_codec *codec, } } -#define alc662_mode2_setup alc663_m51va_setup +#define alc662_mode2_setup alc663_mode1_setup static void alc662_mode2_inithook(struct hda_codec *codec) { @@ -16695,7 +16865,7 @@ static void alc663_mode3_unsol_event(struct hda_codec *codec, } } -#define alc663_mode3_setup alc663_m51va_setup +#define alc663_mode3_setup alc663_mode1_setup static void alc663_mode3_inithook(struct hda_codec *codec) { @@ -16716,7 +16886,7 @@ static void alc663_mode4_unsol_event(struct hda_codec *codec, } } -#define alc663_mode4_setup alc663_m51va_setup +#define alc663_mode4_setup alc663_mode1_setup static void alc663_mode4_inithook(struct hda_codec *codec) { @@ -16737,7 +16907,7 @@ static void alc663_mode5_unsol_event(struct hda_codec *codec, } } -#define alc663_mode5_setup alc663_m51va_setup +#define alc663_mode5_setup alc663_mode1_setup static void alc663_mode5_inithook(struct hda_codec *codec) { @@ -16758,7 +16928,7 @@ static void alc663_mode6_unsol_event(struct hda_codec *codec, } } -#define alc663_mode6_setup alc663_m51va_setup +#define alc663_mode6_setup alc663_mode1_setup static void alc663_mode6_inithook(struct hda_codec *codec) { @@ -16766,6 +16936,50 @@ static void alc663_mode6_inithook(struct hda_codec *codec) alc_mic_automute(codec); } +/* ***************** Mode7 ******************************/ +static void alc663_mode7_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_two_hp_m7_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc_mic_automute(codec); + break; + } +} + +#define alc663_mode7_setup alc663_mode1_setup + +static void alc663_mode7_inithook(struct hda_codec *codec) +{ + alc663_two_hp_m7_speaker_automute(codec); + alc_mic_automute(codec); +} + +/* ***************** Mode8 ******************************/ +static void alc663_mode8_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_two_hp_m8_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc_mic_automute(codec); + break; + } +} + +#define alc663_mode8_setup alc663_m51va_setup + +static void alc663_mode8_inithook(struct hda_codec *codec) +{ + alc663_two_hp_m8_speaker_automute(codec); + alc_mic_automute(codec); +} + static void alc663_g71v_hp_automute(struct hda_codec *codec) { unsigned int present; @@ -16900,6 +17114,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { [ALC663_ASUS_MODE4] = "asus-mode4", [ALC663_ASUS_MODE5] = "asus-mode5", [ALC663_ASUS_MODE6] = "asus-mode6", + [ALC663_ASUS_MODE7] = "asus-mode7", + [ALC663_ASUS_MODE8] = "asus-mode8", [ALC272_DELL] = "dell", [ALC272_DELL_ZM1] = "dell-zm1", [ALC272_SAMSUNG_NC10] = "samsung-nc10", @@ -16916,12 +17132,22 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), + SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), + SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), + SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), + SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), @@ -17205,6 +17431,36 @@ static struct alc_config_preset alc662_presets[] = { .setup = alc663_mode6_setup, .init_hook = alc663_mode6_inithook, }, + [ALC663_ASUS_MODE7] = { + .mixers = { alc663_mode7_mixer }, + .cap_mixer = alc662_auto_capture_mixer, + .init_verbs = { alc662_init_verbs, + alc663_mode7_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .unsol_event = alc663_mode7_unsol_event, + .setup = alc663_mode7_setup, + .init_hook = alc663_mode7_inithook, + }, + [ALC663_ASUS_MODE8] = { + .mixers = { alc663_mode8_mixer }, + .cap_mixer = alc662_auto_capture_mixer, + .init_verbs = { alc662_init_verbs, + alc663_mode8_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .unsol_event = alc663_mode8_unsol_event, + .setup = alc663_mode8_setup, + .init_hook = alc663_mode8_inithook, + }, [ALC272_DELL] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc272_auto_capture_mixer, @@ -17688,7 +17944,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, + { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, + { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, -- cgit From 254bba6a7e28c77d8b32d9eaeba02d4943ee844e Mon Sep 17 00:00:00 2001 From: Einar Rünkaru Date: Wed, 16 Dec 2009 22:16:13 +0200 Subject: ALSA: hda - Fixed internal mic initialization for Dell Vostro 1015 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed initialization of internal mic and added internal mic boost control Renamed analog mic boost control to ext mic boost contol. Name pair analog/digital seems too confusing for a normal user. Signed-off-by: Einar Rünkaru Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a09c03c3f62b..ca9ad9fddbf2 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -111,6 +111,7 @@ struct conexant_spec { unsigned int dell_automute; unsigned int port_d_mode; unsigned char ext_mic_bias; + unsigned int dell_vostro; }; static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, @@ -2109,9 +2110,12 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); int val; + hda_nid_t nid = kcontrol->private_value & 0xff; + int inout = (kcontrol->private_value & 0x100) ? + AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT; - val = snd_hda_codec_read(codec, 0x17, 0, - AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT); + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, inout); ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN; return 0; @@ -2123,6 +2127,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); const struct hda_input_mux *imux = &cxt5066_analog_mic_boost; unsigned int idx; + hda_nid_t nid = kcontrol->private_value & 0xff; + int inout = (kcontrol->private_value & 0x100) ? + AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT; if (!imux->num_items) return 0; @@ -2130,9 +2137,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol, if (idx >= imux->num_items) idx = imux->num_items - 1; - snd_hda_codec_write_cache(codec, 0x17, 0, + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | + AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout | imux->items[idx].index); return 1; @@ -2201,10 +2208,11 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Mic Boost Capture Enum", + .name = "Ext Mic Boost Capture Enum", .info = cxt5066_mic_boost_mux_enum_info, .get = cxt5066_mic_boost_mux_enum_get, .put = cxt5066_mic_boost_mux_enum_put, + .private_value = 0x17, }, HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others), @@ -2212,6 +2220,18 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { {} }; +static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Int Mic Boost Capture Enum", + .info = cxt5066_mic_boost_mux_enum_info, + .get = cxt5066_mic_boost_mux_enum_get, + .put = cxt5066_mic_boost_mux_enum_put, + .private_value = 0x23 | 0x100, + }, + {} +}; + static struct hda_verb cxt5066_init_verbs[] = { {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ @@ -2397,11 +2417,16 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = { /* initialize jack-sensing, too */ static int cxt5066_init(struct hda_codec *codec) { + struct conexant_spec *spec = codec->spec; + snd_printdd("CXT5066: init\n"); conexant_init(codec); if (codec->patch_ops.unsol_event) { cxt5066_hp_automute(codec); - cxt5066_automic(codec); + if (spec->dell_vostro) + cxt5066_vostro_automic(codec); + else + cxt5066_automic(codec); } return 0; } @@ -2500,7 +2525,9 @@ static int patch_cxt5066(struct hda_codec *codec) spec->init_verbs[0] = cxt5066_init_verbs_vostro; spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; spec->mixers[spec->num_mixers++] = cxt5066_mixers; + spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; spec->port_d_mode = 0; + spec->dell_vostro = 1; /* no S/PDIF out */ spec->multiout.dig_out_nid = 0; -- cgit From c0f8faf0c7cd497ec7c1d61e1e9424f4384c1f68 Mon Sep 17 00:00:00 2001 From: Einar Rünkaru Date: Wed, 16 Dec 2009 22:41:36 +0200 Subject: ALSA: hda - Make use of beep device found in Dell Vostro 1015n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Conexant CX20583-10Z has digital beep device with volume control. Making use of them. Signed-off-by: Einar Rünkaru Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ca9ad9fddbf2..c578c28f368e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -29,6 +29,7 @@ #include "hda_codec.h" #include "hda_local.h" +#include "hda_beep.h" #define CXT_PIN_DIR_IN 0x00 #define CXT_PIN_DIR_OUT 0x01 @@ -477,6 +478,7 @@ static void conexant_free(struct hda_codec *codec) snd_array_free(&spec->jacks); } #endif + snd_hda_detach_beep_device(codec); kfree(codec->spec); } @@ -2229,6 +2231,7 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { .put = cxt5066_mic_boost_mux_enum_put, .private_value = 0x23 | 0x100, }, + HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), {} }; @@ -2528,6 +2531,7 @@ static int patch_cxt5066(struct hda_codec *codec) spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers; spec->port_d_mode = 0; spec->dell_vostro = 1; + snd_hda_attach_beep_device(codec, 0x13); /* no S/PDIF out */ spec->multiout.dig_out_nid = 0; -- cgit From 035eb0cff0671ada49ba9f3e5c9e7b0cb950efea Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2009 15:00:26 +0100 Subject: ALSA: hda - Fix missing capsrc_nids for ALC88x Some model quirks missed the corresponding capsrc_nids. This resulted in non-working capture source selection. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_realtek.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 287bb6019df9..d9a9f0c7cf5b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9238,6 +9238,8 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), .adc_nids = alc889_adc_nids, + .capsrc_nids = alc889_capsrc_nids, + .capsrc_nids = alc889_capsrc_nids, .dig_out_nid = ALC883_DIGOUT_NID, .dig_in_nid = ALC883_DIGIN_NID, .slave_dig_outs = alc883_slave_dig_outs, @@ -9284,6 +9286,7 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .adc_nids = alc883_adc_nids_alt, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), + .capsrc_nids = alc883_capsrc_nids, .dig_out_nid = ALC883_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, @@ -9430,6 +9433,7 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .adc_nids = alc883_adc_nids_alt, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), + .capsrc_nids = alc883_capsrc_nids, .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, @@ -9491,6 +9495,7 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .adc_nids = alc883_adc_nids_alt, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), + .capsrc_nids = alc883_capsrc_nids, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_lenovo_101e_capture_source, @@ -9670,6 +9675,7 @@ static struct alc_config_preset alc882_presets[] = { alc880_gpio1_init_verbs }, .adc_nids = alc883_adc_nids, .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .capsrc_nids = alc883_capsrc_nids, .dac_nids = alc883_dac_nids, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .channel_mode = alc889A_mb31_6ch_modes, -- cgit From d1409ae4cecb4af260759bdfdf88fafca23a9940 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Dec 2009 15:01:31 +0100 Subject: ALSA: hda - Fix NULL dereference in kctl-NID mapping in patch_realtek.c capsrc_nids can be NULL, and adc_nids should be taken as fallback. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 36556b10357a..012435212e58 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2517,7 +2517,10 @@ static int alc_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids, + hda_nid_t *nids = spec->capsrc_nids; + if (!nids) + nids = spec->adc_nids; + err = snd_hda_add_nids(codec, kctl, i, nids, spec->input_mux->num_items); if (err < 0) return err; -- cgit From 2fef62c825f09e29d2f52dc187ddf6f99e28c7f1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Dec 2009 08:48:42 +0100 Subject: ALSA: hda - Fix quirk for Maxdata obook4-1 Works fine with the auto-parser. Reference: Novell bnc#564940 https://bugzilla.novell.com/show_bug.cgi?id=564940 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d9a9f0c7cf5b..84bc2c7c4421 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8921,7 +8921,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ - SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), + SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), -- cgit From 3e85fd614c7b6bb7f33bb04a0dcb5a3bfca4c0fe Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 18 Dec 2009 09:27:24 +0100 Subject: sound: sgio2audio/pdaudiocf/usb-audio: initialize PCM buffer When allocating the PCM buffer, use vmalloc_user() instead of vmalloc(). Otherwise, it would be possible for applications to play the previous contents of the kernel memory to the speakers, or to read it directly if the buffer is exported to userspace. Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Takashi Iwai --- sound/mips/sgio2audio.c | 2 +- sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c | 2 +- sound/usb/usbaudio.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 8691f4cf6191..f1d9d16b5486 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -609,7 +609,7 @@ static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream, /* alloc virtual 'dma' area */ if (runtime->dma_area) vfree(runtime->dma_area); - runtime->dma_area = vmalloc(size); + runtime->dma_area = vmalloc_user(size); if (runtime->dma_area == NULL) return -ENOMEM; runtime->dma_bytes = size; diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index d057e6489643..5cfa608823f7 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -51,7 +51,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s return 0; /* already enough large */ vfree(runtime->dma_area); } - runtime->dma_area = vmalloc_32(size); + runtime->dma_area = vmalloc_32_user(size); if (! runtime->dma_area) return -ENOMEM; runtime->dma_bytes = size; diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index b074a594c595..4963defee18a 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -752,7 +752,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s return 0; /* already large enough */ vfree(runtime->dma_area); } - runtime->dma_area = vmalloc(size); + runtime->dma_area = vmalloc_user(size); if (!runtime->dma_area) return -ENOMEM; runtime->dma_bytes = size; -- cgit From 48c03ce72f2665f79a3fe54fc6d71b8cc3d30803 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 17 Dec 2009 14:51:35 +0100 Subject: ASoC: wm8974: fix a wrong bit definition The wm8974 datasheet defines BUFIOEN as bit 2. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8974.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 81c57b5c591c..a808675388fc 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -47,7 +47,7 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = { }; #define WM8974_POWER1_BIASEN 0x08 -#define WM8974_POWER1_BUFIOEN 0x10 +#define WM8974_POWER1_BUFIOEN 0x04 struct wm8974_priv { struct snd_soc_codec codec; -- cgit From 0c2fd1bf4c6cb6095d8b3088d285167e66c12147 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Dec 2009 16:41:39 +0100 Subject: ALSA: hda - Check class to identify Nvidia controller chips Instead of listing all individual PCI IDs, check the matching with the PCI class together with the vendor id for Nvidia. This simplifies the pci id entries. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9b56f937913e..93eaf4fc39be 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2694,32 +2694,10 @@ static struct pci_device_id azx_ids[] = { /* ULI M5461 */ { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI }, /* NVIDIA MCP */ - { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA }, - { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), + .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, + .class_mask = 0xffffff, + .driver_data = AZX_DRIVER_NVIDIA }, /* Teradici */ { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, /* Creative X-Fi (CA0110-IBG) */ -- cgit From d49464318a7c51676c44cbd1e2480f651cc43807 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 18 Dec 2009 20:25:30 +0100 Subject: ALSA: aaci - Fix a typo Fixed a typo of the max buffer size specified for buffer allocation changed in the commit d6797322231af98b9bb4afb175dd614cf511e5f7. Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 1497dce1b04a..ae38f2c342cc 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -1028,7 +1028,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - NULL, 0, 64 * 104); + NULL, 0, 64 * 1024); } return ret; -- cgit From 6ca867c827c84d21316e9dc4035abe9480f8347c Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:35 +0000 Subject: ALSA: AACI: simplify codec rate information There's no need for a specific rule; ALSA's generic AC'97 support calculates the necessary rate constraint information itself, and we can use this directly. Signed-off-by: Russell King Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 75 +++----------------------------------------------------- 1 file changed, 3 insertions(+), 72 deletions(-) (limited to 'sound') diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index ae38f2c342cc..ea3be874c84f 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -330,63 +330,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) /* * ALSA support. */ - -struct aaci_stream { - unsigned char codec_idx; - unsigned char rate_idx; -}; - -static struct aaci_stream aaci_streams[] = { - [ACSTREAM_FRONT] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_FRONT_DAC, - }, - [ACSTREAM_SURROUND] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_SURR_DAC, - }, - [ACSTREAM_LFE] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_LFE_DAC, - }, -}; - -static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid) -{ - struct aaci_stream *s = aaci_streams + streamid; - return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx]; -} - -static unsigned int rate_list[] = { - 5512, 8000, 11025, 16000, 22050, 32000, 44100, - 48000, 64000, 88200, 96000, 176400, 192000 -}; - -/* - * Double-rate rule: we can support double rate iff channels == 2 - * (unimplemented) - */ -static int -aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule) -{ - struct aaci *aaci = rule->private; - unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512; - struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS); - - switch (c->max) { - case 6: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE); - case 4: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND); - case 2: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT); - } - - return snd_interval_list(hw_param_interval(p, rule->var), - ARRAY_SIZE(rate_list), rate_list, - rate_mask); -} - static struct snd_pcm_hardware aaci_hw_info = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -400,10 +343,7 @@ static struct snd_pcm_hardware aaci_hw_info = { */ .formats = SNDRV_PCM_FMTBIT_S16_LE, - /* should this be continuous or knot? */ - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_max = 48000, - .rate_min = 4000, + /* rates are setup from the AC'97 codec */ .channels_min = 2, .channels_max = 6, .buffer_bytes_max = 64 * 1024, @@ -423,6 +363,8 @@ static int __aaci_pcm_open(struct aaci *aaci, aacirun->substream = substream; runtime->private_data = aacirun; runtime->hw = aaci_hw_info; + runtime->hw.rates = aacirun->pcm->rates; + snd_pcm_limit_hw_rates(runtime); /* * FIXME: ALSA specifies fifo_size in bytes. If we're in normal @@ -433,17 +375,6 @@ static int __aaci_pcm_open(struct aaci *aaci, */ runtime->hw.fifo_size = aaci->fifosize * 2; - /* - * Add rule describing hardware rate dependency - * on the number of channels. - */ - ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - aaci_rule_rate_by_channels, aaci, - SNDRV_PCM_HW_PARAM_CHANNELS, - SNDRV_PCM_HW_PARAM_RATE, -1); - if (ret) - goto out; - ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED, DRIVER_NAME, aaci); if (ret) -- cgit From 4e30b69108b20eca80f1a323f969bf7629c7795f Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:37 +0000 Subject: ALSA: AACI: cleanup aaci_pcm_hw_params Since the recording and playback paths are now the same, eliminate the needless conditionals. Signed-off-by: Russell King Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'sound') diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index ea3be874c84f..2e28748a3d8d 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -438,18 +438,14 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - if (err < 0) - goto out; - - err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), - params_channels(params), - aacirun->pcm->r[0].slots); - if (err) - goto out; + if (err >= 0) { + err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), + params_channels(params), + aacirun->pcm->r[0].slots); - aacirun->pcm_open = 1; + aacirun->pcm_open = err == 0; + } - out: return err; } @@ -458,7 +454,7 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct aaci_runtime *aacirun = runtime->private_data; - aacirun->start = (void *)runtime->dma_area; + aacirun->start = runtime->dma_area; aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream); aacirun->ptr = aacirun->start; aacirun->period = -- cgit From d3aee7996c30f928bbbbfd0994148e35d2e83084 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:40 +0000 Subject: ALSA: AACI: factor common hw_params logic into aaci_pcm_hw_params Signed-off-by: Russell King Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'sound') diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 2e28748a3d8d..b88bbded2f4f 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -444,6 +444,11 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, aacirun->pcm->r[0].slots); aacirun->pcm_open = err == 0; + aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; + aacirun->fifosz = aaci->fifosize * 4; + + if (aacirun->cr & CR_COMPACT) + aacirun->fifosz >>= 1; } return err; @@ -554,14 +559,9 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, * Enable FIFO, compact mode, 16 bits per sample. * FIXME: double rate slots? */ - if (ret >= 0) { - aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; + if (ret >= 0) aacirun->cr |= channels_to_txmask[channels]; - aacirun->fifosz = aaci->fifosize * 4; - if (aacirun->cr & CR_COMPACT) - aacirun->fifosz >>= 1; - } return ret; } @@ -648,18 +648,10 @@ static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, int ret; ret = aaci_pcm_hw_params(substream, aacirun, params); - - if (ret >= 0) { - aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; - + if (ret >= 0) /* Line in record: slot 3 and 4 */ aacirun->cr |= CR_SL3 | CR_SL4; - aacirun->fifosz = aaci->fifosize * 4; - - if (aacirun->cr & CR_COMPACT) - aacirun->fifosz >>= 1; - } return ret; } -- cgit From a08d56583f6b87e2981d1b6e9ee891bdc741cc44 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:45 +0000 Subject: ALSA: AACI: add double-rate support Signed-off-by: Russell King Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b88bbded2f4f..b377370af2d7 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -366,6 +366,10 @@ static int __aaci_pcm_open(struct aaci *aaci, runtime->hw.rates = aacirun->pcm->rates; snd_pcm_limit_hw_rates(runtime); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && + aacirun->pcm->r[1].slots) + snd_ac97_pcm_double_rate_rules(runtime); + /* * FIXME: ALSA specifies fifo_size in bytes. If we're in normal * mode, each 32-bit word contains one sample. If we're in @@ -439,9 +443,12 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); if (err >= 0) { - err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), + unsigned int rate = params_rate(params); + int dbl = rate > 48000; + + err = snd_ac97_pcm_open(aacirun->pcm, rate, params_channels(params), - aacirun->pcm->r[0].slots); + aacirun->pcm->r[dbl].slots); aacirun->pcm_open = err == 0; aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16; @@ -808,6 +815,12 @@ static struct ac97_pcm ac97_defs[] __devinitdata = { (1 << AC97_SLOT_PCM_SRIGHT) | (1 << AC97_SLOT_LFE), }, + [1] = { + .slots = (1 << AC97_SLOT_PCM_LEFT) | + (1 << AC97_SLOT_PCM_RIGHT) | + (1 << AC97_SLOT_PCM_LEFT_0) | + (1 << AC97_SLOT_PCM_RIGHT_0), + }, }, }, [1] = { /* PCM in */ -- cgit From d6a89fefa50feda5516cd5210ad0008a44632b52 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 18 Dec 2009 17:48:50 +0000 Subject: ALSA: AACI: switch to per-pcm locking We can use finer-grained locking, which makes things easier when we gain DMA support. Signed-off-by: Russell King Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 49 +++++++++++++++++++++++++++++-------------------- sound/arm/aaci.h | 2 +- 2 files changed, 30 insertions(+), 21 deletions(-) (limited to 'sound') diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b377370af2d7..c5699863643b 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -172,14 +172,15 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) return v; } -static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun) +static inline void +aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask) { u32 val; int timeout = 5000; do { val = readl(aacirun->base + AACI_SR); - } while (val & (SR_TXB|SR_RXB) && timeout--); + } while (val & mask && timeout--); } @@ -208,8 +209,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) writel(0, aacirun->base + AACI_IE); return; } - ptr = aacirun->ptr; + spin_lock(&aacirun->lock); + + ptr = aacirun->ptr; do { unsigned int len = aacirun->fifosz; u32 val; @@ -217,9 +220,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) if (aacirun->bytes <= 0) { aacirun->bytes += aacirun->period; aacirun->ptr = ptr; - spin_unlock(&aaci->lock); + spin_unlock(&aacirun->lock); snd_pcm_period_elapsed(aacirun->substream); - spin_lock(&aaci->lock); + spin_lock(&aacirun->lock); } if (!(aacirun->cr & CR_EN)) break; @@ -245,7 +248,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) ptr = aacirun->start; } } while(1); + aacirun->ptr = ptr; + + spin_unlock(&aacirun->lock); } if (mask & ISR_URINTR) { @@ -263,6 +269,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) return; } + spin_lock(&aacirun->lock); + ptr = aacirun->ptr; do { unsigned int len = aacirun->fifosz; @@ -271,9 +279,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) if (aacirun->bytes <= 0) { aacirun->bytes += aacirun->period; aacirun->ptr = ptr; - spin_unlock(&aaci->lock); + spin_unlock(&aacirun->lock); snd_pcm_period_elapsed(aacirun->substream); - spin_lock(&aaci->lock); + spin_lock(&aacirun->lock); } if (!(aacirun->cr & CR_EN)) break; @@ -301,6 +309,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) } while (1); aacirun->ptr = ptr; + + spin_unlock(&aacirun->lock); } } @@ -310,7 +320,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) u32 mask; int i; - spin_lock(&aaci->lock); mask = readl(aaci->base + AACI_ALLINTS); if (mask) { u32 m = mask; @@ -320,7 +329,6 @@ static irqreturn_t aaci_irq(int irq, void *devid) } } } - spin_unlock(&aaci->lock); return mask ? IRQ_HANDLED : IRQ_NONE; } @@ -580,7 +588,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun) ie &= ~(IE_URIE|IE_TXIE); writel(ie, aacirun->base + AACI_IE); aacirun->cr &= ~CR_EN; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_TXB); writel(aacirun->cr, aacirun->base + AACI_TXCR); } @@ -588,7 +596,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) { u32 ie; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_TXB); aacirun->cr |= CR_EN; ie = readl(aacirun->base + AACI_IE); @@ -599,12 +607,12 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) { - struct aaci *aaci = substream->private_data; struct aaci_runtime *aacirun = substream->runtime->private_data; unsigned long flags; int ret = 0; - spin_lock_irqsave(&aaci->lock, flags); + spin_lock_irqsave(&aacirun->lock, flags); + switch (cmd) { case SNDRV_PCM_TRIGGER_START: aaci_pcm_playback_start(aacirun); @@ -631,7 +639,8 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm default: ret = -EINVAL; } - spin_unlock_irqrestore(&aaci->lock, flags); + + spin_unlock_irqrestore(&aacirun->lock, flags); return ret; } @@ -666,7 +675,7 @@ static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun) { u32 ie; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_RXB); ie = readl(aacirun->base + AACI_IE); ie &= ~(IE_ORIE | IE_RXIE); @@ -681,7 +690,7 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun) { u32 ie; - aaci_chan_wait_ready(aacirun); + aaci_chan_wait_ready(aacirun, SR_RXB); #ifdef DEBUG /* RX Timeout value: bits 28:17 in RXCR */ @@ -698,12 +707,11 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun) static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) { - struct aaci *aaci = substream->private_data; struct aaci_runtime *aacirun = substream->runtime->private_data; unsigned long flags; int ret = 0; - spin_lock_irqsave(&aaci->lock, flags); + spin_lock_irqsave(&aacirun->lock, flags); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -732,7 +740,7 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd ret = -EINVAL; } - spin_unlock_irqrestore(&aaci->lock, flags); + spin_unlock_irqrestore(&aacirun->lock, flags); return ret; } @@ -933,7 +941,6 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) aaci = card->private_data; mutex_init(&aaci->ac97_sem); - spin_lock_init(&aaci->lock); aaci->card = card; aaci->dev = dev; @@ -1020,12 +1027,14 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) /* * Playback uses AACI channel 0 */ + spin_lock_init(&aaci->playback.lock); aaci->playback.base = aaci->base + AACI_CSCH1; aaci->playback.fifo = aaci->base + AACI_DR1; /* * Capture uses AACI channel 0 */ + spin_lock_init(&aaci->capture.lock); aaci->capture.base = aaci->base + AACI_CSCH1; aaci->capture.fifo = aaci->base + AACI_DR1; diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h index 924f69c1c44c..6a4a2eebdda1 100644 --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h @@ -202,6 +202,7 @@ struct aaci_runtime { void __iomem *base; void __iomem *fifo; + spinlock_t lock; struct ac97_pcm *pcm; int pcm_open; @@ -232,7 +233,6 @@ struct aaci { struct snd_ac97 *ac97; u32 maincr; - spinlock_t lock; struct aaci_runtime playback; struct aaci_runtime capture; -- cgit From ef86f581f7e8b29cb58d7f4e892e1a91b3805124 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 19 Dec 2009 08:18:03 +0100 Subject: ALSA: Use kzalloc for allocating only one thing Use kzalloc rather than kcalloc(1,...) The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ @@ - kcalloc(1, + kzalloc( ...) // Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai --- sound/isa/msnd/msnd_midi.c | 2 +- sound/pci/hda/patch_realtek.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c index cb9aa4c4edd0..4be562b2cf21 100644 --- a/sound/isa/msnd/msnd_midi.c +++ b/sound/isa/msnd/msnd_midi.c @@ -162,7 +162,7 @@ int snd_msndmidi_new(struct snd_card *card, int device) err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi); if (err < 0) return err; - mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL); + mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); if (mpu == NULL) { snd_device_free(card, rmidi); return -ENOMEM; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index aeed4cc5aa79..20c1828e4bac 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12857,7 +12857,7 @@ static int patch_alc268(struct hda_codec *codec) int board_config; int i, has_beep, err; - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; -- cgit From 440b004cf953bec2bc8cd91c64ae707fd7e25327 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 20 Dec 2009 12:04:08 +0100 Subject: ALSA: hda/realtek: Remove extra .capsrc_nids initialization for ALC889_INTEL Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8b375771b3ab..2d3f4f893ef3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9238,8 +9238,6 @@ static struct alc_config_preset alc882_presets[] = { .dac_nids = alc883_dac_nids, .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), .adc_nids = alc889_adc_nids, - .capsrc_nids = alc889_capsrc_nids, - .capsrc_nids = alc889_capsrc_nids, .dig_out_nid = ALC883_DIGOUT_NID, .dig_in_nid = ALC883_DIGIN_NID, .slave_dig_outs = alc883_slave_dig_outs, -- cgit From e2595322a3a353a59cecd7f57e7aa421ecb02d12 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sat, 19 Dec 2009 18:19:02 -0500 Subject: ALSA: hda: Set Front Mic to input vref 50% for Lenovo 3000 Y410 BugLink: https://bugs.launchpad.net/bugs/479373 The OR has verified with hda-verb that the internal microphone needs VREF50 set for audible capture. Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 84bc2c7c4421..1554c3a6fd2e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10686,6 +10686,13 @@ static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { {} }; +static struct hda_verb alc262_lenovo_3000_init_verbs[] = { + /* Front Mic pin: input vref at 50% */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {} +}; + static struct hda_input_mux alc262_fujitsu_capture_source = { .num_items = 3, .items = { @@ -11728,7 +11735,8 @@ static struct alc_config_preset alc262_presets[] = { [ALC262_LENOVO_3000] = { .mixers = { alc262_lenovo_3000_mixer }, .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, - alc262_lenovo_3000_unsol_verbs }, + alc262_lenovo_3000_unsol_verbs, + alc262_lenovo_3000_init_verbs }, .num_dacs = ARRAY_SIZE(alc262_dac_nids), .dac_nids = alc262_dac_nids, .hp_nid = 0x03, -- cgit From 0f86a228f4a4639b3142ce0dad208433b2db377a Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Dec 2009 22:51:18 +0100 Subject: ALSA: HDA: simplify Aspire 8930G verb array This patch just simplifies the 8930G verb array a bit. Just use the common ALC889 EAPD verb array to make things more consistent. The file is already huge enough already. Signed-off-by: Hector Martin Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1554c3a6fd2e..cb97323acc17 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1665,9 +1665,6 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { /* some bit here disables the other DACs. Init=0x4900 */ {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, -/* Enable amplifiers */ - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, /* DMIC fix * This laptop has a stereo digital microphone. The mics are only 1cm apart * which makes the stereo useless. However, either the mic or the ALC889 @@ -9386,7 +9383,8 @@ static struct alc_config_preset alc882_presets[] = { .mixers = { alc888_base_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, - alc889_acer_aspire_8930g_verbs }, + alc889_acer_aspire_8930g_verbs, + alc889_eapd_verbs}, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), -- cgit From 556eea9a926bff8f014b4f80522b4de97ae84213 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Dec 2009 22:51:23 +0100 Subject: ALSA: HDA: remove useless mixers on Aspire 8930G This patch removes some extra mixers that do nothing on the Acer Aspire 8930G. The CD mixer is useless because the SATA DVD/Blu-Ray drive has no analog audio output, and the Side mixer is useless because we max out at 6ch anyway. Signed-off-by: Hector Martin Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cb97323acc17..faeb74f28207 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1777,6 +1777,25 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, + HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + { } /* end */ +}; + + static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -9380,7 +9399,7 @@ static struct alc_config_preset alc882_presets[] = { .init_hook = alc_automute_amp, }, [ALC888_ACER_ASPIRE_8930G] = { - .mixers = { alc888_base_mixer, + .mixers = { alc889_acer_aspire_8930g_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, alc889_acer_aspire_8930g_verbs, -- cgit From f5de24b06aa46427500d0fdbe8616b73a71d8c28 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Dec 2009 22:51:31 +0100 Subject: ALSA: HDA: add powersaving hook for Realtek The current Realtek code makes no specific provision for turning stuff off. The codec chip is placed into low-power mode generically, but this doesn't turn off any external hardware connected to it, in particular external amplifiers. This patch creates a hook function that is called by the codec suspend/resume functions. It ought to disable any external hardware in a device-specific way. I've implemented a generic ALC889 function that sets the EAPD pin properly, and used it for the Acer Aspire 8930G which can benefit from this feature. On my laptop, this results in ~0.5W extra savings. Signed-off-by: Hector Martin Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index faeb74f28207..b3abe9ca826d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -337,6 +337,9 @@ struct alc_spec { /* hooks */ void (*init_hook)(struct hda_codec *codec); void (*unsol_event)(struct hda_codec *codec, unsigned int res); +#ifdef CONFIG_SND_HDA_POWER_SAVE + void (*power_hook)(struct hda_codec *codec, int power); +#endif /* for pin sensing */ unsigned int sense_updated: 1; @@ -388,6 +391,7 @@ struct alc_config_preset { void (*init_hook)(struct hda_codec *); #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_amp_list *loopbacks; + void (*power_hook)(struct hda_codec *codec, int power); #endif }; @@ -900,6 +904,7 @@ static void setup_preset(struct hda_codec *codec, spec->unsol_event = preset->unsol_event; spec->init_hook = preset->init_hook; #ifdef CONFIG_SND_HDA_POWER_SAVE + spec->power_hook = preset->power_hook; spec->loopback.amplist = preset->loopbacks; #endif @@ -1826,6 +1831,16 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[2] = 0x1b; } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static void alc889_power_eapd(struct hda_codec *codec, int power) +{ + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); +} +#endif + /* * ALC880 3-stack model * @@ -3619,12 +3634,29 @@ static void alc_free(struct hda_codec *codec) snd_hda_detach_beep_device(codec); } +#ifdef CONFIG_SND_HDA_POWER_SAVE +static int alc_suspend(struct hda_codec *codec, pm_message_t state) +{ + struct alc_spec *spec = codec->spec; + if (spec && spec->power_hook) + spec->power_hook(codec, 0); + return 0; +} +#endif + #ifdef SND_HDA_NEEDS_RESUME static int alc_resume(struct hda_codec *codec) { +#ifdef CONFIG_SND_HDA_POWER_SAVE + struct alc_spec *spec = codec->spec; +#endif codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); +#ifdef CONFIG_SND_HDA_POWER_SAVE + if (spec && spec->power_hook) + spec->power_hook(codec, 1); +#endif return 0; } #endif @@ -3641,6 +3673,7 @@ static struct hda_codec_ops alc_patch_ops = { .resume = alc_resume, #endif #ifdef CONFIG_SND_HDA_POWER_SAVE + .suspend = alc_suspend, .check_power_status = alc_check_power_status, #endif }; @@ -9420,6 +9453,9 @@ static struct alc_config_preset alc882_presets[] = { .unsol_event = alc_automute_amp_unsol_event, .setup = alc889_acer_aspire_8930g_setup, .init_hook = alc_automute_amp, +#ifdef CONFIG_SND_HDA_POWER_SAVE + .power_hook = alc889_power_eapd, +#endif }, [ALC888_ACER_ASPIRE_7730G] = { .mixers = { alc883_3ST_6ch_mixer, -- cgit From 40962d7c741de1c21b6ce8516c1d9f8836fb383e Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sat, 19 Dec 2009 18:31:04 +0100 Subject: ALSA: fix incorrect rounding direction in snd_interval_ratnum() The direction of rounding is incorrect in the snd_interval_ratnum() It was detected with following parameters (sb8 driver playing 8kHz stereo file): - num is always 1000000 - requested frequency rate is from 7999 to 7999 (single frequency) The first loop calculates div_down(num, freq->min) which is 125. Thus, a frequency range's minimum value is 1000000 / 125 = 8000 Hz. The second loop calculates div_up(num, freq->max) which is 126 The frequency range's maximum value is 1000000 / 126 = 7936 Hz. The range maximum is lower than the range minimum so the function fails due to empty result range. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- sound/core/pcm_lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 30f410832a25..a27545b23ee9 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -758,7 +758,7 @@ int snd_interval_ratnum(struct snd_interval *i, int diff; if (q == 0) q = 1; - den = div_down(num, q); + den = div_up(num, q); if (den < rats[k].den_min) continue; if (den > rats[k].den_max) @@ -794,7 +794,7 @@ int snd_interval_ratnum(struct snd_interval *i, i->empty = 1; return -EINVAL; } - den = div_up(num, q); + den = div_down(num, q); if (den > rats[k].den_max) continue; if (den < rats[k].den_min) -- cgit From db8cf334f66bdf1ba2b3d2f7128095fc9b7a6e2b Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 20 Dec 2009 20:15:19 +0100 Subject: ALSA: sbawe: fix memory detection Memory amount is increased before a successful write-read sequence is done. Thus, 512 kB of onboard memory is detected on memoryless cards like SB32. Move the increasing of memory counter after successful read is done. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- sound/isa/sb/emu8000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 96678d5d3834..751762f1c59a 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -393,8 +393,6 @@ size_dram(struct snd_emu8000 *emu) while (size < EMU8000_MAX_DRAM) { - size += 512 * 1024; /* increment 512kbytes */ - /* Write a unique data on the test address. * if the address is out of range, the data is written on * 0x200000(=EMU8000_DRAM_OFFSET). Then the id word is @@ -414,7 +412,9 @@ size_dram(struct snd_emu8000 *emu) /*snd_emu8000_read_wait(emu);*/ EMU8000_SMLD_READ(emu); /* discard stale data */ if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2) - break; /* we must have wrapped around */ + break; /* no memory at this address */ + + size += 512 * 1024; /* increment 512kbytes */ snd_emu8000_read_wait(emu); -- cgit From d8d881dd2c814e1500558889d800cf78d11cf898 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 22 Dec 2009 07:52:49 +0100 Subject: ALSA: hda - Fix NULL dereference with enable_beep=0 option Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3d59f8325848..417fb22ae83c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3779,15 +3779,16 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out err = snd_hda_attach_beep_device(codec, nid); if (err < 0) return err; - /* IDT/STAC codecs have linear beep tone parameter */ - codec->beep->linear_tone = 1; - /* if no beep switch is available, make its own one */ - caps = query_amp_caps(codec, nid, HDA_OUTPUT); - if (codec->beep && - !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) { - err = stac92xx_beep_switch_ctl(codec); - if (err < 0) - return err; + if (codec->beep) { + /* IDT/STAC codecs have linear beep tone parameter */ + codec->beep->linear_tone = 1; + /* if no beep switch is available, make its own one */ + caps = query_amp_caps(codec, nid, HDA_OUTPUT); + if (!(caps & AC_AMPCAP_MUTE)) { + err = stac92xx_beep_switch_ctl(codec); + if (err < 0) + return err; + } } } #endif -- cgit From 1a5ba2e9fc7999b8de2a71c7e7b9f58d752c05e4 Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Tue, 22 Dec 2009 07:59:37 +0100 Subject: ALSA: hda - Add support for the new 27 inch IMacs With the attached patch I am able to use the sound on a new IMac 27. What works: *) Internal speakers *) Internal microphone *) Headphone I don't have an external mic or a SPDIF device to test the rest. Signed-off-by: Rafael Avila de Espindola Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_cirrus.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 4b200da1bd18..fe0423c39598 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -66,6 +66,7 @@ struct cs_spec { /* available models */ enum { CS420X_MBP55, + CS420X_IMAC27, CS420X_AUTO, CS420X_MODELS }; @@ -827,7 +828,8 @@ static void cs_automute(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, hp_present ? 0 : PIN_OUT); } - if (spec->board_config == CS420X_MBP55) { + if (spec->board_config == CS420X_MBP55 || + spec->board_config == CS420X_IMAC27) { unsigned int gpio = hp_present ? 0x02 : 0x08; snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, gpio); @@ -1069,12 +1071,14 @@ static int cs_parse_auto_config(struct hda_codec *codec) static const char *cs420x_models[CS420X_MODELS] = { [CS420X_MBP55] = "mbp55", + [CS420X_IMAC27] = "imac27", [CS420X_AUTO] = "auto", }; static struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), + SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), {} /* terminator */ }; @@ -1097,8 +1101,23 @@ static struct cs_pincfg mbp55_pincfgs[] = { {} /* terminator */ }; +static struct cs_pincfg imac27_pincfgs[] = { + { 0x09, 0x012b4050 }, + { 0x0a, 0x90100140 }, + { 0x0b, 0x90100142 }, + { 0x0c, 0x018b3020 }, + { 0x0d, 0x90a00110 }, + { 0x0e, 0x400000f0 }, + { 0x0f, 0x01cbe030 }, + { 0x10, 0x014be060 }, + { 0x12, 0x01ab9070 }, + { 0x15, 0x400000f0 }, + {} /* terminator */ +}; + static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { [CS420X_MBP55] = mbp55_pincfgs, + [CS420X_IMAC27] = imac27_pincfgs, }; static void fix_pincfg(struct hda_codec *codec, int model) @@ -1128,6 +1147,7 @@ static int patch_cs420x(struct hda_codec *codec) fix_pincfg(codec, spec->board_config); switch (spec->board_config) { + case CS420X_IMAC27: case CS420X_MBP55: /* GPIO1 = headphones */ /* GPIO3 = speakers */ -- cgit From 9dc8398bab52931435fce403ce2eaf5822f28e58 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 22 Dec 2009 08:15:01 +0100 Subject: ALSA: hda - Add MSI blacklist A machine with AMD CPU with Nvidia board doesn't work with MSI. Reported-by: Robert J. King Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9b56f937913e..ff8ad46cc50e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2322,6 +2322,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) * white/black-list for enable_msi */ static struct snd_pci_quirk msi_black_list[] __devinitdata = { + SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ {} }; -- cgit From a9605391cfab2bf9a73e51faac5147622f73c6d5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 21 Dec 2009 16:36:10 -0800 Subject: ALSA: sound/core/pcm_timer.c: use lib/gcd.c Make sound/core/pcm_timer.c use lib/gcd.c Signed-off-by: Florian Fainelli Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/core/Kconfig | 1 + sound/core/pcm_timer.c | 17 +---------------- 2 files changed, 2 insertions(+), 16 deletions(-) (limited to 'sound') diff --git a/sound/core/Kconfig b/sound/core/Kconfig index c15682a2f9db..475455c76610 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -5,6 +5,7 @@ config SND_TIMER config SND_PCM tristate select SND_TIMER + select GCD config SND_HWDEP tristate diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c index ca8068b63d6c..b01d9481d632 100644 --- a/sound/core/pcm_timer.c +++ b/sound/core/pcm_timer.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -28,22 +29,6 @@ * Timer functions */ -/* Greatest common divisor */ -static unsigned long gcd(unsigned long a, unsigned long b) -{ - unsigned long r; - if (a < b) { - r = a; - a = b; - b = r; - } - while ((r = a % b) != 0) { - a = b; - b = r; - } - return b; -} - void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) { unsigned long rate, mult, fsize, l, post; -- cgit From 75d1aeb9d6899b10420d10284e8ea894b2794224 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 22 Dec 2009 11:56:32 +0100 Subject: ALSA: hda - Add Bass Speaker switch for HP dv7 The bass speaker is controlled via GPIO5. Tested-by: Wael Nasreddine Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 0bafea9d5106..a4526d008042 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5402,6 +5402,54 @@ static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, return 0; } +/* HP dv7 bass switch - GPIO5 */ +#define stac_hp_bass_gpio_info snd_ctl_boolean_mono_info +static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20); + return 0; +} + +static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int gpio_data; + + gpio_data = (spec->gpio_data & ~0x20) | + (ucontrol->value.integer.value[0] ? 0x20 : 0); + if (gpio_data == spec->gpio_data) + return 0; + spec->gpio_data = gpio_data; + stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); + return 1; +} + +static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = stac_hp_bass_gpio_info, + .get = stac_hp_bass_gpio_get, + .put = stac_hp_bass_gpio_put, +}; + +static int stac_add_hp_bass_switch(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + + if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl, + "Bass Speaker Playback Switch", 0)) + return -ENOMEM; + + spec->gpio_mask |= 0x20; + spec->gpio_dir |= 0x20; + spec->gpio_data |= 0x20; + return 0; +} + static int patch_stac92hd71bxx(struct hda_codec *codec) { struct sigmatel_spec *spec; @@ -5642,6 +5690,15 @@ again: return err; } + /* enable bass on HP dv7 */ + if (spec->board_config == STAC_HP_DV5) { + unsigned int cap; + cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); + cap &= AC_GPIO_IO_COUNT; + if (cap >= 6) + stac_add_hp_bass_switch(codec); + } + codec->proc_widget_hook = stac92hd7x_proc_hook; return 0; -- cgit From b6aa179334743c6152bd63f1fa368d6db3720db9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 16 Dec 2009 17:10:09 +0100 Subject: ASoC: sh: FSI:: don't check platform_get_irq's return value against zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit platform_get_irq returns -ENXIO on failure, so !irq was probably always true. Better use (int)irq <= 0. Note that a return value of zero is still handled as error even though this could mean irq0. This is a followup to 305b3228f9ff4d59f49e6d34a7034d44ee8ce2f0 that changed the return value of platform_get_irq from 0 to -ENXIO on error. Signed-off-by: Uwe Kleine-König Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9c49c11c43ce..42813b808389 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -876,7 +876,7 @@ static int fsi_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!res || !irq) { + if (!res || (int)irq <= 0) { dev_err(&pdev->dev, "Not enough FSI platform resources.\n"); ret = -ENODEV; goto exit; -- cgit From 1628af5adf64cc2960bce81009f119de822f876e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 22 Dec 2009 09:26:10 +0100 Subject: ASoC: add missing parameter to mx27vis_hifi_hw_free() Commit 2ccafed4 added an extra parameter to the DAI .set_pll() method, but it missed this call in sound/soc/imx/mx27vis_wm8974.c. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/mx27vis_wm8974.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c index 0267d2d91685..07d2a248438c 100644 --- a/sound/soc/imx/mx27vis_wm8974.c +++ b/sound/soc/imx/mx27vis_wm8974.c @@ -180,7 +180,8 @@ static int mx27vis_hifi_hw_free(struct snd_pcm_substream *substream) struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; /* disable the PLL */ - return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 0, 0); + return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, IGNORED_ARG, + 0, 0); } /* -- cgit From 21949f00a022e090a7e8bc9a01dfca88273c6146 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 23 Dec 2009 08:31:59 +0100 Subject: ALSA: hda - Fix NID association for capture mixers Fix the wrong implementation of NID <-> kctl mapping for capture mixers introduced by the ocmmit 5b0cb1d850c26893b1468b3a519433a1b7a176be. So far, the driver returns an error at probe. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 26 -------------------------- sound/pci/hda/hda_local.h | 2 -- sound/pci/hda/patch_analog.c | 3 +-- sound/pci/hda/patch_cirrus.c | 12 ++++++++---- sound/pci/hda/patch_cmedia.c | 3 +-- sound/pci/hda/patch_realtek.c | 3 +-- sound/pci/hda/patch_via.c | 3 +-- 7 files changed, 12 insertions(+), 40 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c848ec0f085e..29c90d748c91 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3537,32 +3537,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) } EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); -/** - * snd_hda_add_nids - assign nids to controls from the array - * @codec: the HDA codec - * @kctl: struct snd_kcontrol - * @index: index to kctl - * @nids: the array of hda_nid_t - * @size: count of hda_nid_t items - * - * This helper function assigns NIDs in the given array to a control element. - * - * Returns 0 if successful, or a negative error code. - */ -int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl, - unsigned int index, hda_nid_t *nids, unsigned int size) -{ - int err; - - for ( ; size > 0; size--, nids++) { - err = snd_hda_add_nid(codec, kctl, index, *nids); - if (err < 0) - return err; - } - return 0; -} -EXPORT_SYMBOL_HDA(snd_hda_add_nids); - #ifdef CONFIG_SND_HDA_POWER_SAVE static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state); diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index d505d052972e..7cee364976ff 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -343,8 +343,6 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); -int snd_hda_add_nids(struct hda_codec *codec, struct snd_kcontrol *kctl, - unsigned int index, hda_nid_t *nids, unsigned int size); /* * unsolicited event handler diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 92b72d4f3984..45ee352df329 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -244,8 +244,7 @@ static int ad198x_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->capsrc_nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 093cfbb55e9e..7de782a5b8f4 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -753,6 +753,7 @@ static int build_input(struct hda_codec *codec) spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); for (i = 0; i < 2; i++) { struct snd_kcontrol *kctl; + int n; if (!spec->capture_bind[i]) return -ENOMEM; kctl = snd_ctl_new1(&cs_capture_ctls[i], codec); @@ -762,10 +763,13 @@ static int build_input(struct hda_codec *codec) err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; - err = snd_hda_add_nids(codec, kctl, 0, spec->adc_nid, - spec->num_inputs); - if (err < 0) - return err; + for (n = 0; n < AUTO_PIN_LAST; n++) { + if (!spec->adc_nid[n]) + continue; + err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]); + if (err < 0) + return err; + } } if (spec->num_inputs > 1 && !spec->mic_detect) { diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index cc1c22370a60..ff60908f4554 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -345,8 +345,7 @@ static int cmi9880_build_controls(struct hda_codec *codec) /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->adc_nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e7cdc6a7d61d..a45199014986 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2551,8 +2551,7 @@ static int alc_build_controls(struct hda_codec *codec) hda_nid_t *nids = spec->capsrc_nids; if (!nids) nids = spec->adc_nids; - err = snd_hda_add_nids(codec, kctl, i, nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, nids[i]); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index de4839e46762..9ddc37300f6b 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1907,8 +1907,7 @@ static int via_build_controls(struct hda_codec *codec) /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nids(codec, kctl, i, spec->mux_nids, - spec->input_mux->num_items); + err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); if (err < 0) return err; } -- cgit From f62faedbed546f4e0c1ba204999e7c206059f305 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 23 Dec 2009 09:27:51 +0100 Subject: ALSA: hda - Set mixer name after codec patch Postpone the mixer name setup after the codec patch since the codec patch may change the codec name string in itself. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 9cfdb771928c..950ee5cfcacf 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1086,11 +1086,6 @@ int snd_hda_codec_configure(struct hda_codec *codec) if (err < 0) return err; } - /* audio codec should override the mixer name */ - if (codec->afg || !*codec->bus->card->mixername) - snprintf(codec->bus->card->mixername, - sizeof(codec->bus->card->mixername), - "%s %s", codec->vendor_name, codec->chip_name); if (is_generic_config(codec)) { err = snd_hda_parse_generic_codec(codec); @@ -1109,6 +1104,11 @@ int snd_hda_codec_configure(struct hda_codec *codec) patched: if (!err && codec->patch_ops.unsol_event) err = init_unsol_queue(codec->bus); + /* audio codec should override the mixer name */ + if (!err && (codec->afg || !*codec->bus->card->mixername)) + snprintf(codec->bus->card->mixername, + sizeof(codec->bus->card->mixername), + "%s %s", codec->vendor_name, codec->chip_name); return err; } EXPORT_SYMBOL_HDA(snd_hda_codec_configure); -- cgit From 48e3cbb3f67a27d9c2db075f3d0f700246c40caa Mon Sep 17 00:00:00 2001 From: Eric Millbrandt Date: Tue, 22 Dec 2009 10:13:24 -0500 Subject: ASoC: Do not write to invalid registers on the wm9712. This patch fixes a bug where "virtual" registers were being written to the ac97 bus. This was causing unrelated registers to become corrupted (headphone 0x04, touchscreen 0x78, etc). This patch duplicates protection that was included in the wm9713 driver. Signed-off-by: Eric Millbrandt Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm9712.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 0ac1215dcd9b..e237bf615129 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -463,7 +463,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, { u16 *cache = codec->reg_cache; - soc_ac97_ops.write(codec->ac97, reg, val); + if (reg < 0x7c) + soc_ac97_ops.write(codec->ac97, reg, val); reg = reg >> 1; if (reg < (ARRAY_SIZE(wm9712_reg))) cache[reg] = val; -- cgit From 95e70e87533f9d117d369495ee633cb7d18dc802 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Wed, 23 Dec 2009 17:28:45 +0100 Subject: ALSA: hda - Add STAC9205 PCI_QUIRK for Dell Vostro 1700 Signed-off-by: Anisse Astier Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 417fb22ae83c..eeda7beeb57a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2104,6 +2104,7 @@ static unsigned int ref9205_pin_configs[12] = { 10280204 1028021F 10280228 (Dell Vostro 1500) + 10280229 (Dell Vostro 1700) */ static unsigned int dell_9205_m42_pin_configs[12] = { 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, @@ -2189,6 +2190,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { "Dell Inspiron", STAC_9205_DELL_M44), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, "Dell Vostro 1500", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229, + "Dell Vostro 1700", STAC_9205_DELL_M42), /* Gateway */ SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD), SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), -- cgit From ef18beded8ddbaafdf4914bab209f77e60ae3a18 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 25 Dec 2009 13:14:27 +0800 Subject: ALSA: hda - HDMI sticky stream tag support When we run the following commands in turn (with CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0), speaker-test -Dhw:0,3 -c2 -twav # HDMI speaker-test -Dhw:0,0 -c2 -twav # Analog The second command will produce sound in the analog lineout _as well as_ HDMI sink. The root cause is, device 0 "reuses" the same stream tag that was used by device 3, and the "intelhdmi - sticky stream id" patch leaves the HDMI codec in a functional state. So the HDMI codec happily accepts the audio samples which reuse its stream tag. The proposed solution is to remember the last device each azx_dev was assigned to, and prefer to 1) reuse the azx_dev (and hence the stream tag) the HDMI codec last used 2) or assign a never-used azx_dev for HDMI With this patch and the above two speaker-test commands, HDMI codec will use stream tag 8 and Analog codec will use 5. The stream tag used by HDMI codec won't be reused by others, as long as we don't run out of the 4 playback azx_dev's. The legacy Analog codec will continue to use stream tag 5 because its device id is 0 (this is a bit tricky). Signed-off-by: Wu Fengguang Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ff8ad46cc50e..ec9c348336cc 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -356,6 +356,7 @@ struct azx_dev { */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ + int device; /* last device number assigned to */ unsigned int opened :1; unsigned int running :1; @@ -1441,10 +1442,13 @@ static int __devinit azx_codec_configure(struct azx *chip) */ /* assign a stream for the PCM */ -static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) +static inline struct azx_dev * +azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) { int dev, i, nums; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + struct azx_dev *res = NULL; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dev = chip->playback_index_offset; nums = chip->playback_streams; } else { @@ -1453,10 +1457,15 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream) } for (i = 0; i < nums; i++, dev++) if (!chip->azx_dev[dev].opened) { - chip->azx_dev[dev].opened = 1; - return &chip->azx_dev[dev]; + res = &chip->azx_dev[dev]; + if (res->device == substream->pcm->device) + break; } - return NULL; + if (res) { + res->opened = 1; + res->device = substream->pcm->device; + } + return res; } /* release the assigned stream */ @@ -1505,7 +1514,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) int err; mutex_lock(&chip->open_mutex); - azx_dev = azx_assign_device(chip, substream->stream); + azx_dev = azx_assign_device(chip, substream); if (azx_dev == NULL) { mutex_unlock(&chip->open_mutex); return -EBUSY; -- cgit From 043958e602ac2cbf918c0dab1e4e2a7f9751ebf6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 26 Dec 2009 10:36:12 +0100 Subject: ALSA: hda - Add more hints for GPIO setup of IDT/STAC codecs gpio_led, gpio_led_polarity and gpio_mute are added now. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 247be19e17b8..69dd5a4e52f2 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4184,9 +4184,23 @@ static void stac_store_hints(struct hda_codec *codec) p = snd_hda_get_hint(codec, "eapd_mask"); if (p) spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask; + p = snd_hda_get_hint(codec, "gpio_mute"); + if (p) + spec->gpio_mute = simple_strtoul(p, NULL, 0) & spec->gpio_mask; val = snd_hda_get_bool_hint(codec, "eapd_switch"); if (val >= 0) spec->eapd_switch = val; + p = snd_hda_get_hint(codec, "gpio_led_polarity"); + if (p) + spec->gpio_led_polarity = simple_strtoul(p, NULL, 0); + p = snd_hda_get_hint(codec, "gpio_led"); + if (p) { + spec->gpio_led = simple_strtoul(p, NULL, 0); + spec->gpio_mask |= spec->gpio_led; + spec->gpio_dir |= spec->gpio_led; + if (spec->gpio_led_polarity) + spec->gpio_data |= spec->gpio_led; + } } static int stac92xx_init(struct hda_codec *codec) -- cgit From 92ee6162c48fab24f0676969f0f147fc12f8f21c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 27 Dec 2009 11:18:59 +0100 Subject: ALSA: hda - Add snd_hda_shutup_pins() helper function Add a common helper function for clearing pin controls before suspend. Use the pincfg array instead of looking through all widget tree. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 19 +++++++++++++++++++ sound/pci/hda/hda_codec.h | 1 + sound/pci/hda/patch_sigmatel.c | 12 +----------- 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b3554df740ff..94ae69f20925 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -899,6 +899,25 @@ static void restore_pincfgs(struct hda_codec *codec) } } +/** + * snd_hda_shutup_pins - Shut up all pins + * @codec: the HDA codec + * + * Clear all pin controls to shup up before suspend for avoiding click noise. + * The controls aren't cached so that they can be resumed properly. + */ +void snd_hda_shutup_pins(struct hda_codec *codec) +{ + int i; + for (i = 0; i < codec->init_pins.used; i++) { + struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); + /* use read here for syncing after issuing each verb */ + snd_hda_codec_read(codec, pin->nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + } +} +EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); + static void init_hda_cache(struct hda_cache_rec *cache, unsigned int record_size); static void free_hda_cache(struct hda_cache_rec *cache); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 0d08ad5bd898..11c4aa8ee996 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -898,6 +898,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid, unsigned int cfg); int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, hda_nid_t nid, unsigned int cfg); /* for hwdep */ +void snd_hda_shutup_pins(struct hda_codec *codec); /* * Mixer diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 69dd5a4e52f2..dc1d9f124578 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4385,18 +4385,8 @@ static void stac92xx_free_kctls(struct hda_codec *codec) static void stac92xx_shutup(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - int i; - hda_nid_t nid; - /* reset each pin before powering down DAC/ADC to avoid click noise */ - nid = codec->start_nid; - for (i = 0; i < codec->num_nodes; i++, nid++) { - unsigned int wcaps = get_wcaps(codec, nid); - unsigned int wid_type = get_wcaps_type(wcaps); - if (wid_type == AC_WID_PIN) - snd_hda_codec_read(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0); - } + snd_hda_shutup_pins(codec); if (spec->eapd_mask) stac_gpio_set(codec, spec->gpio_mask, -- cgit From a4e09aa3cf592d9f084ff4ceb216be40c4c265dc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 27 Dec 2009 11:22:24 +0100 Subject: ALSA: hda - Fix click noises at suspend/free with Realtek codecs Call snd_hda_shutup_pins() at suspend and free for avoiding click noises. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6361e6b3c9c5..cd6d139b4fd5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3693,6 +3693,11 @@ static int alc_build_pcms(struct hda_codec *codec) return 0; } +static inline void alc_shutup(struct hda_codec *codec) +{ + snd_hda_shutup_pins(codec); +} + static void alc_free_kctls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -3713,6 +3718,7 @@ static void alc_free(struct hda_codec *codec) if (!spec) return; + alc_shutup(codec); alc_free_kctls(codec); kfree(spec); snd_hda_detach_beep_device(codec); @@ -3722,6 +3728,7 @@ static void alc_free(struct hda_codec *codec) static int alc_suspend(struct hda_codec *codec, pm_message_t state) { struct alc_spec *spec = codec->spec; + alc_shutup(codec); if (spec && spec->power_hook) spec->power_hook(codec, 0); return 0; -- cgit From b82855a0d76ebda1cc14c00040560d77bfa042ce Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 27 Dec 2009 11:24:56 +0100 Subject: ALSA: hda - Add sanity check for storing the user-defined pin configs Check whether the given NID is a pin widget before storing the user-defined pin configs. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 94ae69f20925..d02ea8926e7e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -824,6 +824,9 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, struct hda_pincfg *pin; unsigned int oldcfg; + if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) + return -EINVAL; + oldcfg = snd_hda_codec_get_pincfg(codec, nid); pin = look_up_pincfg(codec, list, nid); if (!pin) { -- cgit From 014c41fce1bd5cec381e70fc6f58fdfc96cdaf69 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 27 Dec 2009 13:53:24 +0100 Subject: ALSA: hda - Use strict_strtoul() Rewrite the codes to use strict_strtoul() instead of simple_strtoul(). Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_hwdep.c | 7 ++++-- sound/pci/hda/patch_sigmatel.c | 48 +++++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 24 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 40ccb419b6e9..b36919c0d363 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -293,8 +293,11 @@ static ssize_t type##_store(struct device *dev, \ { \ struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ struct hda_codec *codec = hwdep->private_data; \ - char *after; \ - codec->type = simple_strtoul(buf, &after, 0); \ + unsigned long val; \ + int err = strict_strtoul(buf, 0, &val); \ + if (err < 0) \ + return err; \ + codec->type = val; \ return count; \ } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index dc1d9f124578..e28c810bc00c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4159,43 +4159,47 @@ static void stac92xx_power_down(struct hda_codec *codec) static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, int enable); +static inline int get_int_hint(struct hda_codec *codec, const char *key, + int *valp) +{ + const char *p; + p = snd_hda_get_hint(codec, key); + if (p) { + unsigned long val; + if (!strict_strtoul(p, 0, &val)) { + *valp = val; + return 1; + } + } + return 0; +} + /* override some hints from the hwdep entry */ static void stac_store_hints(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - const char *p; int val; val = snd_hda_get_bool_hint(codec, "hp_detect"); if (val >= 0) spec->hp_detect = val; - p = snd_hda_get_hint(codec, "gpio_mask"); - if (p) { - spec->gpio_mask = simple_strtoul(p, NULL, 0); + if (get_int_hint(codec, "gpio_mask", &spec->gpio_mask)) { spec->eapd_mask = spec->gpio_dir = spec->gpio_data = spec->gpio_mask; } - p = snd_hda_get_hint(codec, "gpio_dir"); - if (p) - spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; - p = snd_hda_get_hint(codec, "gpio_data"); - if (p) - spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; - p = snd_hda_get_hint(codec, "eapd_mask"); - if (p) - spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask; - p = snd_hda_get_hint(codec, "gpio_mute"); - if (p) - spec->gpio_mute = simple_strtoul(p, NULL, 0) & spec->gpio_mask; + if (get_int_hint(codec, "gpio_dir", &spec->gpio_dir)) + spec->gpio_mask &= spec->gpio_mask; + if (get_int_hint(codec, "gpio_data", &spec->gpio_data)) + spec->gpio_dir &= spec->gpio_mask; + if (get_int_hint(codec, "eapd_mask", &spec->eapd_mask)) + spec->eapd_mask &= spec->gpio_mask; + if (get_int_hint(codec, "gpio_mute", &spec->gpio_mute)) + spec->gpio_mute &= spec->gpio_mask; val = snd_hda_get_bool_hint(codec, "eapd_switch"); if (val >= 0) spec->eapd_switch = val; - p = snd_hda_get_hint(codec, "gpio_led_polarity"); - if (p) - spec->gpio_led_polarity = simple_strtoul(p, NULL, 0); - p = snd_hda_get_hint(codec, "gpio_led"); - if (p) { - spec->gpio_led = simple_strtoul(p, NULL, 0); + get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); + if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; if (spec->gpio_led_polarity) -- cgit From ea52bf260ecbb175339af3178c15788df21b7516 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 27 Dec 2009 18:48:29 -0500 Subject: ALSA: hda: Add powerdown for Analog Devices HDA codecs This patch ports powerdown fixes to AD198x. Currently we only turn off Front and HP for suspend, but this is easily extended for additional nids. Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 45ee352df329..cecd3c108990 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -441,6 +441,11 @@ static int ad198x_build_pcms(struct hda_codec *codec) return 0; } +static inline void ad198x_shutup(struct hda_codec *codec) +{ + snd_hda_shutup_pins(codec); +} + static void ad198x_free_kctls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; @@ -454,6 +459,46 @@ static void ad198x_free_kctls(struct hda_codec *codec) snd_array_free(&spec->kctls); } +static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, + hda_nid_t hp) +{ + struct ad198x_spec *spec = codec->spec; + snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, + !spec->inv_eapd ? 0x00 : 0x02); + snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, + !spec->inv_eapd ? 0x00 : 0x02); +} + +static void ad198x_power_eapd(struct hda_codec *codec) +{ + /* We currently only handle front, HP */ + switch (codec->vendor_id) { + case 0x11d41882: + case 0x11d4882a: + case 0x11d41884: + case 0x11d41984: + case 0x11d41883: + case 0x11d4184a: + case 0x11d4194a: + case 0x11d4194b: + ad198x_power_eapd_write(codec, 0x12, 0x11); + break; + case 0x11d41981: + case 0x11d41983: + ad198x_power_eapd_write(codec, 0x05, 0x06); + break; + case 0x11d41986: + ad198x_power_eapd_write(codec, 0x1b, 0x1a); + break; + case 0x11d41988: + case 0x11d4198b: + case 0x11d4989a: + case 0x11d4989b: + ad198x_power_eapd_write(codec, 0x29, 0x22); + break; + } +} + static void ad198x_free(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; @@ -461,11 +506,29 @@ static void ad198x_free(struct hda_codec *codec) if (!spec) return; + ad198x_shutup(codec); ad198x_free_kctls(codec); kfree(spec); snd_hda_detach_beep_device(codec); } +#ifdef SND_HDA_NEEDS_RESUME +static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) +{ + ad198x_shutup(codec); + ad198x_power_eapd(codec); + return 0; +} + +static int ad198x_resume(struct hda_codec *codec) +{ + ad198x_init(codec); + snd_hda_codec_resume_amp(codec); + snd_hda_codec_resume_cache(codec); + return 0; +} +#endif + static struct hda_codec_ops ad198x_patch_ops = { .build_controls = ad198x_build_controls, .build_pcms = ad198x_build_pcms, @@ -474,6 +537,11 @@ static struct hda_codec_ops ad198x_patch_ops = { #ifdef CONFIG_SND_HDA_POWER_SAVE .check_power_status = ad198x_check_power_status, #endif +#ifdef SND_HDA_NEEDS_RESUME + .suspend = ad198x_suspend, + .resume = ad198x_resume, +#endif + .reboot_notify = ad198x_shutup, }; -- cgit From c97259df3f2e163c72f4d0685c61fb2e026dc989 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 27 Dec 2009 18:52:08 -0500 Subject: ALSA: hda: Refactor powerdown for Realtek HDA codecs This patch converts the alc889 Aspire-specific powerdown to a generic one. Like the previous effort, it currently only handles Front and PCM but can be easily extended to cover other nids. The existing hook for alc889 Aspire-specific remains enabled. Upon further testing, I've added its use for ALC861_AUTO as well. Following patches will enable them for other quirks. Tested-by: Dr. David Alan Gilbert Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 60 +++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 22 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cd6d139b4fd5..141ff446104a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -338,7 +338,7 @@ struct alc_spec { void (*init_hook)(struct hda_codec *codec); void (*unsol_event)(struct hda_codec *codec, unsigned int res); #ifdef CONFIG_SND_HDA_POWER_SAVE - void (*power_hook)(struct hda_codec *codec, int power); + void (*power_hook)(struct hda_codec *codec); #endif /* for pin sensing */ @@ -391,7 +391,7 @@ struct alc_config_preset { void (*init_hook)(struct hda_codec *); #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_amp_list *loopbacks; - void (*power_hook)(struct hda_codec *codec, int power); + void (*power_hook)(struct hda_codec *codec); #endif }; @@ -1835,16 +1835,6 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[2] = 0x1b; } -#ifdef CONFIG_SND_HDA_POWER_SAVE -static void alc889_power_eapd(struct hda_codec *codec, int power) -{ - snd_hda_codec_write(codec, 0x14, 0, - AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); - snd_hda_codec_write(codec, 0x15, 0, - AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0); -} -#endif - /* * ALC880 3-stack model * @@ -3725,12 +3715,40 @@ static void alc_free(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE +static void alc_power_eapd(struct hda_codec *codec) +{ + /* We currently only handle front, HP */ + switch (codec->vendor_id) { + case 0x10ec0260: + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + snd_hda_codec_write(codec, 0x10, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + break; + case 0x10ec0262: + case 0x10ec0267: + case 0x10ec0268: + case 0x10ec0269: + case 0x10ec0272: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0663: + case 0x10ec0862: + case 0x10ec0889: + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + break; + } +} + static int alc_suspend(struct hda_codec *codec, pm_message_t state) { struct alc_spec *spec = codec->spec; alc_shutup(codec); if (spec && spec->power_hook) - spec->power_hook(codec, 0); + spec->power_hook(codec); return 0; } #endif @@ -3738,16 +3756,9 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state) #ifdef SND_HDA_NEEDS_RESUME static int alc_resume(struct hda_codec *codec) { -#ifdef CONFIG_SND_HDA_POWER_SAVE - struct alc_spec *spec = codec->spec; -#endif codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); -#ifdef CONFIG_SND_HDA_POWER_SAVE - if (spec && spec->power_hook) - spec->power_hook(codec, 1); -#endif return 0; } #endif @@ -3767,6 +3778,7 @@ static struct hda_codec_ops alc_patch_ops = { .suspend = alc_suspend, .check_power_status = alc_check_power_status, #endif + .reboot_notify = alc_shutup, }; @@ -9547,7 +9559,7 @@ static struct alc_config_preset alc882_presets[] = { .setup = alc889_acer_aspire_8930g_setup, .init_hook = alc_automute_amp, #ifdef CONFIG_SND_HDA_POWER_SAVE - .power_hook = alc889_power_eapd, + .power_hook = alc_power_eapd, #endif }, [ALC888_ACER_ASPIRE_7730G] = { @@ -14984,8 +14996,12 @@ static int patch_alc861(struct hda_codec *codec) spec->vmaster_nid = 0x03; codec->patch_ops = alc_patch_ops; - if (board_config == ALC861_AUTO) + if (board_config == ALC861_AUTO) { spec->init_hook = alc861_auto_init; +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->power_hook = alc_power_eapd; +#endif + } #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc861_loopbacks; -- cgit