From f511b01c8e747b80635c8b2acd61431abcab4b29 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Aug 2008 16:46:42 +0200 Subject: ALSA: hda - Fix capture source widgets on ALC codecs On some Realtek codecs like ALC882 or ALC883, the capture source is no mux but sum widget. We have to initialize all channels properly for this type, otherwise noises may come in from the unused route. The patch assures to mute unused routes, and unmute the currently selected route. Signed-off-by: Takashi Iwai Tested-by: Daniel J Blueman --- sound/pci/hda/patch_realtek.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index add4e87e0b2..b80e725432f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6437,6 +6437,39 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) } } +static void alc882_auto_init_input_src(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + const struct hda_input_mux *imux = spec->input_mux; + int c; + + for (c = 0; c < spec->num_adc_nids; c++) { + hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; + hda_nid_t nid = spec->capsrc_nids[c]; + int conns, mute, idx, item; + + conns = snd_hda_get_connections(codec, nid, conn_list, + ARRAY_SIZE(conn_list)); + if (conns < 0) + continue; + for (idx = 0; idx < conns; idx++) { + /* if the current connection is the selected one, + * unmute it as default - otherwise mute it + */ + mute = AMP_IN_MUTE(idx); + for (item = 0; item < imux->num_items; item++) { + if (imux->items[item].index == idx) { + if (spec->cur_mux[c] == item) + mute = AMP_IN_UNMUTE(idx); + break; + } + } + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, mute); + } + } +} + /* add mic boosts if needed */ static int alc_auto_add_mic_boost(struct hda_codec *codec) { @@ -6491,6 +6524,7 @@ static void alc882_auto_init(struct hda_codec *codec) alc882_auto_init_multi_out(codec); alc882_auto_init_hp_out(codec); alc882_auto_init_analog_input(codec); + alc882_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -8285,6 +8319,8 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec) } } +#define alc883_auto_init_input_src alc882_auto_init_input_src + /* almost identical with ALC880 parser... */ static int alc883_parse_auto_config(struct hda_codec *codec) { @@ -8315,6 +8351,7 @@ static void alc883_auto_init(struct hda_codec *codec) alc883_auto_init_multi_out(codec); alc883_auto_init_hp_out(codec); alc883_auto_init_analog_input(codec); + alc883_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -9663,6 +9700,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) #define alc262_auto_init_multi_out alc882_auto_init_multi_out #define alc262_auto_init_hp_out alc882_auto_init_hp_out #define alc262_auto_init_analog_input alc882_auto_init_analog_input +#define alc262_auto_init_input_src alc882_auto_init_input_src /* init callback for auto-configuration model -- overriding the default init */ @@ -9672,6 +9710,7 @@ static void alc262_auto_init(struct hda_codec *codec) alc262_auto_init_multi_out(codec); alc262_auto_init_hp_out(codec); alc262_auto_init_analog_input(codec); + alc262_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -13330,6 +13369,8 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) } } +#define alc861vd_auto_init_input_src alc882_auto_init_input_src + #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) @@ -13512,6 +13553,7 @@ static void alc861vd_auto_init(struct hda_codec *codec) alc861vd_auto_init_multi_out(codec); alc861vd_auto_init_hp_out(codec); alc861vd_auto_init_analog_input(codec); + alc861vd_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } @@ -14677,6 +14719,8 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) } } +#define alc662_auto_init_input_src alc882_auto_init_input_src + static int alc662_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -14733,6 +14777,7 @@ static void alc662_auto_init(struct hda_codec *codec) alc662_auto_init_multi_out(codec); alc662_auto_init_hp_out(codec); alc662_auto_init_analog_input(codec); + alc662_auto_init_input_src(codec); if (spec->unsol_event) alc_sku_automute(codec); } -- cgit v1.2.3 From 320dcc30f498e0a8b282b14cf0feed1897ea3b34 Mon Sep 17 00:00:00 2001 From: Peer Chen Date: Wed, 20 Aug 2008 16:43:24 -0700 Subject: ALSA: hda_intel: enable snoop for nvidia HDA controller Enable the snoop for nvidia hda controller to avoid data coherence issue. Signed-off-by: Peer Chen Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a73d6ca0a90..1c53e337ecb 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -278,6 +278,9 @@ enum { /* Defines for Nvidia HDA support */ #define NVIDIA_HDA_TRANSREG_ADDR 0x4e #define NVIDIA_HDA_ENABLE_COHBITS 0x0f +#define NVIDIA_HDA_ISTRM_COH 0x4d +#define NVIDIA_HDA_OSTRM_COH 0x4c +#define NVIDIA_HDA_ENABLE_COHBIT 0x01 /* Defines for Intel SCH HDA snoop control */ #define INTEL_SCH_HDA_DEVC 0x78 @@ -900,6 +903,12 @@ static void azx_init_pci(struct azx *chip) update_pci_byte(chip->pci, NVIDIA_HDA_TRANSREG_ADDR, 0x0f, NVIDIA_HDA_ENABLE_COHBITS); + update_pci_byte(chip->pci, + NVIDIA_HDA_ISTRM_COH, + 0x01, NVIDIA_HDA_ENABLE_COHBIT); + update_pci_byte(chip->pci, + NVIDIA_HDA_OSTRM_COH, + 0x01, NVIDIA_HDA_ENABLE_COHBIT); break; case AZX_DRIVER_SCH: pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); -- cgit v1.2.3 From 1082c7487cbe5a40755ba9e33552b6ecbf419bf2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Aug 2008 15:24:22 +0200 Subject: ALSA: hda - Fix call of alc888_coef_init() Using init_hook to call alc888_coef_init() is problematic for configurations that already set another init_hook. Better to put it in alc_init() as is (although it looks a bit hackish). Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b80e725432f..909f1c101c9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -952,7 +952,7 @@ do_sku: tmp | 0x2010); break; case 0x10ec0888: - alc888_coef_init(codec); + /*alc888_coef_init(codec);*/ /* called in alc_init() */ break; case 0x10ec0267: case 0x10ec0268: @@ -2439,6 +2439,8 @@ static int alc_init(struct hda_codec *codec) unsigned int i; alc_fix_pll(codec); + if (codec->vendor_id == 0x10ec0888) + alc888_coef_init(codec); for (i = 0; i < spec->num_init_verbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); @@ -8426,8 +8428,6 @@ static int patch_alc883(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC883_AUTO) spec->init_hook = alc883_auto_init; - else if (codec->vendor_id == 0x10ec0888) - spec->init_hook = alc888_coef_init; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) -- cgit v1.2.3 From 7a8fc9b248e77a4eab0613acf30a6811799786b3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 17 Aug 2008 17:36:59 +0300 Subject: removed unused #include 's This patch lets the files using linux/version.h match the files that #include it. Signed-off-by: Adrian Bunk Signed-off-by: Linus Torvalds --- sound/mips/au1x00.c | 1 - sound/soc/at91/eti_b1_wm8731.c | 1 - sound/soc/codecs/wm8753.c | 1 - sound/soc/codecs/wm9712.c | 1 - 4 files changed, 4 deletions(-) (limited to 'sound') diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index ee0741f9eb5..fbef38a9604 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index b081e83766b..b81d6b2cfa1 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8604809f0c3..dc7b18fd278 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 1fb7f9a7aec..2f1c91b1d55 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3 From c5d44423d55e3abca7b1d544af9e4c97ec203999 Mon Sep 17 00:00:00 2001 From: Travis Place Date: Mon, 25 Aug 2008 08:11:50 +0200 Subject: ALSA: CA0106 on MSI K8N Diamond PLUS Motherboard Correct a previous patch for the ca0106 onboard the MSI K8N Diamond PLUS motherboard. Confirmed to have Line/Mic/Aux working for input, and sound output working as expected. Signed-off-by: Travis Place Signed-off-by: Takashi Iwai --- sound/pci/ca0106/ca0106_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 2f8b28add27..03a274becae 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -249,11 +249,12 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .name = "MSI K8N Diamond MB [SB0438]", .gpio_type = 2, .i2c_adc = 1 } , - /* Another MSI K8N Diamond MB, which has apprently a different SSID */ + /* MSI K8N Diamond PLUS MB */ { .serial = 0x10091102, .name = "MSI K8N Diamond MB", .gpio_type = 2, - .i2c_adc = 1 } , + .i2c_adc = 1, + .spi_dac = 2 } /* Shuttle XPC SD31P which has an onboard Creative Labs * Sound Blaster Live! 24-bit EAX * high-definition 7.1 audio processor". -- cgit v1.2.3 From 3051e41ab7daaa59d4564f20b25dcb8c03f35f2b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 25 Aug 2008 11:49:20 +0100 Subject: ALSA: ASoC: Fix double free and memory leak in many codec drivers Many SoC audio codec drivers have improper freeing of memory in error paths. * codec is allocated in the platform device probe function, but is not freed there in case of error. Instead it is freed in the i2c device probe function's error path. However the success or failure of both functions is not linked, so this could result in a double free (if the platform device is successfully probed, the i2c device probing fails and then the platform driver is unregistered.) * codec->private_data is allocated in many platform device probe functions but not freed in their error paths. This patch hopefully solves all these problems. Signed-off-by: Jean Delvare Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/codecs/ak4535.c | 11 +++++++---- sound/soc/codecs/tlv320aic3x.c | 11 +++++++---- sound/soc/codecs/uda1380.c | 9 +++++---- sound/soc/codecs/wm8510.c | 9 +++++---- sound/soc/codecs/wm8731.c | 11 +++++++---- sound/soc/codecs/wm8750.c | 10 ++++++---- sound/soc/codecs/wm8753.c | 11 +++++++---- sound/soc/codecs/wm8990.c | 11 +++++++---- 8 files changed, 51 insertions(+), 32 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index b26003c4f3e..7da9f467b7b 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -562,10 +562,9 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -583,7 +582,6 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -660,6 +658,11 @@ static int ak4535_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index b1dce5f459d..5f9abb19943 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1199,10 +1199,9 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -1221,7 +1220,6 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -1302,6 +1300,11 @@ static int aic3x_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index a52d6d9e007..807318fbdc8 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -729,10 +729,9 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -750,7 +749,6 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -817,6 +815,9 @@ static int uda1380_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) + kfree(codec); return ret; } diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 67325fd9544..3d998e6a997 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -693,10 +693,9 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -714,7 +713,6 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -782,6 +780,9 @@ static int wm8510_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) + kfree(codec); return ret; } diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 369d39c3f74..9402fcaf04f 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -596,10 +596,9 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -617,7 +616,6 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -693,6 +691,11 @@ static int wm8731_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index c6a8edf302a..dd1f55404b2 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -869,10 +869,9 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -890,7 +889,6 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -966,6 +964,10 @@ static int wm8750_probe(struct platform_device *pdev) /* Add other interfaces here */ #endif + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8604809f0c3..35bf1c36987 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1661,10 +1661,9 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (!i2c) { - kfree(codec); + if (!i2c) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -1683,7 +1682,6 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -1760,6 +1758,11 @@ static int wm8753_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index e44153fa38d..dd995ef448b 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1500,10 +1500,9 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind) client_template.addr = addr; i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) { - kfree(codec); + if (i2c == NULL) return -ENOMEM; - } + i2c_set_clientdata(i2c, codec); codec->control_data = i2c; @@ -1521,7 +1520,6 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind) return ret; err: - kfree(codec); kfree(i2c); return ret; } @@ -1595,6 +1593,11 @@ static int wm8990_probe(struct platform_device *pdev) #else /* Add other interfaces here */ #endif + + if (ret != 0) { + kfree(codec->private_data); + kfree(codec); + } return ret; } -- cgit v1.2.3 From e5778ec91e823b97262f045814d34d0abde689c0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 26 Aug 2008 10:33:32 +1000 Subject: ALSA: fix for CA0106 on MSI K8N Diamond PLUS Motherboard Signed-off-by: Stephen Rothwell Signed-off-by: Linus Torvalds --- sound/pci/ca0106/ca0106_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 03a274becae..6abe8a3bd36 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -254,7 +254,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .name = "MSI K8N Diamond MB", .gpio_type = 2, .i2c_adc = 1, - .spi_dac = 2 } + .spi_dac = 2 }, /* Shuttle XPC SD31P which has an onboard Creative Labs * Sound Blaster Live! 24-bit EAX * high-definition 7.1 audio processor". -- cgit v1.2.3 From 3d839e5b87a70effc629c1cdbf77d837ef141919 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 26 Aug 2008 11:06:26 +0200 Subject: ALSA: oxygen: prevent muting of nonexistent AC97 controls The Xonar DX does not have CD Capture controls, so we have to check that a control actually exists before muting it. Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_mixer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 6facac5aed9..05eb8994c14 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -512,9 +512,12 @@ static int ac97_switch_get(struct snd_kcontrol *ctl, static void mute_ac97_ctl(struct oxygen *chip, unsigned int control) { - unsigned int priv_idx = chip->controls[control]->private_value & 0xff; + unsigned int priv_idx; u16 value; + if (!chip->controls[control]) + return; + priv_idx = chip->controls[control]->private_value & 0xff; value = oxygen_read_ac97(chip, 0, priv_idx); if (!(value & 0x8000)) { oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000); -- cgit v1.2.3 From e784539fe81490a982a013621d39a60c4fce427e Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 26 Aug 2008 13:32:57 +0300 Subject: ALSA: ASoC: Fix error paths in N810 machine driver init and release clocks at exit Thanks to Felipe Balbi by noticing that if clk_get to sys_clkout2_src fails, then n810_snd_device is never released. Add also sys_clkout2_src release into error path, error code return and release the clocks at exit. Signed-off-by: Jarkko Nikula Acked-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/omap/n810.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 7694621ec40..87d0ed01f65 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -329,12 +329,14 @@ static int __init n810_soc_init(void) sys_clkout2_src = clk_get(dev, "sys_clkout2_src"); if (IS_ERR(sys_clkout2_src)) { dev_err(dev, "Could not get sys_clkout2_src clock\n"); - return -ENODEV; + err = PTR_ERR(sys_clkout2_src); + goto err2; } sys_clkout2 = clk_get(dev, "sys_clkout2"); if (IS_ERR(sys_clkout2)) { dev_err(dev, "Could not get sys_clkout2\n"); - goto err1; + err = PTR_ERR(sys_clkout2); + goto err3; } /* * Configure 12 MHz output on SYS_CLKOUT2. Therefore we must use @@ -343,7 +345,8 @@ static int __init n810_soc_init(void) func96m_clk = clk_get(dev, "func_96m_ck"); if (IS_ERR(func96m_clk)) { dev_err(dev, "Could not get func 96M clock\n"); - goto err2; + err = PTR_ERR(func96m_clk); + goto err4; } clk_set_parent(sys_clkout2_src, func96m_clk); clk_set_rate(sys_clkout2, 12000000); @@ -356,20 +359,25 @@ static int __init n810_soc_init(void) gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); return 0; -err2: +err4: clk_put(sys_clkout2); +err3: + clk_put(sys_clkout2_src); +err2: platform_device_del(n810_snd_device); err1: platform_device_put(n810_snd_device); return err; - } static void __exit n810_soc_exit(void) { gpio_free(N810_SPEAKER_AMP_GPIO); gpio_free(N810_HEADSET_AMP_GPIO); + clk_put(sys_clkout2_src); + clk_put(sys_clkout2); + clk_put(func96m_clk); platform_device_unregister(n810_snd_device); } -- cgit v1.2.3 From 93a1a5eb70be5cc14990b97ef2460212e32658dc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 27 Aug 2008 07:56:43 +0200 Subject: Revert "ALSA: hda - Added model selection for iMac 24"" This reverts commit 3e0e469fa216ec70c93b1593821b759d19ee2e6b. The patch introduced a wrong detection of other intel Macs with ALC88* codec because they share the same PCI SSID (but have different codec subsystem-IDs). See http://lkml.org/lkml/2008/8/24/143 Reported-and-tested-by: Guillaume Chazarain Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 909f1c101c9..d6ec9eef291 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6197,7 +6197,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), - SND_PCI_QUIRK(0x106b, 0x00a0, "Apple iMac 24''", ALC885_IMAC24), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), -- cgit v1.2.3 From df91bc23dcb052ff2da71b3482bf3c5fbf4b8a53 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 29 Aug 2008 13:08:34 +0200 Subject: ALSA: oxygen: fix distorted output on AK4396-based cards When changing the sample rate, the CMI8788's master clock output becomes unstable for a short time. The AK4396 needs the master clock to do SPI writes, so writing to an AK4396 control register directly after a sample rate change will garble the value. In our case, this leads to the DACs being misconfigured to I2S sample format, which results in a wrong output level and horrible distortions on samples louder than -6 dB. To fix this, we need to wait until the new master clock signal has become stable before doing SPI writes. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/hifier.c | 4 ++++ sound/pci/oxygen/oxygen.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'sound') diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 7442460583d..dad393ae040 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include @@ -107,6 +108,9 @@ static void set_ak4396_params(struct oxygen *chip, else value |= AK4396_DFS_QUAD; data->ak4396_ctl2 = value; + + msleep(1); /* wait for the new MCLK to become stable */ + ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB); ak4396_write(chip, AK4396_CONTROL_2, value); ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 7c8ae31eb46..c5829d30ef8 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -28,6 +28,7 @@ * GPIO 1 -> DFS1 of AK5385 */ +#include #include #include #include @@ -213,6 +214,9 @@ static void set_ak4396_params(struct oxygen *chip, else value |= AK4396_DFS_QUAD; data->ak4396_ctl2 = value; + + msleep(1); /* wait for the new MCLK to become stable */ + for (i = 0; i < 4; ++i) { ak4396_write(chip, i, AK4396_CONTROL_1, AK4396_DIF_24_MSB); -- cgit v1.2.3 From 20f5f95ded9cdab62c26efb146967a75e12533ec Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Mon, 1 Sep 2008 08:17:56 +0200 Subject: ALSA: hda: Distortion fix for dell_m6_core_init Added the EQ distortion fix to the dell_m6_core_init. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7fdafcb0015..ad994fcab72 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -560,8 +560,9 @@ static struct hda_verb dell_eq_core_init[] = { }; static struct hda_verb dell_m6_core_init[] = { - /* set master volume and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* set master volume to max value without distortion + * and direct control */ + { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, /* setup audio connections */ { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, -- cgit v1.2.3 From 6e5ea7015c62b672020ee0a7c2764942fe63fa25 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 31 Aug 2008 00:45:02 +0400 Subject: ALSA: ASoC: fix pxa2xx-i2s clk_get call pxa2xx-i2s: probe actual device and use it for clk_get call thus fixing error during startup hook Signed-off-by: Dmitry Baryshkov Acked-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/pxa/pxa2xx-i2s.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 8548818eea0..c796b188277 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,6 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - clk_i2s = clk_get(NULL, "I2SCLK"); if (IS_ERR(clk_i2s)) return PTR_ERR(clk_i2s); @@ -152,6 +152,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm); pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk); + BUG_ON(IS_ERR(clk_i2s)); clk_enable(clk_i2s); pxa_i2s_wait(); @@ -317,6 +318,43 @@ struct snd_soc_dai pxa_i2s_dai = { EXPORT_SYMBOL_GPL(pxa_i2s_dai); +static int pxa2xx_i2s_probe(struct platform_device *dev) +{ + clk_i2s = clk_get(&dev->dev, "I2SCLK"); + return IS_ERR(clk_i2s) ? PTR_ERR(clk_i2s) : 0; +} + +static int __devexit pxa2xx_i2s_remove(struct platform_device *dev) +{ + clk_put(clk_i2s); + clk_i2s = ERR_PTR(-ENOENT); + return 0; +} + +static struct platform_driver pxa2xx_i2s_driver = { + .probe = pxa2xx_i2s_probe, + .remove = __devexit_p(pxa2xx_i2s_remove), + + .driver = { + .name = "pxa2xx-i2s", + .owner = THIS_MODULE, + }, +}; + +static int __init pxa2xx_i2s_init(void) +{ + clk_i2s = ERR_PTR(-ENOENT); + return platform_driver_register(&pxa2xx_i2s_driver); +} + +static void __exit pxa2xx_i2s_exit(void) +{ + platform_driver_unregister(&pxa2xx_i2s_driver); +} + +module_init(pxa2xx_i2s_init); +module_exit(pxa2xx_i2s_exit); + /* Module information */ MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); -- cgit v1.2.3 From 24fb9173815045ab3f85a670d7df8af5af6ff3be Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 2 Sep 2008 14:48:20 +0200 Subject: ALSA: hda - Fix ALC663 auto-probe Fix the wrong DAC assignment for NID 0x17 mono-pin on ALC663. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d6ec9eef291..635748b122e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14066,6 +14066,13 @@ static struct hda_verb alc662_auto_init_verbs[] = { { } }; +/* additional verbs for ALC663 */ +static struct hda_verb alc663_auto_init_verbs[] = { + {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + { } +}; + static struct hda_verb alc663_m51va_init_verbs[] = { {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -14594,6 +14601,14 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, if (!pin) return 0; + if (pin == 0x17) { + /* ALC663 has a mono output pin on 0x17 */ + sprintf(name, "%s Playback Switch", pfx); + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT)); + return err; + } + if (alc880_is_fixed_pin(pin)) { nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); /* printk("DAC nid=%x\n",nid); */ @@ -14764,6 +14779,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux; spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; + if (codec->vendor_id == 0x10ec0663) + spec->init_verbs[spec->num_init_verbs++] = + alc663_auto_init_verbs; spec->mixers[spec->num_mixers] = alc662_capture_mixer; spec->num_mixers++; return 1; -- cgit v1.2.3 From ee979a143cfd999adea8a9e272649a3cd9ec84bc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 2 Sep 2008 15:42:20 +0200 Subject: ALSA: hda - Add mic-boost controls to ALC662/663 auto configuration Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 635748b122e..66025161bd6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14782,6 +14782,11 @@ static int alc662_parse_auto_config(struct hda_codec *codec) if (codec->vendor_id == 0x10ec0663) spec->init_verbs[spec->num_init_verbs++] = alc663_auto_init_verbs; + + err = alc_auto_add_mic_boost(codec); + if (err < 0) + return err; + spec->mixers[spec->num_mixers] = alc662_capture_mixer; spec->num_mixers++; return 1; -- cgit v1.2.3 From 8a656496b21efd95fd55b66e0601c5ad41f9b156 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 6 Sep 2008 11:43:41 +0200 Subject: Fix CONFIG_AC97_BUS dependency CONFIG_AC97_BUS is used from both sound and ucb1400 drivers. The recent change in Kconfig introduced the exclusive dependency on CONFIG_SOUND, and disabled the ucb1400 build without sound. This patch makes CONFIG_AC97_BUS independent. Signed-off-by: Takashi Iwai Tested-by: Randy Dunlap --- sound/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/Kconfig b/sound/Kconfig index a37bee094eb..8ebf512ced6 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -91,6 +91,9 @@ endif # SOUND_PRIME endif # !M68K +endif # SOUND + +# AC97_BUS is used from both sound and ucb1400 config AC97_BUS tristate help @@ -99,4 +102,3 @@ config AC97_BUS sound although they're sharing the AC97 bus. Concerned drivers should "select" this. -endif # SOUND -- cgit v1.2.3