From 45c1de8e20cec40b6846def0aeca09cb1bfb839b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 2 Nov 2010 17:08:37 +0100 Subject: ALSA: oxygen: merge HiFier driver into snd-oxygen The snd-hifier driver contains more duplicated code than model-specific code, so it does not make sense for it to be a separate driver. Handling the two-channel output restriction can be easily done in the generic driver. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/Kconfig | 15 +-- sound/pci/oxygen/Makefile | 2 - sound/pci/oxygen/hifier.c | 239 ---------------------------------------------- sound/pci/oxygen/oxygen.c | 43 ++++++++- 4 files changed, 40 insertions(+), 259 deletions(-) delete mode 100644 sound/pci/oxygen/hifier.c (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 12e34653b8a8..dfe406de9935 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -209,7 +209,7 @@ config SND_OXYGEN_LIB tristate config SND_OXYGEN - tristate "C-Media 8788 (Oxygen)" + tristate "C-Media 8787, 8788 (Oxygen)" select SND_OXYGEN_LIB select SND_PCM select SND_MPU401_UART @@ -224,6 +224,7 @@ config SND_OXYGEN * HT-Omega Claro halo (XT) * Razer Barracuda AC-1 * Sondigo Inferno + * TempoTec/MediaTek HiFier Fantasia To compile this driver as a module, choose M here: the module will be called snd-oxygen. @@ -578,18 +579,6 @@ config SND_HDSPM To compile this driver as a module, choose M here: the module will be called snd-hdspm. -config SND_HIFIER - tristate "TempoTec HiFier Fantasia" - select SND_OXYGEN_LIB - select SND_PCM - select SND_MPU401_UART - help - Say Y here to include support for the MediaTek/TempoTec HiFier - Fantasia sound card. - - To compile this driver as a module, choose M here: the module - will be called snd-hifier. - config SND_ICE1712 tristate "ICEnsemble ICE1712 (Envy24)" select SND_MPU401_UART diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile index acd8f15f7bff..bd67c0d7779c 100644 --- a/sound/pci/oxygen/Makefile +++ b/sound/pci/oxygen/Makefile @@ -1,10 +1,8 @@ snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o -snd-hifier-objs := hifier.o snd-oxygen-objs := oxygen.o snd-virtuoso-objs := virtuoso.o xonar_lib.o \ xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o -obj-$(CONFIG_SND_HIFIER) += snd-hifier.o obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c deleted file mode 100644 index 5a87d683691f..000000000000 --- a/sound/pci/oxygen/hifier.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia - * - * Copyright (c) Clemens Ladisch - * - * - * This driver is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2. - * - * This driver is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this driver; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * CMI8788: - * - * SPI 0 -> AK4396 - */ - -#include -#include -#include -#include -#include -#include -#include -#include "oxygen.h" -#include "ak4396.h" - -MODULE_AUTHOR("Clemens Ladisch "); -MODULE_DESCRIPTION("TempoTec HiFier driver"); -MODULE_LICENSE("GPL v2"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "card index"); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string"); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "enable card"); - -static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = { - { OXYGEN_PCI_SUBID(0x14c3, 0x1710) }, - { OXYGEN_PCI_SUBID(0x14c3, 0x1711) }, - { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, - { } -}; -MODULE_DEVICE_TABLE(pci, hifier_ids); - -struct hifier_data { - u8 ak4396_regs[5]; -}; - -static void ak4396_write(struct oxygen *chip, u8 reg, u8 value) -{ - struct hifier_data *data = chip->model_data; - - oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | - OXYGEN_SPI_DATA_LENGTH_2 | - OXYGEN_SPI_CLOCK_160 | - (0 << OXYGEN_SPI_CODEC_SHIFT) | - OXYGEN_SPI_CEN_LATCH_CLOCK_HI, - AK4396_WRITE | (reg << 8) | value); - data->ak4396_regs[reg] = value; -} - -static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value) -{ - struct hifier_data *data = chip->model_data; - - if (value != data->ak4396_regs[reg]) - ak4396_write(chip, reg, value); -} - -static void hifier_registers_init(struct oxygen *chip) -{ - struct hifier_data *data = chip->model_data; - - ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); - ak4396_write(chip, AK4396_CONTROL_2, - data->ak4396_regs[AK4396_CONTROL_2]); - ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); - ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]); - ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); -} - -static void hifier_init(struct oxygen *chip) -{ - struct hifier_data *data = chip->model_data; - - data->ak4396_regs[AK4396_CONTROL_2] = - AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; - hifier_registers_init(chip); - - snd_component_add(chip->card, "AK4396"); - snd_component_add(chip->card, "CS5340"); -} - -static void hifier_cleanup(struct oxygen *chip) -{ -} - -static void hifier_resume(struct oxygen *chip) -{ - hifier_registers_init(chip); -} - -static void set_ak4396_params(struct oxygen *chip, - struct snd_pcm_hw_params *params) -{ - struct hifier_data *data = chip->model_data; - u8 value; - - value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK; - if (params_rate(params) <= 54000) - value |= AK4396_DFS_NORMAL; - else if (params_rate(params) <= 108000) - value |= AK4396_DFS_DOUBLE; - else - value |= AK4396_DFS_QUAD; - - msleep(1); /* wait for the new MCLK to become stable */ - - if (value != data->ak4396_regs[AK4396_CONTROL_2]) { - 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); - } -} - -static void update_ak4396_volume(struct oxygen *chip) -{ - ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]); - ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]); -} - -static void update_ak4396_mute(struct oxygen *chip) -{ - struct hifier_data *data = chip->model_data; - u8 value; - - value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE; - if (chip->dac_mute) - value |= AK4396_SMUTE; - ak4396_write_cached(chip, AK4396_CONTROL_2, value); -} - -static void set_cs5340_params(struct oxygen *chip, - struct snd_pcm_hw_params *params) -{ -} - -static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); - -static const struct oxygen_model model_hifier = { - .shortname = "C-Media CMI8787", - .longname = "C-Media Oxygen HD Audio", - .chip = "CMI8788", - .init = hifier_init, - .cleanup = hifier_cleanup, - .resume = hifier_resume, - .get_i2s_mclk = oxygen_default_i2s_mclk, - .set_dac_params = set_ak4396_params, - .set_adc_params = set_cs5340_params, - .update_dac_volume = update_ak4396_volume, - .update_dac_mute = update_ak4396_mute, - .dac_tlv = ak4396_db_scale, - .model_data_size = sizeof(struct hifier_data), - .device_config = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1, - .dac_channels = 2, - .dac_volume_min = 0, - .dac_volume_max = 255, - .function_flags = OXYGEN_FUNCTION_SPI, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, -}; - -static int __devinit get_hifier_model(struct oxygen *chip, - const struct pci_device_id *id) -{ - chip->model = model_hifier; - return 0; -} - -static int __devinit hifier_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - int err; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - ++dev; - return -ENOENT; - } - err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE, - hifier_ids, get_hifier_model); - if (err >= 0) - ++dev; - return err; -} - -static struct pci_driver hifier_driver = { - .name = "CMI8787HiFier", - .id_table = hifier_ids, - .probe = hifier_probe, - .remove = __devexit_p(oxygen_pci_remove), -#ifdef CONFIG_PM - .suspend = oxygen_pci_suspend, - .resume = oxygen_pci_resume, -#endif -}; - -static int __init alsa_card_hifier_init(void) -{ - return pci_register_driver(&hifier_driver); -} - -static void __exit alsa_card_hifier_exit(void) -{ - pci_unregister_driver(&hifier_driver); -} - -module_init(alsa_card_hifier_init) -module_exit(alsa_card_hifier_exit) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 98a8eb3c92f7..5e258b26f044 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -70,6 +70,7 @@ enum { MODEL_MERIDIAN, /* AuzenTech X-Meridian */ MODEL_CLARO, /* HT-Omega Claro */ MODEL_CLARO_HALO, /* HT-Omega Claro halo */ + MODEL_HIFIER, /* TempoTec HiFier Fantasia */ }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { @@ -81,6 +82,8 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, + { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, @@ -98,6 +101,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); #define GPIO_CLARO_HP 0x0100 struct generic_data { + unsigned int dacs; u8 ak4396_regs[4][5]; u16 wm8785_regs[3]; }; @@ -148,7 +152,7 @@ static void ak4396_registers_init(struct oxygen *chip) struct generic_data *data = chip->model_data; unsigned int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { ak4396_write(chip, i, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); ak4396_write(chip, i, AK4396_CONTROL_2, @@ -166,6 +170,7 @@ static void ak4396_init(struct oxygen *chip) { struct generic_data *data = chip->model_data; + data->dacs = chip->model.dac_channels / 2; data->ak4396_regs[0][AK4396_CONTROL_2] = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; ak4396_registers_init(chip); @@ -232,6 +237,12 @@ static void claro_halo_init(struct oxygen *chip) claro_enable_hp(chip); } +static void hifier_init(struct oxygen *chip) +{ + ak4396_init(chip); + snd_component_add(chip->card, "CS5340"); +} + static void generic_cleanup(struct oxygen *chip) { } @@ -268,6 +279,11 @@ static void claro_resume(struct oxygen *chip) claro_enable_hp(chip); } +static void stereo_resume(struct oxygen *chip) +{ + ak4396_registers_init(chip); +} + static void set_ak4396_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -286,7 +302,7 @@ static void set_ak4396_params(struct oxygen *chip, msleep(1); /* wait for the new MCLK to become stable */ if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { ak4396_write(chip, i, AK4396_CONTROL_1, AK4396_DIF_24_MSB); ak4396_write(chip, i, AK4396_CONTROL_2, value); @@ -298,9 +314,10 @@ static void set_ak4396_params(struct oxygen *chip, static void update_ak4396_volume(struct oxygen *chip) { + struct generic_data *data = chip->model_data; unsigned int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { ak4396_write_cached(chip, i, AK4396_LCH_ATT, chip->dac_volume[i * 2]); ak4396_write_cached(chip, i, AK4396_RCH_ATT, @@ -317,7 +334,7 @@ static void update_ak4396_mute(struct oxygen *chip) value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; if (chip->dac_mute) value |= AK4396_SMUTE; - for (i = 0; i < 4; ++i) + for (i = 0; i < data->dacs; ++i) ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); } @@ -356,6 +373,10 @@ static void set_ak5385_params(struct oxygen *chip, value, GPIO_AK5385_DFS_MASK); } +static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params) +{ +} + static int rolloff_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { @@ -400,7 +421,7 @@ static int rolloff_put(struct snd_kcontrol *ctl, reg &= ~AK4396_SLOW; changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; if (changed) { - for (i = 0; i < 4; ++i) + for (i = 0; i < data->dacs; ++i) ak4396_write(chip, i, AK4396_CONTROL_2, reg); } mutex_unlock(&chip->mutex); @@ -550,6 +571,18 @@ static int __devinit get_oxygen_model(struct oxygen *chip, CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; break; + case MODEL_HIFIER: + chip->model.shortname = "C-Media CMI8787"; + chip->model.chip = "CMI8787"; + chip->model.init = hifier_init; + chip->model.resume = stereo_resume; + chip->model.mixer_init = generic_mixer_init; + chip->model.set_adc_params = set_no_params; + chip->model.device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_1; + chip->model.dac_channels = 2; + break; } if (id->driver_data == MODEL_MERIDIAN || id->driver_data == MODEL_CLARO_HALO) { -- cgit v1.2.3 From 31f86bacfc9c8f6a3f25fa991c1f373374a9f25b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 2 Nov 2010 17:18:23 +0100 Subject: ALSA: oxygen: add Kuroutoshikou CMI8787-HG2PCI support Add support for the Kuroutoshikou CMI8787-HG2PCI sound card. [replaced non-latin letters in the patch by tiwai] Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/Kconfig | 1 + sound/pci/oxygen/oxygen.c | 19 +++++++++++++++---- sound/pci/oxygen/oxygen_lib.c | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index f1a1787e71e5..fdd388ded62a 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1531,6 +1531,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * Club3D Theatron DTS * HT-Omega Claro (plus) * HT-Omega Claro halo (XT) + * Kuroutoshikou CMI8787-HG2PCI * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec HiFier Fantasia diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index dfe406de9935..f7139d09cbbe 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -222,6 +222,7 @@ config SND_OXYGEN * Club3D Theatron DTS * HT-Omega Claro (plus) * HT-Omega Claro halo (XT) + * Kuroutoshikou CMI8787-HG2PCI * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec/MediaTek HiFier Fantasia diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 5e258b26f044..dd0f3f478999 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -71,6 +71,7 @@ enum { MODEL_CLARO, /* HT-Omega Claro */ MODEL_CLARO_HALO, /* HT-Omega Claro halo */ MODEL_HIFIER, /* TempoTec HiFier Fantasia */ + MODEL_HG2PCI, /* Kuroutoshikou CMI8787-HG2PCI */ }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { @@ -80,7 +81,7 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, - { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, @@ -243,6 +244,11 @@ static void hifier_init(struct oxygen *chip) snd_component_add(chip->card, "CS5340"); } +static void hg2pci_init(struct oxygen *chip) +{ + ak4396_init(chip); +} + static void generic_cleanup(struct oxygen *chip) { } @@ -572,15 +578,20 @@ static int __devinit get_oxygen_model(struct oxygen *chip, CAPTURE_1_FROM_SPDIF; break; case MODEL_HIFIER: + case MODEL_HG2PCI: chip->model.shortname = "C-Media CMI8787"; chip->model.chip = "CMI8787"; - chip->model.init = hifier_init; + if (id->driver_data == MODEL_HIFIER) + chip->model.init = hifier_init; + else + chip->model.init = hg2pci_init; chip->model.resume = stereo_resume; chip->model.mixer_init = generic_mixer_init; chip->model.set_adc_params = set_no_params; chip->model.device_config = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1; + PLAYBACK_1_TO_SPDIF; + if (id->driver_data == MODEL_HIFIER) + chip->model.device_config |= CAPTURE_0_FROM_I2S_1; chip->model.dac_channels = 2; break; } diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index e5ebe56fb0c5..2e6579962217 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -262,7 +262,7 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[]) */ subdevice = oxygen_read_eeprom(chip, 2); /* use default ID if EEPROM is missing */ - if (subdevice == 0xffff) + if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff) subdevice = 0x8788; /* * We use only the subsystem device ID for searching because it is -- cgit v1.2.3 From 18f24839f18f1934c1e37e86ce8f3fecbb0328c9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 3 Nov 2010 11:36:33 +0100 Subject: ALSA: oxygen: reorganize PCI IDs Sort the PCI IDs so that they make logical sense. Also move the card name comments into this list because the model symbols should be (more) self-explanationary. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index dd0f3f478999..13f39e58f3de 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -66,28 +66,34 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "enable card"); enum { - MODEL_CMEDIA_REF, /* C-Media's reference design */ - MODEL_MERIDIAN, /* AuzenTech X-Meridian */ - MODEL_CLARO, /* HT-Omega Claro */ - MODEL_CLARO_HALO, /* HT-Omega Claro halo */ - MODEL_HIFIER, /* TempoTec HiFier Fantasia */ - MODEL_HG2PCI, /* Kuroutoshikou CMI8787-HG2PCI */ + MODEL_CMEDIA_REF, + MODEL_MERIDIAN, + MODEL_CLARO, + MODEL_CLARO_HALO, + MODEL_HIFIER, + MODEL_HG2PCI, }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { + /* C-Media's reference design */ { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, - { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, + /* Kuroutoshikou CMI8787-HG2PCI */ + { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, + /* TempoTec HiFier Fantasia */ { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, - { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, + /* AuzenTech X-Meridian */ { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, + /* HT-Omega Claro */ { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, + /* HT-Omega Claro halo */ { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO }, { } }; -- cgit v1.2.3 From 2146dcfd15ad55cfdd18b45e1e6601d6a86f0cbe Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 3 Nov 2010 12:26:35 +0100 Subject: ALSA: oxygen: add HiFier Serenade support Add support for the TempoTec/MediaTek HiFier Serenade sound card. The PCI ID was already there, but the driver handled it like the Fantasia model, which resulted in a dummy recording device. As a stereo output-only card, this model is to be handled exactly like the HG2PCI. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/Kconfig | 1 + sound/pci/oxygen/oxygen.c | 27 +++++++++++++------------ 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'sound/pci') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index fdd388ded62a..7124340038ea 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1535,6 +1535,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec HiFier Fantasia + * TempoTec HiFier Serenade This module supports autoprobe and multiple cards. diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index f7139d09cbbe..5add96bdf172 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -226,6 +226,7 @@ config SND_OXYGEN * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec/MediaTek HiFier Fantasia + * TempoTec/MediaTek HiFier Serenade To compile this driver as a module, choose M here: the module will be called snd-oxygen. diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 13f39e58f3de..ea8fffefad9f 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -70,8 +70,8 @@ enum { MODEL_MERIDIAN, MODEL_CLARO, MODEL_CLARO_HALO, - MODEL_HIFIER, - MODEL_HG2PCI, + MODEL_FANTASIA, + MODEL_2CH_OUTPUT, }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { @@ -85,10 +85,11 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, /* Kuroutoshikou CMI8787-HG2PCI */ - { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, + { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_2CH_OUTPUT }, /* TempoTec HiFier Fantasia */ - { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, - { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, + { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA }, + /* TempoTec HiFier Serenade */ + { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_2CH_OUTPUT }, /* AuzenTech X-Meridian */ { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, /* HT-Omega Claro */ @@ -244,13 +245,13 @@ static void claro_halo_init(struct oxygen *chip) claro_enable_hp(chip); } -static void hifier_init(struct oxygen *chip) +static void fantasia_init(struct oxygen *chip) { ak4396_init(chip); snd_component_add(chip->card, "CS5340"); } -static void hg2pci_init(struct oxygen *chip) +static void stereo_output_init(struct oxygen *chip) { ak4396_init(chip); } @@ -583,20 +584,20 @@ static int __devinit get_oxygen_model(struct oxygen *chip, CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; break; - case MODEL_HIFIER: - case MODEL_HG2PCI: + case MODEL_FANTASIA: + case MODEL_2CH_OUTPUT: chip->model.shortname = "C-Media CMI8787"; chip->model.chip = "CMI8787"; - if (id->driver_data == MODEL_HIFIER) - chip->model.init = hifier_init; + if (id->driver_data == MODEL_FANTASIA) + chip->model.init = fantasia_init; else - chip->model.init = hg2pci_init; + chip->model.init = stereo_output_init; chip->model.resume = stereo_resume; chip->model.mixer_init = generic_mixer_init; chip->model.set_adc_params = set_no_params; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF; - if (id->driver_data == MODEL_HIFIER) + if (id->driver_data == MODEL_FANTASIA) chip->model.device_config |= CAPTURE_0_FROM_I2S_1; chip->model.dac_channels = 2; break; -- cgit v1.2.3 From 03b7a1ab557efe34e8f79b78660e514bd7374248 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 9 Nov 2010 14:35:30 +0100 Subject: ALSA: HDA: Create mixers on ALC887 BugLink: http://launchpad.net/bugs/669092 ALC887 does not have any volume control ability on the mixer NIDs, so put the volume controls on the dac NIDs instead. Without this patch, ALC887 users cannot use alsamixer at all. Cc: stable@kernel.org Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5f00589cb791..74029b5e7a62 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10816,6 +10816,9 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) return 0; } +static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg); + /* almost identical with ALC880 parser... */ static int alc882_parse_auto_config(struct hda_codec *codec) { @@ -10833,7 +10836,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec) err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); if (err < 0) return err; - err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (codec->vendor_id == 0x10ec0887) + err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); + else + err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); if (err < 0) return err; err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], @@ -16963,7 +16969,7 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) /* add playback controls from the parsed DAC table */ -/* Based on ALC880 version. But ALC861VD has separate, +/* Based on ALC880 version. But ALC861VD and ALC887 have separate, * different NIDs for mute/unmute switch and volume control */ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) -- cgit v1.2.3 From 86cbbad2b6712fbd25c07a17e86b4345cee82c6d Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sat, 20 Nov 2010 10:20:35 -0500 Subject: ALSA: hda: Add Samsung R720 SSID for subwoofer pin fixup BugLink: https://launchpad.net/bugs/677830 The original reporter states that the subwoofer does not mute when inserting headphones. We need an entry for his machine's SSID in the subwoofer pin fixup list, so add it there (verified using hda_analyzer). Reported-and-tested-by: i-NoD Cc: 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/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 74029b5e7a62..b7e234898fd8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19304,6 +19304,7 @@ static const struct alc_fixup alc662_fixups[] = { static struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), {} -- cgit v1.2.3 From 7974150c8524423f878e8269010e911c3cc7ddb8 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Sun, 21 Nov 2010 12:09:32 +0100 Subject: ALSA: azt3328: period bug fix (for PA), add missing ACK on stop timer . Fix PulseAudio "ALSA driver bug" issue (if we have two alternated areas within a 64k DMA buffer, then max period size should obviously be 32k only). Back references: http://pulseaudio.org/wiki/AlsaIssues http://fedoraproject.org/wiki/Features/GlitchFreeAudio . In stop timer function, need to supply ACK in the timer control byte. . Minor log output correction When I did my first PA testing recently, the period size bug resulted in quite precisely observeable half-period-based playback distortion. PA-based operation is quite a bit more underrun-prone (despite its zero-copy optimizations etc.) than raw ALSA with this rather spartan sound hardware implementation on my puny Athlon. Note that even with this patch, azt3328 still doesn't work for both cases yet, PA tsched=0 and tsched (on tsched=0 it will playback tiny fragments of periods, leading to tiny stuttering sounds with some pauses in between, whereas with timer-scheduled operation playback works fine - minus some quite increased underrun trouble on PA vs. ALSA, that is). Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 4679ed83a43b..2f3cacbd5528 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1129,10 +1129,11 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, count_areas = size/2; addr_area2 = addr+count_areas; - count_areas--; /* max. index */ snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", addr, count_areas, addr_area2, count_areas); + count_areas--; /* max. index */ + /* build combined I/O buffer length word */ lengths = (count_areas << 16) | (count_areas); spin_lock_irqsave(&chip->reg_lock, flags); @@ -1740,11 +1741,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware = .rate_max = AZF_FREQ_66200, .channels_min = 1, .channels_max = 2, - .buffer_bytes_max = 65536, - .period_bytes_min = 64, - .period_bytes_max = 65536, - .periods_min = 1, - .periods_max = 1024, + .buffer_bytes_max = (64*1024), + .period_bytes_min = 1024, + .period_bytes_max = (32*1024), + /* We simply have two DMA areas (instead of a list of descriptors + such as other cards); I believe that this is a fixed hardware + attribute and there isn't much driver magic to be done to expand it. + Thus indicate that we have at least and at most 2 periods. */ + .periods_min = 2, + .periods_max = 2, /* FIXME: maybe that card actually has a FIFO? * Hmm, it seems newer revisions do have one, but we still don't know * its size... */ @@ -1980,8 +1985,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer) chip = snd_timer_chip(timer); spin_lock_irqsave(&chip->reg_lock, flags); /* disable timer countdown and interrupt */ - /* FIXME: should we write TIMER_IRQ_ACK here? */ - snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); + /* Hmm, should we write TIMER_IRQ_ACK here? + YES indeed, otherwise a rogue timer operation - which prompts + ALSA(?) to call repeated stop() in vain, but NOT start() - + will never end (value 0x03 is kept shown in control byte). + Simply manually poking 0x04 _once_ immediately successfully stops + the hardware/ALSA interrupt activity. */ + snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_azf3328_dbgcallleave(); return 0; -- cgit v1.2.3 From a1d71a2c91239ecc1c1f9c97a081d71ebd30bfe5 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 21 Nov 2010 14:01:14 -0500 Subject: ALSA: hda: Use hp-laptop quirk to enable headphones automute for Asus A52J BugLink: https://launchpad.net/bugs/677652 The original reporter states that, in 2.6.35, headphones do not appear to work, nor does inserting them mute the A52J's onboard speakers. Upon inspecting the codec dump, it appears that the newly committed hp-laptop quirk will suffice to enable this basic functionality. Testing was done with an alsa-driver build from 2010-11-21. Reported-and-tested-by: Joan Creus Cc: [2.6.35+] Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 6361f752b5f3..3cfb31e77b16 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3100,6 +3100,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), + SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP), SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), -- cgit v1.2.3 From 7bb8fb70c491bd6f5ec99728db8d1b5f43b95471 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Nov 2010 10:49:47 +0100 Subject: ALSA: hda-intel: support for period wakeup disabling Allow disabling period wakeup interrupts for HDA PCM streams. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21aa9b0e28f6..a78ea34863ee 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1235,7 +1235,8 @@ static int azx_setup_periods(struct azx *chip, pos_adj = 0; } else { ofs = setup_bdle(substream, azx_dev, - &bdl, ofs, pos_adj, 1); + &bdl, ofs, pos_adj, + !substream->runtime->no_period_wakeup); if (ofs < 0) goto error; } @@ -1247,7 +1248,8 @@ static int azx_setup_periods(struct azx *chip, period_bytes - pos_adj, 0); else ofs = setup_bdle(substream, azx_dev, &bdl, ofs, - period_bytes, 1); + period_bytes, + !substream->runtime->no_period_wakeup); if (ofs < 0) goto error; } @@ -1515,7 +1517,8 @@ static struct snd_pcm_hardware azx_pcm_hw = { /* No full-resume yet implemented */ /* SNDRV_PCM_INFO_RESUME |*/ SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START), + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, -- cgit v1.2.3 From 075140ea8bf1405057c072a84ccf4e0d3f2c76f5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Nov 2010 10:50:37 +0100 Subject: ALSA: oxygen: support for period wakeup disabling Allow disabling period wakeup interrupts for all PCM streams. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_pcm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 814667442eb0..60e4aa00c042 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_32000 | @@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_32000 | @@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, @@ -530,7 +533,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream) oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); - chip->interrupt_mask |= channel_mask; + if (substream->runtime->no_period_wakeup) + chip->interrupt_mask &= ~channel_mask; + else + chip->interrupt_mask |= channel_mask; oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); spin_unlock_irq(&chip->reg_lock); return 0; -- cgit v1.2.3 From 9d57883f08d3c0c111b50bf185dfee9731a12c76 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Nov 2010 13:29:19 +0100 Subject: ALSA: hda - Add a generic fixup callback for Realtek codecs Add a generic callback function for fixup elements. This can be used to do some unusual things like overriding the AMP cache, etc. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 564e6c136ddd..f10c613c530f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1681,6 +1681,8 @@ struct alc_fixup { unsigned int sku; const struct alc_pincfg *pins; const struct hda_verb *verbs; + void (*func)(struct hda_codec *codec, const struct alc_fixup *fix, + int pre_init); }; static void alc_pick_fixup(struct hda_codec *codec, @@ -1720,6 +1722,13 @@ static void alc_pick_fixup(struct hda_codec *codec, #endif add_verb(codec->spec, fix->verbs); } + if (fix->func) { +#ifdef CONFIG_SND_DEBUG_VERBOSE + snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n", + codec->chip_name, quirk->name); +#endif + fix->func(codec, fix, pre_init); + } } static int alc_read_coef_idx(struct hda_codec *codec, -- cgit v1.2.3 From dc427170750f7be9ddedf16ca049b5cb827bd880 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 29 Nov 2010 07:42:59 +0100 Subject: ALSA: hda - Remove dead md2 quirk code Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/HD-Audio-Models.txt | 1 - sound/pci/hda/patch_realtek.c | 42 ++-------------------------- 2 files changed, 2 insertions(+), 41 deletions(-) (limited to 'sound/pci') diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 37c6aad5e590..16ae4300c747 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -149,7 +149,6 @@ ALC882/883/885/888/889 acer-aspire-7730g Acer Aspire 7730G acer-aspire-8930g Acer Aspire 8930G medion Medion Laptops - medion-md2 Medion MD2 targa-dig Targa/MSI targa-2ch-dig Targa/MSI with 2-channel targa-8ch-dig Targa/MSI with 8-channel (MSI GX620) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f0af8cfab410..65a9edeee9ea 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -231,7 +231,6 @@ enum { ALC888_ACER_ASPIRE_8930G, ALC888_ACER_ASPIRE_7730G, ALC883_MEDION, - ALC883_MEDION_MD2, ALC883_MEDION_WIM2160, ALC883_LAPTOP_EAPD, ALC883_LENOVO_101E_2ch, @@ -8989,19 +8988,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - { } /* end */ -}; - static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -9443,18 +9429,8 @@ static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, alc888_lenovo_ms7195_rca_automute(codec); } -static struct hda_verb alc883_medion_md2_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - /* toggle speaker-output according to the hp-jack state */ -static void alc883_medion_md2_setup(struct hda_codec *codec) +static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -9739,7 +9715,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", [ALC883_MEDION] = "medion", - [ALC883_MEDION_MD2] = "medion-md2", [ALC883_MEDION_WIM2160] = "medion-wim2160", [ALC883_LAPTOP_EAPD] = "laptop-eapd", [ALC883_LENOVO_101E_2ch] = "lenovo-101e", @@ -10387,19 +10362,6 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, }, - [ALC883_MEDION_MD2] = { - .mixers = { alc883_medion_md2_mixer}, - .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, - .setup = alc883_medion_md2_setup, - .init_hook = alc_automute_amp, - }, [ALC883_MEDION_WIM2160] = { .mixers = { alc883_medion_wim2160_mixer }, .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, @@ -10476,7 +10438,7 @@ static struct alc_config_preset alc882_presets[] = { .need_dac_fix = 1, .input_mux = &alc883_lenovo_nb0763_capture_source, .unsol_event = alc_automute_amp_unsol_event, - .setup = alc883_medion_md2_setup, + .setup = alc883_lenovo_nb0763_setup, .init_hook = alc_automute_amp, }, [ALC888_LENOVO_MS7195_DIG] = { -- cgit v1.2.3 From 28b26e15533e60970a014582d812d471ad63bcd0 Mon Sep 17 00:00:00 2001 From: Florian Faber Date: Wed, 1 Dec 2010 12:14:47 +0100 Subject: ALSA: hdsp - Add support for RPM io box Add support for the RME HDSP RPM IO box. Changes have been made in the identification of the IO box and the neccessary controls have been added. Signed-off-by: Florian Faber Signed-off-by: Takashi Iwai --- include/sound/hdsp.h | 1 + sound/pci/rme9652/hdsp.c | 538 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 482 insertions(+), 57 deletions(-) (limited to 'sound/pci') diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h index d98a78dff2db..0909a3843479 100644 --- a/include/sound/hdsp.h +++ b/include/sound/hdsp.h @@ -28,6 +28,7 @@ enum HDSP_IO_Type { Multiface, H9652, H9632, + RPM, Undefined, }; diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 0b720cf7783e..2d8332416c83 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -60,6 +60,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," "{RME HDSP-9652}," "{RME HDSP-9632}}"); #ifdef HDSP_FW_LOADER +MODULE_FIRMWARE("rpm_firmware.bin"); MODULE_FIRMWARE("multiface_firmware.bin"); MODULE_FIRMWARE("multiface_firmware_rev11.bin"); MODULE_FIRMWARE("digiface_firmware.bin"); @@ -81,6 +82,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); #define H9632_SS_CHANNELS 12 #define H9632_DS_CHANNELS 8 #define H9632_QS_CHANNELS 4 +#define RPM_CHANNELS 6 /* Write registers. These are defined as byte-offsets from the iobase value. */ @@ -191,6 +193,25 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); #define HDSP_PhoneGain1 (1<<30) #define HDSP_QuadSpeed (1<<31) +/* RPM uses some of the registers for special purposes */ +#define HDSP_RPM_Inp12 0x04A00 +#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */ +#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */ +#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */ +#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */ +#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */ + +#define HDSP_RPM_Inp34 0x32000 +#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */ +#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */ +#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */ +#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */ +#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */ + +#define HDSP_RPM_Bypass 0x01000 + +#define HDSP_RPM_Disconnect 0x00001 + #define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1) #define HDSP_ADGainMinus10dBV HDSP_ADGainMask #define HDSP_ADGainPlus4dBu (HDSP_ADGain0) @@ -450,7 +471,7 @@ struct hdsp { u32 creg_spdif; u32 creg_spdif_stream; int clock_source_locked; - char *card_name; /* digiface/multiface */ + char *card_name; /* digiface/multiface/rpm */ enum HDSP_IO_Type io_type; /* ditto, but for code use */ unsigned short firmware_rev; unsigned short state; /* stores state bits */ @@ -612,6 +633,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out) switch (hdsp->io_type) { case Multiface: case Digiface: + case RPM: default: if (hdsp->firmware_rev == 0xa) return (64 * out) + (32 + (in)); @@ -629,6 +651,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out) switch (hdsp->io_type) { case Multiface: case Digiface: + case RPM: default: if (hdsp->firmware_rev == 0xa) return (64 * out) + in; @@ -655,7 +678,7 @@ static int hdsp_check_for_iobox (struct hdsp *hdsp) { if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { - snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n"); + snd_printk("Hammerfall-DSP: no IO box connected!\n"); hdsp->state &= ~HDSP_FirmwareLoaded; return -EIO; } @@ -680,7 +703,7 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, } } - snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n"); + snd_printk("Hammerfall-DSP: no IO box connected!\n"); hdsp->state &= ~HDSP_FirmwareLoaded; return -EIO; } @@ -752,17 +775,21 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write (hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) { - hdsp->io_type = Multiface; - hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); - hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); - hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) { + hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) + hdsp->io_type = RPM; + else + hdsp->io_type = Multiface; } else { hdsp->io_type = Digiface; } } else { /* firmware was already loaded, get iobox type */ - if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) + if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) + hdsp->io_type = RPM; + else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) hdsp->io_type = Multiface; else hdsp->io_type = Digiface; @@ -1184,6 +1211,7 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) hdsp->channel_map = channel_map_ds; } else { switch (hdsp->io_type) { + case RPM: case Multiface: hdsp->channel_map = channel_map_mf_ss; break; @@ -3231,6 +3259,318 @@ HDSP_PRECISE_POINTER("Precise Pointer", 0), HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), }; + +static int hdsp_rpm_input12(struct hdsp *hdsp) +{ + switch (hdsp->control_register & HDSP_RPM_Inp12) { + case HDSP_RPM_Inp12_Phon_6dB: + return 0; + case HDSP_RPM_Inp12_Phon_n6dB: + return 2; + case HDSP_RPM_Inp12_Line_0dB: + return 3; + case HDSP_RPM_Inp12_Line_n6dB: + return 4; + } + return 1; +} + + +static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp); + return 0; +} + + +static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode) +{ + hdsp->control_register &= ~HDSP_RPM_Inp12; + switch (mode) { + case 0: + hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB; + break; + case 1: + break; + case 2: + hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB; + break; + case 3: + hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB; + break; + case 4: + hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB; + break; + default: + return -1; + } + + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.enumerated.item[0]; + if (val < 0) + val = 0; + if (val > 4) + val = 4; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_rpm_input12(hdsp)) + change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0; + else + change = 0; + spin_unlock_irq(&hdsp->lock); + return change; +} + + +static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"}; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 5; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + + +static int hdsp_rpm_input34(struct hdsp *hdsp) +{ + switch (hdsp->control_register & HDSP_RPM_Inp34) { + case HDSP_RPM_Inp34_Phon_6dB: + return 0; + case HDSP_RPM_Inp34_Phon_n6dB: + return 2; + case HDSP_RPM_Inp34_Line_0dB: + return 3; + case HDSP_RPM_Inp34_Line_n6dB: + return 4; + } + return 1; +} + + +static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp); + return 0; +} + + +static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode) +{ + hdsp->control_register &= ~HDSP_RPM_Inp34; + switch (mode) { + case 0: + hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB; + break; + case 1: + break; + case 2: + hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB; + break; + case 3: + hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB; + break; + case 4: + hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB; + break; + default: + return -1; + } + + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.enumerated.item[0]; + if (val < 0) + val = 0; + if (val > 4) + val = 4; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_rpm_input34(hdsp)) + change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0; + else + change = 0; + spin_unlock_irq(&hdsp->lock); + return change; +} + + +/* RPM Bypass switch */ +static int hdsp_rpm_bypass(struct hdsp *hdsp) +{ + return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0; +} + + +static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp); + return 0; +} + + +static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on) +{ + if (on) + hdsp->control_register |= HDSP_RPM_Bypass; + else + hdsp->control_register &= ~HDSP_RPM_Bypass; + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + unsigned int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.integer.value[0] & 1; + spin_lock_irq(&hdsp->lock); + change = (int)val != hdsp_rpm_bypass(hdsp); + hdsp_set_rpm_bypass(hdsp, val); + spin_unlock_irq(&hdsp->lock); + return change; +} + + +static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"On", "Off"}; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + + +/* RPM Disconnect switch */ +static int hdsp_rpm_disconnect(struct hdsp *hdsp) +{ + return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0; +} + + +static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp); + return 0; +} + + +static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on) +{ + if (on) + hdsp->control_register |= HDSP_RPM_Disconnect; + else + hdsp->control_register &= ~HDSP_RPM_Disconnect; + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + unsigned int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.integer.value[0] & 1; + spin_lock_irq(&hdsp->lock); + change = (int)val != hdsp_rpm_disconnect(hdsp); + hdsp_set_rpm_disconnect(hdsp, val); + spin_unlock_irq(&hdsp->lock); + return change; +} + +static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"On", "Off"}; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + +static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "RPM Bypass", + .get = snd_hdsp_get_rpm_bypass, + .put = snd_hdsp_put_rpm_bypass, + .info = snd_hdsp_info_rpm_bypass + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "RPM Disconnect", + .get = snd_hdsp_get_rpm_disconnect, + .put = snd_hdsp_put_rpm_disconnect, + .info = snd_hdsp_info_rpm_disconnect + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input 1/2", + .get = snd_hdsp_get_rpm_input12, + .put = snd_hdsp_put_rpm_input12, + .info = snd_hdsp_info_rpm_input + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input 3/4", + .get = snd_hdsp_get_rpm_input34, + .put = snd_hdsp_put_rpm_input34, + .info = snd_hdsp_info_rpm_input + }, + HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), + HDSP_MIXER("Mixer", 0) +}; + static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; @@ -3240,6 +3580,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) int err; struct snd_kcontrol *kctl; + if (hdsp->io_type == RPM) { + /* RPM Bypass, Disconnect and Input switches */ + for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) { + err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp)); + if (err < 0) + return err; + } + return 0; + } + for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) { if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) return err; @@ -3459,48 +3809,102 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) snd_iprintf(buffer, "\n"); - switch (hdsp_spdif_in(hdsp)) { - case HDSP_SPDIFIN_OPTICAL: - snd_iprintf(buffer, "IEC958 input: Optical\n"); - break; - case HDSP_SPDIFIN_COAXIAL: - snd_iprintf(buffer, "IEC958 input: Coaxial\n"); - break; - case HDSP_SPDIFIN_INTERNAL: - snd_iprintf(buffer, "IEC958 input: Internal\n"); - break; - case HDSP_SPDIFIN_AES: - snd_iprintf(buffer, "IEC958 input: AES\n"); - break; - default: - snd_iprintf(buffer, "IEC958 input: ???\n"); - break; + if (hdsp->io_type != RPM) { + switch (hdsp_spdif_in(hdsp)) { + case HDSP_SPDIFIN_OPTICAL: + snd_iprintf(buffer, "IEC958 input: Optical\n"); + break; + case HDSP_SPDIFIN_COAXIAL: + snd_iprintf(buffer, "IEC958 input: Coaxial\n"); + break; + case HDSP_SPDIFIN_INTERNAL: + snd_iprintf(buffer, "IEC958 input: Internal\n"); + break; + case HDSP_SPDIFIN_AES: + snd_iprintf(buffer, "IEC958 input: AES\n"); + break; + default: + snd_iprintf(buffer, "IEC958 input: ???\n"); + break; + } } - if (hdsp->control_register & HDSP_SPDIFOpticalOut) - snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); - else - snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); + if (RPM == hdsp->io_type) { + if (hdsp->control_register & HDSP_RPM_Bypass) + snd_iprintf(buffer, "RPM Bypass: disabled\n"); + else + snd_iprintf(buffer, "RPM Bypass: enabled\n"); + if (hdsp->control_register & HDSP_RPM_Disconnect) + snd_iprintf(buffer, "RPM disconnected\n"); + else + snd_iprintf(buffer, "RPM connected\n"); - if (hdsp->control_register & HDSP_SPDIFProfessional) - snd_iprintf(buffer, "IEC958 quality: Professional\n"); - else - snd_iprintf(buffer, "IEC958 quality: Consumer\n"); + switch (hdsp->control_register & HDSP_RPM_Inp12) { + case HDSP_RPM_Inp12_Phon_6dB: + snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n"); + break; + case HDSP_RPM_Inp12_Phon_0dB: + snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n"); + break; + case HDSP_RPM_Inp12_Phon_n6dB: + snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n"); + break; + case HDSP_RPM_Inp12_Line_0dB: + snd_iprintf(buffer, "Input 1/2: Line, 0dB\n"); + break; + case HDSP_RPM_Inp12_Line_n6dB: + snd_iprintf(buffer, "Input 1/2: Line, -6dB\n"); + break; + default: + snd_iprintf(buffer, "Input 1/2: ???\n"); + } - if (hdsp->control_register & HDSP_SPDIFEmphasis) - snd_iprintf(buffer, "IEC958 emphasis: on\n"); - else - snd_iprintf(buffer, "IEC958 emphasis: off\n"); + switch (hdsp->control_register & HDSP_RPM_Inp34) { + case HDSP_RPM_Inp34_Phon_6dB: + snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n"); + break; + case HDSP_RPM_Inp34_Phon_0dB: + snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n"); + break; + case HDSP_RPM_Inp34_Phon_n6dB: + snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n"); + break; + case HDSP_RPM_Inp34_Line_0dB: + snd_iprintf(buffer, "Input 3/4: Line, 0dB\n"); + break; + case HDSP_RPM_Inp34_Line_n6dB: + snd_iprintf(buffer, "Input 3/4: Line, -6dB\n"); + break; + default: + snd_iprintf(buffer, "Input 3/4: ???\n"); + } - if (hdsp->control_register & HDSP_SPDIFNonAudio) - snd_iprintf(buffer, "IEC958 NonAudio: on\n"); - else - snd_iprintf(buffer, "IEC958 NonAudio: off\n"); - if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) - snd_iprintf (buffer, "IEC958 sample rate: %d\n", x); - else - snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n"); + } else { + if (hdsp->control_register & HDSP_SPDIFOpticalOut) + snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); + else + snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); + + if (hdsp->control_register & HDSP_SPDIFProfessional) + snd_iprintf(buffer, "IEC958 quality: Professional\n"); + else + snd_iprintf(buffer, "IEC958 quality: Consumer\n"); + + if (hdsp->control_register & HDSP_SPDIFEmphasis) + snd_iprintf(buffer, "IEC958 emphasis: on\n"); + else + snd_iprintf(buffer, "IEC958 emphasis: off\n"); + if (hdsp->control_register & HDSP_SPDIFNonAudio) + snd_iprintf(buffer, "IEC958 NonAudio: on\n"); + else + snd_iprintf(buffer, "IEC958 NonAudio: off\n"); + x = hdsp_spdif_sample_rate(hdsp); + if (x != 0) + snd_iprintf(buffer, "IEC958 sample rate: %d\n", x); + else + snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n"); + } snd_iprintf(buffer, "\n"); /* Sync Check */ @@ -3765,7 +4169,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id) snd_hdsp_midi_input_read (&hdsp->midi[0]); } } - if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) { + if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) { if (hdsp->use_midi_tasklet) { /* we disable interrupts for this input until processing is done */ hdsp->control_register &= ~HDSP_Midi1InterruptEnable; @@ -4093,7 +4497,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo = SNDRV_PCM_RATE_96000), .rate_min = 32000, .rate_max = 96000, - .channels_min = 14, + .channels_min = 6, .channels_max = HDSP_MAX_CHANNELS, .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, .period_bytes_min = (64 * 4) * 10, @@ -4122,7 +4526,7 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo = SNDRV_PCM_RATE_96000), .rate_min = 32000, .rate_max = 96000, - .channels_min = 14, + .channels_min = 5, .channels_max = HDSP_MAX_CHANNELS, .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, .period_bytes_min = (64 * 4) * 10, @@ -4357,10 +4761,12 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream) snd_hdsp_hw_rule_rate_out_channels, hdsp, SNDRV_PCM_HW_PARAM_CHANNELS, -1); - hdsp->creg_spdif_stream = hdsp->creg_spdif; - hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | - SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + if (RPM != hdsp->io_type) { + hdsp->creg_spdif_stream = hdsp->creg_spdif; + hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + } return 0; } @@ -4375,9 +4781,11 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream) spin_unlock_irq(&hdsp->lock); - hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | - SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + if (RPM != hdsp->io_type) { + hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + } return 0; } @@ -4616,7 +5024,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne if (hdsp->io_type != H9632) info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp); info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp); - for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) + for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); @@ -4636,6 +5044,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); + } else if (hdsp->io_type == RPM) { + info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); + info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); } if (hdsp->io_type == H9632 || hdsp->io_type == H9652) info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); @@ -4844,6 +5255,14 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp) hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS; break; + case RPM: + hdsp->card_name = "RME Hammerfall DSP + RPM"; + hdsp->ss_in_channels = RPM_CHANNELS-1; + hdsp->ss_out_channels = RPM_CHANNELS; + hdsp->ds_in_channels = RPM_CHANNELS-1; + hdsp->ds_out_channels = RPM_CHANNELS; + break; + default: /* should never get here */ break; @@ -4930,6 +5349,9 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp) /* caution: max length of firmware filename is 30! */ switch (hdsp->io_type) { + case RPM: + fwfile = "rpm_firmware.bin"; + break; case Multiface: if (hdsp->firmware_rev == 0xa) fwfile = "multiface_firmware.bin"; @@ -5100,7 +5522,9 @@ static int __devinit snd_hdsp_create(struct snd_card *card, return 0; } else { snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n"); - if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) + if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) + hdsp->io_type = RPM; + else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) hdsp->io_type = Multiface; else hdsp->io_type = Digiface; -- cgit v1.2.3 From a3de8ab8853c5a14e881f0a01aa31e3dc87fc304 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 3 Dec 2010 12:29:14 +0100 Subject: ALSA: hda - Clean up cxt5066 port-D handling & co Instead of hard-coded magic numbers, properly define and use macros for improve the readability. Also, dell_automute is handled samely as thinkpad, since it also sets port_d_mode, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e652b34b1bd9..cb15ac9ee137 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -2111,6 +2111,11 @@ static struct hda_channel_mode cxt5066_modes[1] = { { 2, NULL }, }; +#define HP_PRESENT_PORT_A (1 << 0) +#define HP_PRESENT_PORT_D (1 << 1) +#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A) +#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D) + static void cxt5066_update_speaker(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -2120,24 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec) spec->hp_present, spec->cur_eapd); /* Port A (HP) */ - pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; + pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0; snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); /* Port D (HP/LO) */ - if (spec->dell_automute) { - /* DELL AIO Port Rule: PortA> PortD> IntSpk */ - pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) - ? PIN_OUT : 0; - } else if (spec->thinkpad) { - if (spec->cur_eapd) - pinctl = spec->port_d_mode; - /* Mute dock line-out if Port A (laptop HP) is present */ - if (spec->hp_present& 1) + pinctl = spec->cur_eapd ? spec->port_d_mode : 0; + if (spec->dell_automute || spec->thinkpad) { + /* Mute if Port A is connected */ + if (hp_port_a_present(spec)) pinctl = 0; } else { - pinctl = ((spec->hp_present & 2) && spec->cur_eapd) - ? spec->port_d_mode : 0; + /* Thinkpad/Dell doesn't give pin-D status */ + if (!hp_port_d_present(spec)) + pinctl = 0; } snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); @@ -2379,8 +2380,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec) /* Port D */ portD = snd_hda_jack_detect(codec, 0x1c); - spec->hp_present = !!(portA); - spec->hp_present |= portD ? 2 : 0; + spec->hp_present = portA ? HP_PRESENT_PORT_A : 0; + spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0; snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", portA, portD, spec->hp_present); cxt5066_update_speaker(codec); -- cgit v1.2.3 From 1e1675e9c1342a841e87e5427e77da78e980da06 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 3 Dec 2010 14:58:37 +0100 Subject: ALSA: hda - Enable beep for IDT92HD87 / 88 codecs These codecs have the digital beep widget in NID 0x21. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index efa4225f5fd6..a1df0facdda4 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5471,7 +5471,6 @@ again: spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); spec->pin_nids = stac92hd88xxx_pin_nids; spec->mono_nid = 0; - spec->digbeep_nid = 0; spec->num_pwrs = 0; break; case 0x111d7604: -- cgit v1.2.3 From 1db7ccdb2ef4dbd8df0e0f742c9da9b054d899ba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 3 Dec 2010 15:19:14 +0100 Subject: ALSA: hda - Fix beep-tone on IDT 92HD87/88 codecs It sounds like a non-linear beep tone on my test machines... Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a1df0facdda4..8e2bb0aad0ae 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5423,7 +5423,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); codec->no_trigger_sense = 1; codec->spec = spec; - spec->linear_tone_beep = 1; + spec->linear_tone_beep = 0; codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->digbeep_nid = 0x21; spec->dmic_nids = stac92hd83xxx_dmic_nids; -- cgit v1.2.3 From 36e9c135e2c485cabb24084834ec29efe928bb5c Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Sun, 5 Dec 2010 02:34:15 +0200 Subject: ALSA: hda - use generic hdmi parser for ATI R6xx codec Switch to the generic hdmi parser for codec id 1002:aa01 (ATI R6xx HDMI), as the codec appears to work fine with it. Note that the codec is still limited to stereo output only, despite it reportedly being multichannel capable. Some as of yet unknown quirks will be needed to get that working. Testing was done on 2.6.36 by John Ettedgui. Signed-off-by: Anssi Hannula Tested-by: John Ettedgui Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d3e49aa5b9ec..f2267cfdd992 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1533,7 +1533,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, -{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi }, +{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi }, { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi }, { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi }, { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi }, -- cgit v1.2.3 From f7e4bad74e1b18aaff6e89cf2bc4a3868a6ba56e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:36:51 +0100 Subject: ALSA: virtuoso: initialize unknown GPIO bits Initialize the configuration of some unknown GPIO output bits (that might not be used at all) to be the same as in the Windows driver, just to be sure. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_cs43xx.c | 5 ++++- sound/pci/oxygen/xonar_pcm179x.c | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index aa27c31049af..ae4e5b512483 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -63,6 +63,7 @@ #define GPI_EXT_POWER 0x01 #define GPIO_D1_OUTPUT_ENABLE 0x0001 #define GPIO_D1_FRONT_PANEL 0x0002 +#define GPIO_D1_MAGIC 0x00c0 #define GPIO_D1_INPUT_ROUTE 0x0100 #define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ @@ -169,7 +170,9 @@ static void xonar_d1_init(struct oxygen *chip) cs43xx_registers_init(chip); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, - GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); + GPIO_D1_FRONT_PANEL | + GPIO_D1_MAGIC | + GPIO_D1_INPUT_ROUTE); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index d491fd6c0be2..fe4b2655a252 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -167,12 +167,14 @@ #define GPIO_INPUT_ROUTE 0x0100 #define GPIO_HDAV_OUTPUT_ENABLE 0x0001 +#define GPIO_HDAV_MAGIC 0x00c0 #define GPIO_DB_MASK 0x0030 #define GPIO_DB_H6 0x0000 #define GPIO_ST_OUTPUT_ENABLE 0x0001 #define GPIO_ST_HP_REAR 0x0002 +#define GPIO_ST_MAGIC 0x0040 #define GPIO_ST_HP 0x0080 #define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ @@ -350,7 +352,8 @@ static void xonar_hdav_init(struct oxygen *chip) pcm1796_init(chip); - oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE); + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE); xonar_init_cs53x1(chip); @@ -381,7 +384,8 @@ static void xonar_st_init_common(struct oxygen *chip) pcm1796_init(chip); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, - GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); + GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | + GPIO_ST_MAGIC | GPIO_ST_HP); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); -- cgit v1.2.3 From 2509ec623d44320419d44d4060dbedf91b8d192d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:38:06 +0100 Subject: ALSA: virtuoso: add HDMI enable switch for HDAV1.3 The GPIO bit that enables analog output on the Xonar HDAV1.3 also disables the HDMI audio output, so we better add a switch for it. Hopefully, this is sufficient to make the HDMI output work. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/Kconfig | 2 +- sound/pci/oxygen/xonar.h | 2 ++ sound/pci/oxygen/xonar_lib.c | 6 ++++-- sound/pci/oxygen/xonar_pcm179x.c | 19 ++++++++++++++++++- 4 files changed, 25 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 5add96bdf172..7b2678a25ca0 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -817,7 +817,7 @@ config SND_VIRTUOSO Say Y here to include support for sound cards based on the Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, Essence ST (Deluxe), and Essence STX. - Support for the HDAV1.3 (Deluxe) is incomplete; for the + Support for the HDAV1.3 (Deluxe) is experimental; for the HDAV1.3 Slim and Xense, missing. To compile this driver as a module, choose M here: the module diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h index b35343b0a9a5..0434c207e811 100644 --- a/sound/pci/oxygen/xonar.h +++ b/sound/pci/oxygen/xonar.h @@ -24,6 +24,8 @@ void xonar_init_ext_power(struct oxygen *chip); void xonar_init_cs53x1(struct oxygen *chip); void xonar_set_cs53x1_params(struct oxygen *chip, struct snd_pcm_hw_params *params); + +#define XONAR_GPIO_BIT_INVERT (1 << 16) int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value); int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c index b3ff71316653..0ebe7f5916f9 100644 --- a/sound/pci/oxygen/xonar_lib.c +++ b/sound/pci/oxygen/xonar_lib.c @@ -104,9 +104,10 @@ int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, { struct oxygen *chip = ctl->private_data; u16 bit = ctl->private_value; + bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT; value->value.integer.value[0] = - !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit); + !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert; return 0; } @@ -115,12 +116,13 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, { struct oxygen *chip = ctl->private_data; u16 bit = ctl->private_value; + bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT; u16 old_bits, new_bits; int changed; spin_lock_irq(&chip->reg_lock); old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); - if (value->value.integer.value[0]) + if (!!value->value.integer.value[0] ^ invert) new_bits = old_bits | bit; else new_bits = old_bits & ~bit; diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index fe4b2655a252..3850834f989c 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -776,6 +776,15 @@ static const struct snd_kcontrol_new os_128_control = { .put = os_128_put, }; +static const struct snd_kcontrol_new hdav_hdmi_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "HDMI Playback Switch", + .info = snd_ctl_boolean_mono_info, + .get = xonar_gpio_bit_switch_get, + .put = xonar_gpio_bit_switch_put, + .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT, +}; + static int st_output_switch_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { @@ -960,7 +969,15 @@ static int xonar_d2_mixer_init(struct oxygen *chip) static int xonar_hdav_mixer_init(struct oxygen *chip) { - return add_pcm1796_controls(chip); + int err; + + err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip)); + if (err < 0) + return err; + err = add_pcm1796_controls(chip); + if (err < 0) + return err; + return 0; } static int xonar_st_mixer_init(struct oxygen *chip) -- cgit v1.2.3 From e96f38f732d24515792296b3738842934c985539 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:39:34 +0100 Subject: ALSA: virtuoso: fix front panel routing for D1/DX/ST(X) The "Front Panel" switch on the Xonar D1/DX actually switches only the output direction, so mark it appropriately. The front panel microphone is controlled by the FMIC2MIC bit of the CM9780. It was unconditionally enabled on the D1/DX and never set on the ST(X); add a control for it. Selecting the front panel microphone as source does not actually disable the microphone jack, but this is bug-compatible with the Windows driver, and users rely on it. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.h | 1 + sound/pci/oxygen/oxygen_mixer.c | 55 ++++++++++++++++++++++++++++++++++++++++ sound/pci/oxygen/xonar_cs43xx.c | 9 +++---- sound/pci/oxygen/xonar_pcm179x.c | 3 ++- 4 files changed, 62 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 7d5222caa0a9..cf9054ecb97b 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -35,6 +35,7 @@ #define MIDI_OUTPUT 0x0800 #define MIDI_INPUT 0x1000 #define AC97_CD_INPUT 0x2000 +#define AC97_FMIC_SWITCH 0x4000 enum { CONTROL_SPDIF_PCM, diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 2849b36f5f7e..605e84b9e1ec 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -644,6 +644,51 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, return change; } +static int mic_fmic_source_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) +{ + static const char *const names[] = { "Mic Jack", "Front Panel" }; + + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = 1; + info->value.enumerated.items = 2; + info->value.enumerated.item &= 1; + strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); + return 0; +} + +static int mic_fmic_source_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + + mutex_lock(&chip->mutex); + value->value.enumerated.item[0] = + !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC); + mutex_unlock(&chip->mutex); + return 0; +} + +static int mic_fmic_source_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + u16 oldreg, newreg; + int change; + + mutex_lock(&chip->mutex); + oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK); + if (value->value.enumerated.item[0]) + newreg = oldreg | CM9780_FMIC2MIC; + else + newreg = oldreg & ~CM9780_FMIC2MIC; + change = newreg != oldreg; + if (change) + oxygen_write_ac97(chip, 0, CM9780_JACK, newreg); + mutex_unlock(&chip->mutex); + return change; +} + static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { @@ -908,6 +953,13 @@ static const struct snd_kcontrol_new ac97_controls[] = { AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Source Capture Enum", + .info = mic_fmic_source_info, + .get = mic_fmic_source_get, + .put = mic_fmic_source_put, + }, AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), @@ -972,6 +1024,9 @@ static int add_controls(struct oxygen *chip, if (!strcmp(template.name, "Stereo Upmixing") && chip->model.dac_channels == 2) continue; + if (!strcmp(template.name, "Mic Source Capture Enum") && + !(chip->model.device_config & AC97_FMIC_SWITCH)) + continue; if (!strncmp(template.name, "CD Capture ", 11) && !(chip->model.device_config & AC97_CD_INPUT)) continue; diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index ae4e5b512483..501fe45bbdce 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -28,7 +28,7 @@ * GPI 0 <- external power present (DX only) * * GPIO 0 -> enable output to speakers - * GPIO 1 -> enable front panel I/O + * GPIO 1 -> route output to front panel * GPIO 2 -> M0 of CS5361 * GPIO 3 -> M1 of CS5361 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) @@ -176,8 +176,6 @@ static void xonar_d1_init(struct oxygen *chip) oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); - oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); - xonar_init_cs53x1(chip); xonar_enable_output(chip); @@ -287,7 +285,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed) static const struct snd_kcontrol_new front_panel_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Panel Switch", + .name = "Front Panel Playback Switch", .info = snd_ctl_boolean_mono_info, .get = xonar_gpio_bit_switch_get, .put = xonar_gpio_bit_switch_put, @@ -402,7 +400,8 @@ static const struct oxygen_model model_xonar_d1 = { .model_data_size = sizeof(struct xonar_cs43xx), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, + CAPTURE_0_FROM_I2S_2 | + AC97_FMIC_SWITCH, .dac_channels = 8, .dac_volume_min = 127 - 60, .dac_volume_max = 127, diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 3850834f989c..5193d73a916d 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -1079,7 +1079,8 @@ static const struct oxygen_model model_xonar_st = { .model_data_size = sizeof(struct xonar_pcm179x), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, + CAPTURE_0_FROM_I2S_2 | + AC97_FMIC_SWITCH, .dac_channels = 2, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, -- cgit v1.2.3 From 9719fcaa6a82be59a2d7767725e5cd8233c6a387 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:41:10 +0100 Subject: ALSA: oxygen: allow to dump codec registers To help with debugging, add the registers of the model-specific codecs to the controller and AC97 register dump in the proc file. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 38 +++++++++++++++++++++++++++ sound/pci/oxygen/oxygen.h | 3 +++ sound/pci/oxygen/oxygen_lib.c | 10 ++++--- sound/pci/oxygen/xonar_cs43xx.c | 25 ++++++++++++++++++ sound/pci/oxygen/xonar_pcm179x.c | 56 +++++++++++++++++++++++++++++++++++----- sound/pci/oxygen/xonar_wm87x6.c | 30 +++++++++++++++++++++ 6 files changed, 151 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index ea8fffefad9f..a58e448fc1bf 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -518,6 +519,39 @@ static int generic_wm8785_mixer_init(struct oxygen *chip) return 0; } +static void dump_ak4396_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct generic_data *data = chip->model_data; + unsigned int dac, i; + + for (dac = 0; dac < data->dacs; ++dac) { + snd_iprintf(buffer, "\nAK4396 %u:", dac + 1); + for (i = 0; i < 5; ++i) + snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]); + } + snd_iprintf(buffer, "\n"); +} + +static void dump_wm8785_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct generic_data *data = chip->model_data; + unsigned int i; + + snd_iprintf(buffer, "\nWM8785:"); + for (i = 0; i < 3; ++i) + snd_iprintf(buffer, " %03x", data->wm8785_regs[i]); + snd_iprintf(buffer, "\n"); +} + +static void dump_oxygen_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + dump_ak4396_registers(chip, buffer); + dump_wm8785_registers(chip, buffer); +} + static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); static const struct oxygen_model model_generic = { @@ -533,6 +567,7 @@ static const struct oxygen_model model_generic = { .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, + .dump_registers = dump_oxygen_registers, .dac_tlv = ak4396_db_scale, .model_data_size = sizeof(struct generic_data), .device_config = PLAYBACK_0_TO_I2S | @@ -561,6 +596,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.mixer_init = generic_mixer_init; chip->model.resume = meridian_resume; chip->model.set_adc_params = set_ak5385_params; + chip->model.dump_registers = dump_ak4396_registers; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | @@ -579,6 +615,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.suspend = claro_suspend; chip->model.resume = claro_resume; chip->model.set_adc_params = set_ak5385_params; + chip->model.dump_registers = dump_ak4396_registers; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | @@ -595,6 +632,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.resume = stereo_resume; chip->model.mixer_init = generic_mixer_init; chip->model.set_adc_params = set_no_params; + chip->model.dump_registers = dump_ak4396_registers; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF; if (id->driver_data == MODEL_FANTASIA) diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index cf9054ecb97b..b8fbc15b89a3 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -66,6 +66,7 @@ struct snd_pcm_hardware; struct snd_pcm_hw_params; struct snd_kcontrol_new; struct snd_rawmidi; +struct snd_info_buffer; struct oxygen; struct oxygen_model { @@ -93,6 +94,8 @@ struct oxygen_model { void (*uart_input)(struct oxygen *chip); void (*ac97_switch)(struct oxygen *chip, unsigned int reg, unsigned int mute); + void (*dump_registers)(struct oxygen *chip, + struct snd_info_buffer *buffer); const unsigned int *dac_tlv; unsigned long private_data; size_t model_data_size; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 2e6579962217..e581e7ab216c 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -202,7 +202,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, struct oxygen *chip = entry->private_data; int i, j; - snd_iprintf(buffer, "CMI8788\n\n"); + snd_iprintf(buffer, "CMI8788:\n"); for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; ++j) @@ -212,7 +212,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, if (mutex_lock_interruptible(&chip->mutex) < 0) return; if (chip->has_ac97_0) { - snd_iprintf(buffer, "\nAC97\n"); + snd_iprintf(buffer, "\nAC97:\n"); for (i = 0; i < 0x80; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; j += 2) @@ -222,7 +222,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, } } if (chip->has_ac97_1) { - snd_iprintf(buffer, "\nAC97 2\n"); + snd_iprintf(buffer, "\nAC97 2:\n"); for (i = 0; i < 0x80; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; j += 2) @@ -232,13 +232,15 @@ static void oxygen_proc_read(struct snd_info_entry *entry, } } mutex_unlock(&chip->mutex); + if (chip->model.dump_registers) + chip->model.dump_registers(chip, buffer); } static void oxygen_proc_init(struct oxygen *chip) { struct snd_info_entry *entry; - if (!snd_card_proc_new(chip->card, "cmi8788", &entry)) + if (!snd_card_proc_new(chip->card, "oxygen", &entry)) snd_info_set_text_ops(entry, chip, oxygen_proc_read); } #else diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 501fe45bbdce..092addb15e13 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -381,6 +381,30 @@ static int xonar_d1_mixer_init(struct oxygen *chip) return 0; } +static void dump_cs4362a_registers(struct xonar_cs43xx *data, + struct snd_info_buffer *buffer) +{ + unsigned int i; + + snd_iprintf(buffer, "\nCS4362A:"); + for (i = 1; i <= 14; ++i) + snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]); + snd_iprintf(buffer, "\n"); +} + +static void dump_d1_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_cs43xx *data = chip->model_data; + unsigned int i; + + snd_iprintf(buffer, "\nCS4398: 7?"); + for (i = 2; i <= 8; ++i) + snd_iprintf(buffer, " %02x", data->cs4398_regs[i]); + snd_iprintf(buffer, "\n"); + dump_cs4362a_registers(data, buffer); +} + static const struct oxygen_model model_xonar_d1 = { .longname = "Asus Virtuoso 100", .chip = "AV200", @@ -396,6 +420,7 @@ static const struct oxygen_model model_xonar_d1 = { .update_dac_mute = update_cs43xx_mute, .update_center_lfe_mix = update_cs43xx_center_lfe_mix, .ac97_switch = xonar_d1_line_mic_ac97_switch, + .dump_registers = dump_d1_registers, .dac_tlv = cs4362a_db_scale, .model_data_size = sizeof(struct xonar_cs43xx), .device_config = PLAYBACK_0_TO_I2S | diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 5193d73a916d..dc69fddf2e6e 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -150,6 +150,7 @@ #include #include #include +#include #include #include #include @@ -192,7 +193,7 @@ struct xonar_pcm179x { bool hp_active; s8 hp_gain_offset; bool has_cs2000; - u8 cs2000_fun_cfg_1; + u8 cs2000_regs[0x1f]; }; struct xonar_hdav { @@ -251,16 +252,14 @@ static void cs2000_write(struct oxygen *chip, u8 reg, u8 value) struct xonar_pcm179x *data = chip->model_data; oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value); - if (reg == CS2000_FUN_CFG_1) - data->cs2000_fun_cfg_1 = value; + data->cs2000_regs[reg] = value; } static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value) { struct xonar_pcm179x *data = chip->model_data; - if (reg != CS2000_FUN_CFG_1 || - value != data->cs2000_fun_cfg_1) + if (value != data->cs2000_regs[reg]) cs2000_write(chip, reg, value); } @@ -414,7 +413,8 @@ static void cs2000_registers_init(struct oxygen *chip) cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10); cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00); cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00); - cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1); + cs2000_write(chip, CS2000_FUN_CFG_1, + data->cs2000_regs[CS2000_FUN_CFG_1]); cs2000_write(chip, CS2000_FUN_CFG_2, 0); cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2); } @@ -425,7 +425,7 @@ static void xonar_st_init(struct oxygen *chip) data->generic.anti_pop_delay = 100; data->has_cs2000 = 1; - data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; + data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1; oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | @@ -997,6 +997,45 @@ static int xonar_st_mixer_init(struct oxygen *chip) return 0; } +static void dump_pcm1796_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_pcm179x *data = chip->model_data; + unsigned int dac, i; + + for (dac = 0; dac < data->dacs; ++dac) { + snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1); + for (i = 0; i < 5; ++i) + snd_iprintf(buffer, " %02x", + data->pcm1796_regs[dac][i]); + } + snd_iprintf(buffer, "\n"); +} + +static void dump_cs2000_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_pcm179x *data = chip->model_data; + unsigned int i; + + if (data->has_cs2000) { + snd_iprintf(buffer, "\nCS2000:\n00: "); + for (i = 1; i < 0x10; ++i) + snd_iprintf(buffer, " %02x", data->cs2000_regs[i]); + snd_iprintf(buffer, "\n10:"); + for (i = 0x10; i < 0x1f; ++i) + snd_iprintf(buffer, " %02x", data->cs2000_regs[i]); + snd_iprintf(buffer, "\n"); + } +} + +static void dump_st_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + dump_pcm1796_registers(chip, buffer); + dump_cs2000_registers(chip, buffer); +} + static const struct oxygen_model model_xonar_d2 = { .longname = "Asus Virtuoso 200", .chip = "AV200", @@ -1011,6 +1050,7 @@ static const struct oxygen_model model_xonar_d2 = { .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, .update_dac_mute = update_pcm1796_mute, + .dump_registers = dump_pcm1796_registers, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_pcm179x), .device_config = PLAYBACK_0_TO_I2S | @@ -1046,6 +1086,7 @@ static const struct oxygen_model model_xonar_hdav = { .update_dac_mute = update_pcm1796_mute, .uart_input = xonar_hdmi_uart_input, .ac97_switch = xonar_line_mic_ac97_switch, + .dump_registers = dump_pcm1796_registers, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_hdav), .device_config = PLAYBACK_0_TO_I2S | @@ -1075,6 +1116,7 @@ static const struct oxygen_model model_xonar_st = { .update_dac_volume = update_pcm1796_volume, .update_dac_mute = update_pcm1796_mute, .ac97_switch = xonar_line_mic_ac97_switch, + .dump_registers = dump_st_registers, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_pcm179x), .device_config = PLAYBACK_0_TO_I2S | diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 200f7601276f..2b5e69b64708 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1062,6 +1063,34 @@ static int xonar_ds_mixer_init(struct oxygen *chip) return 0; } +static void dump_wm8776_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_wm87x6 *data = chip->model_data; + unsigned int i; + + snd_iprintf(buffer, "\nWM8776:\n00:"); + for (i = 0; i < 0x10; ++i) + snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); + snd_iprintf(buffer, "\n10:"); + for (i = 0x10; i < 0x17; ++i) + snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); + snd_iprintf(buffer, "\n"); +} + +static void dump_wm87x6_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_wm87x6 *data = chip->model_data; + unsigned int i; + + dump_wm8776_registers(chip, buffer); + snd_iprintf(buffer, "\nWM8766:\n00:"); + for (i = 0; i < 0x10; ++i) + snd_iprintf(buffer, " %03x", data->wm8766_regs[i]); + snd_iprintf(buffer, "\n"); +} + static const struct oxygen_model model_xonar_ds = { .shortname = "Xonar DS", .longname = "Asus Virtuoso 66", @@ -1079,6 +1108,7 @@ static const struct oxygen_model model_xonar_ds = { .update_dac_mute = update_wm87x6_mute, .update_center_lfe_mix = update_wm8766_center_lfe_mix, .gpio_changed = xonar_ds_gpio_changed, + .dump_registers = dump_wm87x6_registers, .dac_tlv = wm87x6_dac_db_scale, .model_data_size = sizeof(struct xonar_wm87x6), .device_config = PLAYBACK_0_TO_I2S | -- cgit v1.2.3 From e2943efa4fda376903974e33298b29091fc596b3 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:42:00 +0100 Subject: ALSA: oxygen: show correct package ID Instead of the hardcoded "CMI8788", show the actual chip name. Note: This is neither what the chip is (it's always the same), nor what the chip is actually called. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_lib.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index e581e7ab216c..3078ed66ad61 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -202,7 +202,13 @@ static void oxygen_proc_read(struct snd_info_entry *entry, struct oxygen *chip = entry->private_data; int i, j; - snd_iprintf(buffer, "CMI8788:\n"); + switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) { + case OXYGEN_PACKAGE_ID_8786: i = '6'; break; + case OXYGEN_PACKAGE_ID_8787: i = '7'; break; + case OXYGEN_PACKAGE_ID_8788: i = '8'; break; + default: i = '?'; break; + } + snd_iprintf(buffer, "CMI878%c:\n", i); for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; ++j) -- cgit v1.2.3 From de664936930dae5469170f7eed24bcff7e91ef82 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:42:48 +0100 Subject: ALSA: oxygen: update hardware comments Reformat and update the comments that describe the hardware connections on the various models. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 24 ++++--- sound/pci/oxygen/xonar_cs43xx.c | 33 +++++---- sound/pci/oxygen/xonar_pcm179x.c | 148 ++++++++++++++++++++++++--------------- sound/pci/oxygen/xonar_wm87x6.c | 43 +++++++++--- 4 files changed, 154 insertions(+), 94 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index a58e448fc1bf..dc47977becae 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -20,19 +20,25 @@ /* * CMI8788: * - * SPI 0 -> 1st AK4396 (front) - * SPI 1 -> 2nd AK4396 (surround) - * SPI 2 -> 3rd AK4396 (center/LFE) - * SPI 3 -> WM8785 - * SPI 4 -> 4th AK4396 (back) + * SPI 0 -> 1st AK4396 (front) + * SPI 1 -> 2nd AK4396 (surround) + * SPI 2 -> 3rd AK4396 (center/LFE) + * SPI 3 -> WM8785 + * SPI 4 -> 4th AK4396 (back) * - * GPIO 0 -> DFS0 of AK5385 - * GPIO 1 -> DFS1 of AK5385 - * GPIO 8 -> enable headphone amplifier on HT-Omega models + * GPIO 0 -> DFS0 of AK5385 + * GPIO 1 -> DFS1 of AK5385 + * GPIO 8 -> enable headphone amplifier on HT-Omega models * * CM9780: * - * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * CD_IN <- CD + * MIC_IN <- mic + * + * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input */ #include diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 092addb15e13..de32895b3172 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -22,29 +22,28 @@ * * CMI8788: * - * I²C <-> CS4398 (front) - * <-> CS4362A (surround, center/LFE, back) + * I²C <-> CS4398 (addr 1001111) (front) + * <-> CS4362A (addr 0011000) (surround, center/LFE, back) * - * GPI 0 <- external power present (DX only) + * GPI 0 <- external power present (DX only) * - * GPIO 0 -> enable output to speakers - * GPIO 1 -> route output to front panel - * GPIO 2 -> M0 of CS5361 - * GPIO 3 -> M1 of CS5361 - * GPIO 8 -> route input jack to line-in (0) or mic-in (1) + * GPIO 0 -> enable output to speakers + * GPIO 1 -> route output to front panel + * GPIO 2 -> M0 of CS5361 + * GPIO 3 -> M1 of CS5361 + * GPIO 6 -> ? + * GPIO 7 -> ? + * GPIO 8 -> route input jack to line-in (0) or mic-in (1) * - * CS4398: - * - * AD0 <- 1 - * AD1 <- 1 - * - * CS4362A: + * CM9780: * - * AD0 <- 0 + * LINE_OUT -> input of ADC * - * CM9780: + * AUX_IN <- aux + * MIC_IN <- mic + * FMIC_IN <- front mic * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input */ #include diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index dc69fddf2e6e..bf357c01afd2 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -22,20 +22,26 @@ * * CMI8788: * - * SPI 0 -> 1st PCM1796 (front) - * SPI 1 -> 2nd PCM1796 (surround) - * SPI 2 -> 3rd PCM1796 (center/LFE) - * SPI 4 -> 4th PCM1796 (back) + * SPI 0 -> 1st PCM1796 (front) + * SPI 1 -> 2nd PCM1796 (surround) + * SPI 2 -> 3rd PCM1796 (center/LFE) + * SPI 4 -> 4th PCM1796 (back) * - * GPIO 2 -> M0 of CS5381 - * GPIO 3 -> M1 of CS5381 - * GPIO 5 <- external power present (D2X only) - * GPIO 7 -> ALT - * GPIO 8 -> enable output to speakers + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 5 <- external power present (D2X only) + * GPIO 7 -> ALT + * GPIO 8 -> enable output to speakers * * CM9780: * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * VIDEO_IN <- CD + * FMIC_IN <- mic + * + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input */ /* @@ -44,52 +50,53 @@ * * CMI8788: * - * I²C <-> PCM1796 (front) - * - * GPI 0 <- external power present + * I²C <-> PCM1796 (addr 1001100) (front) * - * GPIO 0 -> enable output to speakers - * GPIO 2 -> M0 of CS5381 - * GPIO 3 -> M1 of CS5381 - * GPIO 8 -> route input jack to line-in (0) or mic-in (1) + * GPI 0 <- external power present * - * TXD -> HDMI controller - * RXD <- HDMI controller + * GPIO 0 -> enable HDMI (0) or speaker (1) output + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 4 <- daughterboard detection + * GPIO 5 <- daughterboard detection + * GPIO 6 -> ? + * GPIO 7 -> ? + * GPIO 8 -> route input jack to line-in (0) or mic-in (1) * - * PCM1796 front: AD1,0 <- 0,0 + * UART <-> HDMI controller * * CM9780: * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * CD_IN <- CD + * MIC_IN <- mic + * + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input * * no daughterboard * ---------------- * - * GPIO 4 <- 1 + * GPIO 4 <- 1 * * H6 daughterboard * ---------------- * - * GPIO 4 <- 0 - * GPIO 5 <- 0 - * - * I²C <-> PCM1796 (surround) - * <-> PCM1796 (center/LFE) - * <-> PCM1796 (back) + * GPIO 4 <- 0 + * GPIO 5 <- 0 * - * PCM1796 surround: AD1,0 <- 0,1 - * PCM1796 center/LFE: AD1,0 <- 1,0 - * PCM1796 back: AD1,0 <- 1,1 + * I²C <-> PCM1796 (addr 1001101) (surround) + * <-> PCM1796 (addr 1001110) (center/LFE) + * <-> PCM1796 (addr 1001111) (back) * * unknown daughterboard * --------------------- * - * GPIO 4 <- 0 - * GPIO 5 <- 1 - * - * I²C <-> CS4362A (surround, center/LFE, back) + * GPIO 4 <- 0 + * GPIO 5 <- 1 * - * CS4362A: AD0 <- 0 + * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back) */ /* @@ -98,32 +105,35 @@ * * CMI8788: * - * I²C <-> PCM1792A - * <-> CS2000 (ST only) + * I²C <-> PCM1792A (addr 1001100) + * <-> CS2000 (addr 1001110) (ST only) * - * ADC1 MCLK -> REF_CLK of CS2000 (ST only) + * ADC1 MCLK -> REF_CLK of CS2000 (ST only) * - * GPI 0 <- external power present (STX only) + * GPI 0 <- external power present (STX only) * - * GPIO 0 -> enable output to speakers - * GPIO 1 -> route HP to front panel (0) or rear jack (1) - * GPIO 2 -> M0 of CS5381 - * GPIO 3 -> M1 of CS5381 - * GPIO 7 -> route output to speaker jacks (0) or HP (1) - * GPIO 8 -> route input jack to line-in (0) or mic-in (1) + * GPIO 0 -> enable output to speakers + * GPIO 1 -> route HP to front panel (0) or rear jack (1) + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 4 <- daughterboard detection + * GPIO 5 <- daughterboard detection + * GPIO 6 -> ? + * GPIO 7 -> route output to speaker jacks (0) or HP (1) + * GPIO 8 -> route input jack to line-in (0) or mic-in (1) * * PCM1792A: * - * AD1,0 <- 0,0 - * SCK <- CLK_OUT of CS2000 (ST only) + * SCK <- CLK_OUT of CS2000 (ST only) * - * CS2000: + * CM9780: * - * AD0 <- 0 + * LINE_OUT -> input of ADC * - * CM9780: + * AUX_IN <- aux + * MIC_IN <- mic * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input * * H6 daughterboard * ---------------- @@ -133,15 +143,39 @@ */ /* - * Xonar HDAV1.3 Slim - * ------------------ + * Xonar Xense + * ----------- * * CMI8788: * - * GPIO 1 -> enable output + * I²C <-> PCM1796 (addr 1001100) (front) + * <-> CS4362A (addr 0011000) (surround, center/LFE, back) + * <-> CS2000 (addr 1001110) + * + * ADC1 MCLK -> REF_CLK of CS2000 + * + * GPI 0 <- external power present + * + * GPIO 0 -> enable output + * GPIO 1 -> route HP to front panel (0) or rear jack (1) + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 4 -> enable output + * GPIO 5 -> enable output + * GPIO 6 -> ? + * GPIO 7 -> route output to HP (0) or speaker (1) + * GPIO 8 -> route input jack to mic-in (0) or line-in (1) + * + * CM9780: + * + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * VIDEO_IN <- ? + * FMIC_IN <- mic * - * TXD -> HDMI controller - * RXD <- HDMI controller + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * GPO 1 -> route mic-in from input jack (0) or front panel header (1) */ #include diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 2b5e69b64708..1705d1e93115 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -22,20 +22,41 @@ * * CMI8788: * - * SPI 0 -> WM8766 (surround, center/LFE, back) - * SPI 1 -> WM8776 (front, input) + * SPI 0 -> WM8766 (surround, center/LFE, back) + * SPI 1 -> WM8776 (front, input) * - * GPIO 4 <- headphone detect, 0 = plugged - * GPIO 6 -> route input jack to mic-in (0) or line-in (1) - * GPIO 7 -> enable output to front L/R speaker channels - * GPIO 8 -> enable output to other speaker channels and front panel headphone + * GPIO 4 <- headphone detect, 0 = plugged + * GPIO 6 -> route input jack to mic-in (0) or line-in (1) + * GPIO 7 -> enable output to front L/R speaker channels + * GPIO 8 -> enable output to other speaker channels and front panel headphone * - * WM8766: + * WM8776: * - * input 1 <- line - * input 2 <- mic - * input 3 <- front mic - * input 4 <- aux + * input 1 <- line + * input 2 <- mic + * input 3 <- front mic + * input 4 <- aux + */ + +/* + * Xonar HDAV1.3 Slim + * ------------------ + * + * CMI8788: + * + * I²C <-> WM8776 (addr 0011010) + * + * GPIO 0 -> disable HDMI output + * GPIO 1 -> enable HP output + * GPIO 6 -> firmware EEPROM I²C clock + * GPIO 7 <-> firmware EEPROM I²C data + * + * UART <-> HDMI controller + * + * WM8776: + * + * input 1 <- mic + * input 2 <- aux */ #include -- cgit v1.2.3 From 116dcde638065a6b94344ca570e1e79c8e857826 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 23 Nov 2010 10:23:40 +0100 Subject: ALSA: HDA: Remove unconnected PCM devices for Intel HDMI Some newer chips have more than one HDMI output, but usually not all of them are exposed as physical jacks. Removing the unused PCM devices (as indicated by BIOS in the pin config default) will reduce user confusion as they currently have to choose between several HDMI devices, some of them not working anyway. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8f07719ef985..d1b1b5796c98 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -904,23 +904,28 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) spec->pin[spec->num_pins] = pin_nid; spec->num_pins++; - /* - * It is assumed that converter nodes come first in the node list and - * hence have been registered and usable now. - */ return hdmi_read_pin_conn(codec, pin_nid); } static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) { + int i, found_pin = 0; struct hdmi_spec *spec = codec->spec; - if (spec->num_cvts >= MAX_HDMI_CVTS) { - snd_printk(KERN_WARNING - "HDMI: no space for converter %d\n", nid); - return -E2BIG; + for (i = 0; i < spec->num_pins; i++) + if (nid == spec->pin_cvt[i]) { + found_pin = 1; + break; + } + + if (!found_pin) { + snd_printdd("HDMI: Skipping node %d (no connection)\n", nid); + return -EINVAL; } + if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) + return -E2BIG; + spec->cvt[spec->num_cvts] = nid; spec->num_cvts++; @@ -931,6 +936,8 @@ static int hdmi_parse_codec(struct hda_codec *codec) { hda_nid_t nid; int i, nodes; + int num_tmp_cvts = 0; + hda_nid_t tmp_cvt[MAX_HDMI_CVTS]; nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); if (!nid || nodes < 0) { @@ -941,6 +948,7 @@ static int hdmi_parse_codec(struct hda_codec *codec) for (i = 0; i < nodes; i++, nid++) { unsigned int caps; unsigned int type; + unsigned int config; caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); type = get_wcaps_type(caps); @@ -950,17 +958,32 @@ static int hdmi_parse_codec(struct hda_codec *codec) switch (type) { case AC_WID_AUD_OUT: - hdmi_add_cvt(codec, nid); + if (num_tmp_cvts >= MAX_HDMI_CVTS) { + snd_printk(KERN_WARNING + "HDMI: no space for converter %d\n", nid); + continue; + } + tmp_cvt[num_tmp_cvts] = nid; + num_tmp_cvts++; break; case AC_WID_PIN: caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) continue; + + config = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) + continue; + hdmi_add_pin(codec, nid); break; } } + for (i = 0; i < num_tmp_cvts; i++) + hdmi_add_cvt(codec, tmp_cvt[i]); + /* * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event * can be lost and presence sense verb will become inaccurate if the -- cgit v1.2.3 From e1eb5f10069b7c393174b3a272ad647537969862 Mon Sep 17 00:00:00 2001 From: Todd Broch Date: Mon, 6 Dec 2010 11:19:51 -0800 Subject: ALSA: hda: Add modelname lookup and fixup for realtek codecs Facilitate fixup for realtek codecs via modelname lookup of fixup data. Fallback to quirk based lookup in absence of model definition. Signed-off-by: Todd Broch Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 61 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 12 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0badedab1335..9ba4279c690d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1677,6 +1677,11 @@ struct alc_pincfg { u32 val; }; +struct alc_model_fixup { + const int id; + const char *name; +}; + struct alc_fixup { unsigned int sku; const struct alc_pincfg *pins; @@ -1685,23 +1690,19 @@ struct alc_fixup { int pre_init); }; -static void alc_pick_fixup(struct hda_codec *codec, - const struct snd_pci_quirk *quirk, - const struct alc_fixup *fix, - int pre_init) +static void __alc_pick_fixup(struct hda_codec *codec, + const struct alc_fixup *fix, + const char *modelname, + int pre_init) { const struct alc_pincfg *cfg; struct alc_spec *spec; - quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); - if (!quirk) - return; - fix += quirk->value; cfg = fix->pins; if (pre_init && fix->sku) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif spec = codec->spec; spec->cdefine.sku_cfg = fix->sku; @@ -1710,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec, if (pre_init && cfg) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif for (; cfg->nid; cfg++) snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); @@ -1718,19 +1719,55 @@ static void alc_pick_fixup(struct hda_codec *codec, if (!pre_init && fix->verbs) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif add_verb(codec->spec, fix->verbs); } if (fix->func) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif fix->func(codec, fix, pre_init); } } +static void alc_pick_fixup(struct hda_codec *codec, + const struct snd_pci_quirk *quirk, + const struct alc_fixup *fix, + int pre_init) +{ + quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); + if (quirk) { + fix += quirk->value; +#ifdef CONFIG_SND_DEBUG_VERBOSE + __alc_pick_fixup(codec, fix, quirk->name, pre_init); +#else + __alc_pick_fixup(codec, fix, NULL, pre_init); +#endif + } +} + +static void alc_pick_fixup_model(struct hda_codec *codec, + const struct alc_model_fixup *models, + const struct snd_pci_quirk *quirk, + const struct alc_fixup *fix, + int pre_init) +{ + if (codec->modelname && models) { + while (models->name) { + if (!strcmp(codec->modelname, models->name)) { + fix += models->id; + break; + } + models++; + } + __alc_pick_fixup(codec, fix, codec->modelname, pre_init); + } else { + alc_pick_fixup(codec, quirk, fix, pre_init); + } +} + static int alc_read_coef_idx(struct hda_codec *codec, unsigned int coef_idx) { -- cgit v1.2.3 From 6be7948ff4fa7662c1ee1994e1798074f8e832ed Mon Sep 17 00:00:00 2001 From: Todd Broch Date: Tue, 7 Dec 2010 16:51:05 -0800 Subject: ALSA: hda: Add fixup for mario system create fixup function for the mario model and override amp capabilities for NID 0x2 Signed-off-by: Todd Broch Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9ba4279c690d..cd2d3a5efa50 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19332,9 +19332,21 @@ static void alc662_auto_init(struct hda_codec *codec) alc_inithook(codec); } +static void alc272_fixup_mario(struct hda_codec *codec, + const struct alc_fixup *fix, int pre_init) { + if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, + (0x3b << AC_AMPCAP_OFFSET_SHIFT) | + (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (0 << AC_AMPCAP_MUTE_SHIFT))) + printk(KERN_WARNING + "hda_codec: failed to override amp caps for NID 0x2\n"); +} + enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_IDEAPAD, + ALC272_FIXUP_MARIO, }; static const struct alc_fixup alc662_fixups[] = { @@ -19350,6 +19362,9 @@ static const struct alc_fixup alc662_fixups[] = { { } } }, + [ALC272_FIXUP_MARIO] = { + .func = alc272_fixup_mario, + } }; static struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -19360,6 +19375,10 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = { {} }; +static const struct alc_model_fixup alc662_fixup_models[] = { + {.id = ALC272_FIXUP_MARIO, .name = "mario"}, + {} +}; static int patch_alc662(struct hda_codec *codec) @@ -19459,7 +19478,8 @@ static int patch_alc662(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC662_AUTO) { spec->init_hook = alc662_auto_init; - alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0); + alc_pick_fixup_model(codec, alc662_fixup_models, + alc662_fixup_tbl, alc662_fixups, 0); } alc_init_jacks(codec); -- cgit v1.2.3 From 93430096f9d757104080f40f51afb2dada8877b5 Mon Sep 17 00:00:00 2001 From: Brian Bloniarz Date: Wed, 8 Dec 2010 12:45:20 -0800 Subject: ALSA: ice1712 - working M-Audio Delta 66E support Rev. E of the M-Audio Delta 66 is partially supported (commit ef2cd2ccad66b4aba518eca7514eface267ee0f3), but the layout of the GPIO pins was still unclear. This patch adds the GPIO definitions so that communication to the CS8247 & 2x AK4524 works correctly. ALSA bug#3327 has more details; users cap & jhunt report there that the GPIO wiring is similar to the Digigram VX442 (chip select: pin 4 = CS8427, pin 5 = AK4524 #0, pin 6 = AK4524 #1). There has been a lot of conflicting information in the bug, but given these definitions, my Delta 66E works; I tested analog in&out at 44.1kHz & 96kHz, analog gain settings, S/PDIF clock sync, and S/PDIF in&out at 44.1kHz. Signed-off-by: Brian Bloniarz Signed-off-by: Takashi Iwai --- sound/pci/ice1712/delta.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- sound/pci/ice1712/delta.h | 11 +++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 712c1710f9a2..7b62de089fee 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -96,6 +96,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice) tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC; tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL; break; + case ICE1712_SUBDEVICE_DELTA66E: + tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A | + ICE1712_DELTA_66E_CS_CHIP_B; + tmp &= ~ICE1712_DELTA_66E_CS_CS8427; + break; case ICE1712_SUBDEVICE_VX442: tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B; tmp &= ~ICE1712_VX442_CS_DIGITAL; @@ -119,6 +124,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp) case ICE1712_SUBDEVICE_DELTA410: tmp |= ICE1712_DELTA_AP_CS_DIGITAL; break; + case ICE1712_SUBDEVICE_DELTA66E: + tmp |= ICE1712_DELTA_66E_CS_CS8427; + break; case ICE1712_SUBDEVICE_VX442: tmp |= ICE1712_VX442_CS_DIGITAL; break; @@ -275,6 +283,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip) priv->cs_addr = chip << 4; } +/* + * AK4524 on Delta66 rev E to choose the chip address + */ +static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip) +{ + struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; + struct snd_ice1712 *ice = ak->private_data[0]; + + snd_ice1712_save_gpio_status(ice); + priv->cs_mask = + priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A : + ICE1712_DELTA_66E_CS_CHIP_B; +} + /* * AK4528 on VX442 to choose the chip mask */ @@ -487,6 +509,29 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { .mask_flags = 0, }; +static struct snd_akm4xxx akm_delta66e __devinitdata = { + .type = SND_AK4524, + .num_adcs = 4, + .num_dacs = 4, + .ops = { + .lock = delta66e_ak4524_lock, + .set_rate_val = delta_ak4524_set_rate_val + } +}; + +static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = { + .caddr = 2, + .cif = 0, /* the default level of the CIF pin from AK4524 */ + .data_mask = ICE1712_DELTA_66E_DOUT, + .clk_mask = ICE1712_DELTA_66E_CCLK, + .cs_mask = 0, + .cs_addr = 0, /* set later */ + .cs_none = 0, + .add_flags = 0, + .mask_flags = 0, +}; + + static struct snd_akm4xxx akm_delta44 __devinitdata = { .type = SND_AK4524, .num_adcs = 4, @@ -644,9 +689,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice); break; case ICE1712_SUBDEVICE_VX442: - case ICE1712_SUBDEVICE_DELTA66E: err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice); break; + case ICE1712_SUBDEVICE_DELTA66E: + err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice); + break; default: snd_BUG(); return -EINVAL; diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index 1a0ac6cd6501..11a9c3a76507 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -144,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; #define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */ #define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */ +/* M-Audio Delta 66 rev. E definitions. + * Newer revisions of Delta 66 have CS8427 over SPI for + * S/PDIF transceiver instead of CS8404/CS8414. */ +/* 0x01 = DFS */ +#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */ +#define ICE1712_DELTA_66E_DIN 0x04 /* data input */ +#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */ +#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */ +#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */ +#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */ + /* Digigram VX442 definitions */ #define ICE1712_VX442_CCLK 0x02 /* SPI clock */ #define ICE1712_VX442_DIN 0x04 /* data input */ -- cgit v1.2.3 From 5b84ba26a9672e615897234fa5efd3eea2d6b295 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Dec 2010 17:51:26 +0100 Subject: sound: don't use flush_scheduled_work() flush_scheduled_work() is deprecated and scheduled to be removed. * cancel[_delayed]_work() + flush_scheduled_work() -> cancel[_delayed]_work_sync(). * wm8350, wm8753 and soc-core use custom code to cancel a delayed work, execute it immediately if it was pending and wait for its completion. This is equivalent to flush_delayed_work_sync(). Use it instead. Signed-off-by: Tejun Heo Acked-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/aoa/core/gpio-feature.c | 7 +++---- sound/aoa/core/gpio-pmf.c | 7 +++---- sound/i2c/other/ak4113.c | 5 ++--- sound/i2c/other/ak4114.c | 5 ++--- sound/pci/ac97/ac97_codec.c | 6 ++---- sound/pci/hda/patch_via.c | 3 +-- sound/pci/oxygen/oxygen_lib.c | 6 ++++-- sound/soc/codecs/wm8350.c | 9 +-------- sound/soc/codecs/wm8753.c | 21 +-------------------- sound/soc/soc-core.c | 25 +++---------------------- 10 files changed, 22 insertions(+), 72 deletions(-) (limited to 'sound/pci') diff --git a/sound/aoa/core/gpio-feature.c b/sound/aoa/core/gpio-feature.c index de8e03afa97b..faa317490545 100644 --- a/sound/aoa/core/gpio-feature.c +++ b/sound/aoa/core/gpio-feature.c @@ -287,10 +287,9 @@ static void ftr_gpio_exit(struct gpio_runtime *rt) free_irq(linein_detect_irq, &rt->line_in_notify); if (rt->line_out_notify.gpio_private) free_irq(lineout_detect_irq, &rt->line_out_notify); - cancel_delayed_work(&rt->headphone_notify.work); - cancel_delayed_work(&rt->line_in_notify.work); - cancel_delayed_work(&rt->line_out_notify.work); - flush_scheduled_work(); + cancel_delayed_work_sync(&rt->headphone_notify.work); + cancel_delayed_work_sync(&rt->line_in_notify.work); + cancel_delayed_work_sync(&rt->line_out_notify.work); mutex_destroy(&rt->headphone_notify.mutex); mutex_destroy(&rt->line_in_notify.mutex); mutex_destroy(&rt->line_out_notify.mutex); diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c index 7e267c9379bc..c8d8a1a6f964 100644 --- a/sound/aoa/core/gpio-pmf.c +++ b/sound/aoa/core/gpio-pmf.c @@ -107,10 +107,9 @@ static void pmf_gpio_exit(struct gpio_runtime *rt) /* make sure no work is pending before freeing * all things */ - cancel_delayed_work(&rt->headphone_notify.work); - cancel_delayed_work(&rt->line_in_notify.work); - cancel_delayed_work(&rt->line_out_notify.work); - flush_scheduled_work(); + cancel_delayed_work_sync(&rt->headphone_notify.work); + cancel_delayed_work_sync(&rt->line_in_notify.work); + cancel_delayed_work_sync(&rt->line_out_notify.work); mutex_destroy(&rt->headphone_notify.mutex); mutex_destroy(&rt->line_in_notify.mutex); diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index 971a84a4fa77..c424d329f806 100644 --- a/sound/i2c/other/ak4113.c +++ b/sound/i2c/other/ak4113.c @@ -57,8 +57,7 @@ static void snd_ak4113_free(struct ak4113 *chip) { chip->init = 1; /* don't schedule new work */ mb(); - cancel_delayed_work(&chip->work); - flush_scheduled_work(); + cancel_delayed_work_sync(&chip->work); kfree(chip); } @@ -141,7 +140,7 @@ void snd_ak4113_reinit(struct ak4113 *chip) { chip->init = 1; mb(); - flush_scheduled_work(); + flush_delayed_work_sync(&chip->work); ak4113_init_regs(chip); /* bring up statistics / event queing */ chip->init = 0; diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index 0341451f814c..d9fb537b0b94 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c @@ -67,8 +67,7 @@ static void snd_ak4114_free(struct ak4114 *chip) { chip->init = 1; /* don't schedule new work */ mb(); - cancel_delayed_work(&chip->work); - flush_scheduled_work(); + cancel_delayed_work_sync(&chip->work); kfree(chip); } @@ -154,7 +153,7 @@ void snd_ak4114_reinit(struct ak4114 *chip) { chip->init = 1; mb(); - flush_scheduled_work(); + flush_delayed_work_sync(&chip->work); ak4114_init_regs(chip); /* bring up statistics / event queing */ chip->init = 0; diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index a7630e9edf8a..0fc614ce16c1 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1014,8 +1014,7 @@ static int snd_ac97_free(struct snd_ac97 *ac97) { if (ac97) { #ifdef CONFIG_SND_AC97_POWER_SAVE - cancel_delayed_work(&ac97->power_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&ac97->power_work); #endif snd_ac97_proc_done(ac97); if (ac97->bus) @@ -2456,8 +2455,7 @@ void snd_ac97_suspend(struct snd_ac97 *ac97) if (ac97->build_ops->suspend) ac97->build_ops->suspend(ac97); #ifdef CONFIG_SND_AC97_POWER_SAVE - cancel_delayed_work(&ac97->power_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&ac97->power_work); #endif snd_ac97_powerdown(ac97); } diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index d1c3f8defc48..7f4852a478a1 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -263,8 +263,7 @@ static void vt1708_stop_hp_work(struct via_spec *spec) return; snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, !spec->vt1708_jack_detectect); - cancel_delayed_work(&spec->vt1708_hp_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&spec->vt1708_hp_work); } diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index e5ebe56fb0c5..969605fbcb7f 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -557,7 +557,8 @@ static void oxygen_card_free(struct snd_card *card) oxygen_shutdown(chip); if (chip->irq >= 0) free_irq(chip->irq, chip); - flush_scheduled_work(); + flush_work_sync(&chip->spdif_input_bits_work); + flush_work_sync(&chip->gpio_work); chip->model.cleanup(chip); kfree(chip->model_data); mutex_destroy(&chip->mutex); @@ -733,7 +734,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) spin_unlock_irq(&chip->reg_lock); synchronize_irq(chip->irq); - flush_scheduled_work(); + flush_work_sync(&chip->spdif_input_bits_work); + flush_work_sync(&chip->gpio_work); chip->interrupt_mask = saved_interrupt_mask; pci_disable_device(pci); diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 7611add7f8c3..b3e9fac172e5 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1626,7 +1626,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) { struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); struct wm8350 *wm8350 = dev_get_platdata(codec->dev); - int ret; wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, WM8350_JDL_ENA | WM8350_JDR_ENA); @@ -1641,15 +1640,9 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) priv->hpr.jack = NULL; priv->mic.jack = NULL; - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(&codec->delayed_work); - /* if there was any work waiting then we run it now and * wait for its completion */ - if (ret) { - schedule_delayed_work(&codec->delayed_work, 0); - flush_scheduled_work(); - } + flush_delayed_work_sync(&codec->delayed_work); wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8f679a13f2bc..84a23675cba9 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1526,25 +1526,6 @@ static int wm8753_resume(struct snd_soc_codec *codec) return 0; } -/* - * This function forces any delayed work to be queued and run. - */ -static int run_delayed_work(struct delayed_work *dwork) -{ - int ret; - - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(dwork); - - /* if there was any work waiting then we run it now and - * wait for it's completion */ - if (ret) { - schedule_delayed_work(dwork, 0); - flush_scheduled_work(); - } - return ret; -} - static int wm8753_probe(struct snd_soc_codec *codec) { struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); @@ -1604,7 +1585,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) /* power down chip */ static int wm8753_remove(struct snd_soc_codec *codec) { - run_delayed_work(&codec->delayed_work); + flush_delayed_work_sync(&codec->delayed_work); wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 441285ade024..b54ea9a0a1db 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -67,25 +67,6 @@ static int pmdown_time = 5000; module_param(pmdown_time, int, 0); MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); -/* - * This function forces any delayed work to be queued and run. - */ -static int run_delayed_work(struct delayed_work *dwork) -{ - int ret; - - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(dwork); - - /* if there was any work waiting then we run it now and - * wait for it's completion */ - if (ret) { - schedule_delayed_work(dwork, 0); - flush_scheduled_work(); - } - return ret; -} - /* codec register dump */ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) { @@ -1016,7 +997,7 @@ static int soc_suspend(struct device *dev) /* close any waiting streams and save state */ for (i = 0; i < card->num_rtd; i++) { - run_delayed_work(&card->rtd[i].delayed_work); + flush_delayed_work_sync(&card->rtd[i].delayed_work); card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level; } @@ -1687,7 +1668,7 @@ static int soc_remove(struct platform_device *pdev) /* make sure any delayed work runs */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; - run_delayed_work(&rtd->delayed_work); + flush_delayed_work_sync(&rtd->delayed_work); } /* remove and free each DAI */ @@ -1718,7 +1699,7 @@ static int soc_poweroff(struct device *dev) * now, we're shutting down so no imminent restart. */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; - run_delayed_work(&rtd->delayed_work); + flush_delayed_work_sync(&rtd->delayed_work); } snd_soc_dapm_shutdown(card); -- cgit v1.2.3 From fbb5bb563925db138a8bbfa6a0ea0e089fbd2405 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 13 Dec 2010 12:48:35 +0100 Subject: ALSA: hda - Mute speakers when line-out jack is plugged with Conexant auto mode Mute speakers when a line-out jack is plugged as well as headphone jacks with the new Conexant codec parser in the auto mode. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 46bbf14e91ae..96b286aebde6 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3424,6 +3424,9 @@ static void cx_auto_hp_automute(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, present ? 0 : PIN_OUT); } + for (i = 0; !present && i < cfg->line_outs; i++) + if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) + present = 1; for (i = 0; i < cfg->speaker_outs; i++) { snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -- cgit v1.2.3 From eeb433876cf59438a1e1600a957ff6cc99c860eb Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 16 Dec 2010 12:19:47 +0100 Subject: ALSA: hda - factorize an automute_mic realtek quirk function Multiple quirk functions were using the exact same code to verify if the Mic jack was plugged and mute the Mic accordingly Signed-off-by: Anisse Astier Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cd2d3a5efa50..fc435b59a52f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3352,7 +3352,7 @@ static struct hda_verb alc880_beep_init_verbs[] = { }; /* auto-toggle front mic */ -static void alc880_uniwill_mic_automute(struct hda_codec *codec) +static void alc88x_simple_mic_automute(struct hda_codec *codec) { unsigned int present; unsigned char bits; @@ -3374,7 +3374,7 @@ static void alc880_uniwill_setup(struct hda_codec *codec) static void alc880_uniwill_init_hook(struct hda_codec *codec) { alc_automute_amp(codec); - alc880_uniwill_mic_automute(codec); + alc88x_simple_mic_automute(codec); } static void alc880_uniwill_unsol_event(struct hda_codec *codec, @@ -3385,7 +3385,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, */ switch (res >> 28) { case ALC880_MIC_EVENT: - alc880_uniwill_mic_automute(codec); + alc88x_simple_mic_automute(codec); break; default: alc_automute_amp_unsol_event(codec, res); @@ -9480,15 +9480,6 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) #define alc883_targa_init_hook alc882_targa_init_hook #define alc883_targa_unsol_event alc882_targa_unsol_event -static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_jack_detect(codec, 0x18); - snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -} - static void alc883_clevo_m720_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -9500,7 +9491,7 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec) static void alc883_clevo_m720_init_hook(struct hda_codec *codec) { alc_automute_amp(codec); - alc883_clevo_m720_mic_automute(codec); + alc88x_simple_mic_automute(codec); } static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, @@ -9508,7 +9499,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, { switch (res >> 26) { case ALC880_MIC_EVENT: - alc883_clevo_m720_mic_automute(codec); + alc88x_simple_mic_automute(codec); break; default: alc_automute_amp_unsol_event(codec, res); @@ -16697,18 +16688,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { {} }; -static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x18); - bits = present ? HDA_AMP_MUTE : 0; - - snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); -} - static void alc861vd_lenovo_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -16719,7 +16698,7 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec) static void alc861vd_lenovo_init_hook(struct hda_codec *codec) { alc_automute_amp(codec); - alc861vd_lenovo_mic_automute(codec); + alc88x_simple_mic_automute(codec); } static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, @@ -16727,7 +16706,7 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, { switch (res >> 26) { case ALC880_MIC_EVENT: - alc861vd_lenovo_mic_automute(codec); + alc88x_simple_mic_automute(codec); break; default: alc_automute_amp_unsol_event(codec, res); -- cgit v1.2.3 From 30fac30103185d853cb5cdb4bbed70d629d6da7e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Dec 2010 17:55:42 +0100 Subject: ALSA: hda - Clean up dead code in patch_realtek.c Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fc435b59a52f..4e6f4f6d342f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9214,16 +9214,6 @@ static void alc883_mitac_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[1] = 0x17; } -/* auto-toggle front mic */ -/* -static void alc883_mitac_mic_automute(struct hda_codec *codec) -{ - unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0; - - snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); -} -*/ - static struct hda_verb alc883_mitac_verbs[] = { /* HP */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, -- cgit v1.2.3 From 28c4edb71d21623f1e47422194d865d2b6712fd4 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 20 Dec 2010 14:24:29 +0100 Subject: ALSA: HDA: Rename "Int Mic" to "Internal Mic" "Int Mic" and "Internal Mic" both mean the same thing, so rename the former to the latter in order to clean up the namespace a little. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 36 ++++++++++----------- sound/pci/hda/patch_realtek.c | 72 +++++++++++++++++++++--------------------- 2 files changed, 54 insertions(+), 54 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e584b3dd7aa8..62acf10cf493 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -869,14 +869,14 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, } static struct snd_kcontrol_new cxt5045_mixers[] = { - HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), @@ -910,14 +910,14 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { }; static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { - HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), @@ -947,7 +947,7 @@ static struct hda_verb cxt5045_init_verbs[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, @@ -960,7 +960,7 @@ static struct hda_verb cxt5045_init_verbs[] = { }; static struct hda_verb cxt5045_benq_init_verbs[] = { - /* Int Mic, Mic */ + /* Internal Mic, Mic */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, /* Line In,HP, Amp */ @@ -973,7 +973,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, @@ -1847,7 +1847,7 @@ static struct hda_verb cxt5051_init_verbs[] = { {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, @@ -1874,7 +1874,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, /* SPDIF route: PCM */ @@ -1904,7 +1904,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, @@ -1932,7 +1932,7 @@ static struct hda_verb cxt5051_f700_init_verbs[] = { {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, /* SPDIF route: PCM */ @@ -2729,7 +2729,7 @@ 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", + .name = "Internal 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, @@ -2955,7 +2955,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = { {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* internal microphone */ - {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ + {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */ /* EAPD */ {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ @@ -3010,7 +3010,7 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = { {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* internal microphone */ - {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ + {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */ /* EAPD */ {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5baaf12111ba..e976a4ddb0c3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2169,7 +2169,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { { "Line In", 0x2 }, { "CD", 0x4 }, { "Input Mix", 0xa }, - { "Int Mic", 0xb }, + { "Internal Mic", 0xb }, }, }, { @@ -2843,8 +2843,8 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -7451,7 +7451,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, { "Line", 0x2 }, { "CD", 0x4 }, }, @@ -7461,7 +7461,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, }, }; @@ -8824,9 +8824,9 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 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), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8838,9 +8838,9 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 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), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8986,18 +8986,18 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 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), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -9021,8 +9021,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -11676,7 +11676,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, { "CD", 0x4 }, }, }; @@ -11831,9 +11831,9 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -11867,9 +11867,9 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -13248,7 +13248,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), { } }; @@ -16381,7 +16381,7 @@ static struct hda_input_mux alc861vd_dallas_capture_source = { .num_items = 2, .items = { { "Ext Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, }, }; @@ -16522,7 +16522,7 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { }; /* Pin assignment: Speaker=0x14, HP = 0x15, - * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d + * Ext Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d */ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), @@ -16532,9 +16532,9 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -18551,9 +18551,9 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = { HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -19596,7 +19596,7 @@ static struct snd_kcontrol_new alc680_base_mixer[] = { HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x12, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), { } -- cgit v1.2.3 From 8607f7c4245bc1737989d908e9c5adbfe4f5d06d Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 20 Dec 2010 14:43:54 +0100 Subject: ALSA: HDA: Rename "Ext Mic" and "External Mic" to "Mic" Usually external microphones are just labelled "Mic", so rename "Ext Mic" and "External Mic" to "Mic" to clear up the namespace. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 28 ++++++++++++++-------------- sound/pci/hda/patch_realtek.c | 26 +++++++++++++------------- 2 files changed, 27 insertions(+), 27 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 62acf10cf493..74291f744c68 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -871,14 +871,14 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, static struct snd_kcontrol_new cxt5045_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -912,14 +912,14 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1796,8 +1796,8 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = { static struct snd_kcontrol_new cxt5051_capture_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT), {} @@ -1806,8 +1806,8 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = { static struct snd_kcontrol_new cxt5051_hp_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), + HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT), {} }; @@ -1826,8 +1826,8 @@ static struct snd_kcontrol_new cxt5051_f700_mixers[] = { static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), {} }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e976a4ddb0c3..fceb1e60b352 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2165,7 +2165,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { { .num_items = 5, .items = { - { "Ext Mic", 0x0 }, + { "Mic", 0x0 }, { "Line In", 0x2 }, { "CD", 0x4 }, { "Input Mix", 0xa }, @@ -2175,7 +2175,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { { .num_items = 4, .items = { - { "Ext Mic", 0x0 }, + { "Mic", 0x0 }, { "Line In", 0x2 }, { "CD", 0x4 }, { "Input Mix", 0xa }, @@ -2841,8 +2841,8 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ @@ -13247,7 +13247,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), - HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), { } }; @@ -16380,7 +16380,7 @@ static struct hda_input_mux alc861vd_capture_source = { static struct hda_input_mux alc861vd_dallas_capture_source = { .num_items = 2, .items = { - { "Ext Mic", 0x0 }, + { "Mic", 0x0 }, { "Internal Mic", 0x1 }, }, }; @@ -16522,16 +16522,16 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { }; /* Pin assignment: Speaker=0x14, HP = 0x15, - * Ext Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d + * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d */ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -18547,9 +18547,9 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), -- cgit v1.2.3 From 10528020d7323778b60c2de04754a2615a88d002 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 20 Dec 2010 14:50:59 +0100 Subject: ALSA: HDA: Rename "e-Mic" and "i-Mic" to "Mic" and "Internal Mic" Change non-standard mic control names to standard control names to clean up the namespace. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fceb1e60b352..cad88f476acc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -17534,13 +17534,13 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -17684,8 +17684,8 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -17696,8 +17696,8 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), { } /* end */ @@ -18530,13 +18530,13 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic/LineIn Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; -- cgit v1.2.3 From adf5931f8c412e90f47033ca6bc7a0bc8a930ba1 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 27 Dec 2010 21:16:43 +0100 Subject: ALSA: azt3328: cosmetics, minor updates - correct samples to be POSIX shell compatible - add logging of jiffies value in _pointer() - several comments - cleanup Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 2f3cacbd5528..006f8c0ffb56 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1,6 +1,6 @@ /* * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). - * Copyright (C) 2002, 2005 - 2009 by Andreas Mohr + * Copyright (C) 2002, 2005 - 2010 by Andreas Mohr * * Framework borrowed from Bart Hartgers's als4000.c. * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), @@ -201,14 +201,15 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); /* === Debug settings === Further diagnostic functionality than the settings below - does not need to be provided, since one can easily write a bash script + does not need to be provided, since one can easily write a POSIX shell script to dump the card's I/O ports (those listed in lspci -v -v): - function dump() + dump() { local descr=$1; local addr=$2; local count=$3 echo "${descr}: ${count} @ ${addr}:" - dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C + dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \ + 2>/dev/null| hexdump -C } and then use something like "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8", @@ -216,14 +217,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}"); possibly within a "while true; do ... sleep 1; done" loop. Tweaking ports could be done using VALSTRING="`printf "%02x" $value`" - printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null + printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \ + 2>/dev/null */ #define DEBUG_MISC 0 #define DEBUG_CALLS 0 #define DEBUG_MIXER 0 #define DEBUG_CODEC 0 -#define DEBUG_IO 0 #define DEBUG_TIMER 0 #define DEBUG_GAME 0 #define DEBUG_PM 0 @@ -299,6 +300,7 @@ struct snd_azf3328_codec_data { }; enum snd_azf3328_codec_type { + /* warning: fixed indices (also used for bitmask checks!) */ AZF_CODEC_PLAYBACK = 0, AZF_CODEC_CAPTURE = 1, AZF_CODEC_I2S_OUT = 2, @@ -362,6 +364,9 @@ MODULE_DEVICE_TABLE(pci, snd_azf3328_ids); static int snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set) { + /* Well, strictly spoken, the inb/outb sequence isn't atomic + and would need locking. However we currently don't care + since it potentially complicates matters. */ u8 prev = inb(reg), new; new = (do_set) ? (prev|mask) : (prev & ~mask); @@ -1004,7 +1009,8 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, * (FIXME: yes, it works, but what exactly am I doing here?? :) * FIXME: does this have some side effects for full-duplex * or other dramatic side effects? */ - if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */ + /* do it for non-capture codecs only */ + if (codec_type == AZF_CODEC_PLAYBACK) snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) | DMA_RUN_SOMETHING1 | @@ -1368,8 +1374,8 @@ snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, /* calculate offset */ result -= bufptr; frmres = bytes_to_frames( substream->runtime, result); - snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n", - codec->name, result, frmres); + snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n", + jiffies, codec->name, result, frmres); return frmres; } @@ -1532,7 +1538,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport, } } - /* trigger next axes sampling, to be evaluated the next time we + /* trigger next sampling of axes, to be evaluated the next time we * enter this function */ /* for some very, very strange reason we cannot enable @@ -1966,7 +1972,7 @@ snd_azf3328_timer_start(struct snd_timer *timer) snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay); delay = 49; /* minimum time is 49 ticks */ } - snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); + snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay); delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE; spin_lock_irqsave(&chip->reg_lock, flags); snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay); @@ -2257,7 +2263,7 @@ snd_azf3328_create(struct snd_card *card, struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; - /* shutdown codecs to save power */ + /* shutdown codecs to reduce power / noise */ /* have ...ctrl_codec_activity() act properly */ codec->running = 1; snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); @@ -2419,6 +2425,7 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + /* same pcm object for playback/capture */ snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]); snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]); -- cgit v1.2.3 From 8d9a114e6d4acabf6b23ca8bccf0e486c3bdf85c Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 27 Dec 2010 21:16:49 +0100 Subject: ALSA: azt3328: _setfmt() update - use a separate variable for the frequency part, don't always "or" it - use a "clever"(?) macro to shorten the code Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 006f8c0ffb56..3a9a4a1be26f 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -958,28 +958,35 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, unsigned long flags; const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; u16 val = 0xff00; + u8 freq = 0; snd_azf3328_dbgcallenter(); switch (bitrate) { - case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; - case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; - case AZF_FREQ_5512: - /* the AZF3328 names it "5510" for some strange reason */ - val |= SOUNDFORMAT_FREQ_5510; break; - case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break; - case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break; - case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break; - case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break; - case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; - case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break; - case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break; - case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break; +#define AZF_FMT_XLATE(in_freq, out_bits) \ + do { \ + case AZF_FREQ_ ## in_freq: \ + freq = SOUNDFORMAT_FREQ_ ## out_bits; \ + break; \ + } while (0); + AZF_FMT_XLATE(4000, SUSPECTED_4000) + AZF_FMT_XLATE(4800, SUSPECTED_4800) + /* the AZF3328 names it "5510" for some strange reason: */ + AZF_FMT_XLATE(5512, 5510) + AZF_FMT_XLATE(6620, 6620) + AZF_FMT_XLATE(8000, 8000) + AZF_FMT_XLATE(9600, 9600) + AZF_FMT_XLATE(11025, 11025) + AZF_FMT_XLATE(13240, SUSPECTED_13240) + AZF_FMT_XLATE(16000, 16000) + AZF_FMT_XLATE(22050, 22050) + AZF_FMT_XLATE(32000, 32000) default: snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); /* fall-through */ - case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break; - case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break; - case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break; + AZF_FMT_XLATE(44100, 44100) + AZF_FMT_XLATE(48000, 48000) + AZF_FMT_XLATE(66200, SUSPECTED_66200) +#undef AZF_FMT_XLATE } /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ @@ -991,6 +998,8 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ + val |= freq; + if (channels == 2) val |= SOUNDFORMAT_FLAG_2CHANNELS; -- cgit v1.2.3 From 9fd8d36caabaf3102f14cf652d5ca012d775aaa8 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 27 Dec 2010 21:17:00 +0100 Subject: ALSA: azt3328: cosmetics: use a helper variable for codec setup Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 3a9a4a1be26f..0cb5499ad36a 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -2195,6 +2195,7 @@ snd_azf3328_create(struct snd_card *card, }; u8 dma_init; enum snd_azf3328_codec_type codec_type; + struct snd_azf3328_codec *codec_setup; *rchip = NULL; @@ -2232,15 +2233,17 @@ snd_azf3328_create(struct snd_card *card, chip->opl3_io = pci_resource_start(pci, 3); chip->mixer_io = pci_resource_start(pci, 4); - chip->codecs[AZF_CODEC_PLAYBACK].io_base = - chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; - chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK"; - chip->codecs[AZF_CODEC_CAPTURE].io_base = - chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; - chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE"; - chip->codecs[AZF_CODEC_I2S_OUT].io_base = - chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; - chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT"; + codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK]; + codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; + codec_setup->name = "PLAYBACK"; + + codec_setup = &chip->codecs[AZF_CODEC_CAPTURE]; + codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; + codec_setup->name = "CAPTURE"; + + codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT]; + codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; + codec_setup->name = "I2S_OUT"; if (request_irq(pci->irq, snd_azf3328_interrupt, IRQF_SHARED, card->shortname, chip)) { -- cgit v1.2.3 From 345855951a7d36eed815fd129c49b7ee2b7a6864 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 27 Dec 2010 21:17:11 +0100 Subject: ALSA: azt3328: use a helper variable to remove one indirection in hotpath Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 0cb5499ad36a..b1fad46a7b02 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -294,6 +294,7 @@ MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor ( struct snd_azf3328_codec_data { unsigned long io_base; + unsigned int dma_base; /* helper to avoid an indirection in hotpath */ struct snd_pcm_substream *substream; bool running; const char *name; @@ -1165,14 +1166,17 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, static int snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) { -#if 0 - struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_azf3328_codec *codec = runtime->private_data; +#if 0 unsigned int size = snd_pcm_lib_buffer_bytes(substream); unsigned int count = snd_pcm_lib_period_bytes(substream); #endif snd_azf3328_dbgcallenter(); + + codec->dma_base = runtime->dma_addr; + #if 0 snd_azf3328_codec_setfmt(chip, AZF_CODEC_..., runtime->rate, @@ -1370,18 +1374,17 @@ snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, { const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; - unsigned long bufptr, result; + unsigned long result; snd_pcm_uframes_t frmres; -#ifdef QUERY_HARDWARE - bufptr = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1); -#else - bufptr = substream->runtime->dma_addr; -#endif result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS); /* calculate offset */ - result -= bufptr; +#ifdef QUERY_HARDWARE + result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1); +#else + result -= codec->dma_base; +#endif frmres = bytes_to_frames( substream->runtime, result); snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n", jiffies, codec->name, result, frmres); -- cgit v1.2.3 From da237f35a8a503fb8893fb3b9d0622a991bcebef Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 27 Dec 2010 21:17:26 +0100 Subject: ALSA: azt3328: use proper private_data hookup for codec identification - much improved implementation due to clean codec hierarchy - preparation for potential per-codec spinlock change NOTE: additionally removes a chip->pcm[codec_type] NULL ptr check (due to it requiring access to external chip struct), however I believe this to be ok since this condition should not occur and most drivers don't check against that either. Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 234 ++++++++++++++++++++-------------------------------- 1 file changed, 90 insertions(+), 144 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index b1fad46a7b02..76ff5fdb4838 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -292,14 +292,6 @@ static int seqtimer_scaling = 128; module_param(seqtimer_scaling, int, 0444); MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); -struct snd_azf3328_codec_data { - unsigned long io_base; - unsigned int dma_base; /* helper to avoid an indirection in hotpath */ - struct snd_pcm_substream *substream; - bool running; - const char *name; -}; - enum snd_azf3328_codec_type { /* warning: fixed indices (also used for bitmask checks!) */ AZF_CODEC_PLAYBACK = 0, @@ -307,6 +299,16 @@ enum snd_azf3328_codec_type { AZF_CODEC_I2S_OUT = 2, }; +struct snd_azf3328_codec_data { + unsigned long io_base; /* keep first! (avoid offset calc) */ + unsigned int dma_base; /* helper to avoid an indirection in hotpath */ + spinlock_t *lock; /* TODO: convert to our own per-codec lock member */ + struct snd_pcm_substream *substream; + bool running; + enum snd_azf3328_codec_type type; + const char *name; +}; + struct snd_azf3328 { /* often-used fields towards beginning, then grouped */ @@ -949,15 +951,13 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream) } static void -snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, - enum snd_azf3328_codec_type codec_type, +snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec, enum azf_freq_t bitrate, unsigned int format_width, unsigned int channels ) { unsigned long flags; - const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; u16 val = 0xff00; u8 freq = 0; @@ -1007,7 +1007,7 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, if (format_width == 16) val |= SOUNDFORMAT_FLAG_16BIT; - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irqsave(codec->lock, flags); /* set bitrate/format */ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val); @@ -1020,7 +1020,7 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, * FIXME: does this have some side effects for full-duplex * or other dramatic side effects? */ /* do it for non-capture codecs only */ - if (codec_type == AZF_CODEC_PLAYBACK) + if (codec->type != AZF_CODEC_CAPTURE) snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) | DMA_RUN_SOMETHING1 | @@ -1030,20 +1030,19 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, DMA_SOMETHING_ELSE ); - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irqrestore(codec->lock, flags); snd_azf3328_dbgcallleave(); } static inline void -snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, - enum snd_azf3328_codec_type codec_type +snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec ) { /* choose lowest frequency for low power consumption. * While this will cause louder noise due to rather coarse frequency, * it should never matter since output should always * get disabled properly when idle anyway. */ - snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1); + snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1); } static void @@ -1117,23 +1116,18 @@ snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip, /* ...and adjust clock, too * (reduce noise and power consumption) */ if (!enable) - snd_azf3328_codec_setfmt_lowpower( - chip, - codec_type - ); + snd_azf3328_codec_setfmt_lowpower(codec); codec->running = enable; } } static void -snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, - enum snd_azf3328_codec_type codec_type, +snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec, unsigned long addr, unsigned int count, unsigned int size ) { - const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; snd_azf3328_dbgcallenter(); if (!codec->running) { /* AZF3328 uses a two buffer pointer DMA transfer approach */ @@ -1152,22 +1146,22 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, /* build combined I/O buffer length word */ lengths = (count_areas << 16) | (count_areas); - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irqsave(codec->lock, flags); snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr); snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2, addr_area2); snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS, lengths); - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irqrestore(codec->lock, flags); } snd_azf3328_dbgcallleave(); } static int -snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) +snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_azf3328_codec *codec = runtime->private_data; + struct snd_azf3328_codec_data *codec = runtime->private_data; #if 0 unsigned int size = snd_pcm_lib_buffer_bytes(substream); unsigned int count = snd_pcm_lib_period_bytes(substream); @@ -1178,11 +1172,11 @@ snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) codec->dma_base = runtime->dma_addr; #if 0 - snd_azf3328_codec_setfmt(chip, AZF_CODEC_..., + snd_azf3328_codec_setfmt(codec, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels); - snd_azf3328_codec_setdmaa(chip, AZF_CODEC_..., + snd_azf3328_codec_setdmaa(codec, runtime->dma_addr, count, size); #endif snd_azf3328_dbgcallleave(); @@ -1190,24 +1184,23 @@ snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) } static int -snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, - struct snd_pcm_substream *substream, int cmd) +snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); - const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_azf3328_codec_data *codec = runtime->private_data; int result = 0; u16 flags1; bool previously_muted = 0; - bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type); + bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type); - snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd); + snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_azf3328_dbgcodec("START %s\n", codec->name); - if (is_playback_codec) { + if (is_main_mixer_playback_codec) { /* mute WaveOut (avoid clicking during setup) */ previously_muted = snd_azf3328_mixer_set_mute( @@ -1215,12 +1208,12 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, ); } - snd_azf3328_codec_setfmt(chip, codec_type, + snd_azf3328_codec_setfmt(codec, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels); - spin_lock(&chip->reg_lock); + spin_lock(codec->lock); /* first, remember current value: */ flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); @@ -1230,14 +1223,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, /* FIXME: clear interrupts or what??? */ snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff); - spin_unlock(&chip->reg_lock); + spin_unlock(codec->lock); - snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr, + snd_azf3328_codec_setdmaa(codec, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream) ); - spin_lock(&chip->reg_lock); + spin_lock(codec->lock); #ifdef WIN9X /* FIXME: enable playback/recording??? */ flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2; @@ -1261,10 +1254,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, DMA_EPILOGUE_SOMETHING | DMA_SOMETHING_ELSE); #endif - spin_unlock(&chip->reg_lock); - snd_azf3328_ctrl_codec_activity(chip, codec_type, 1); + spin_unlock(codec->lock); + snd_azf3328_ctrl_codec_activity(chip, codec->type, 1); - if (is_playback_codec) { + if (is_main_mixer_playback_codec) { /* now unmute WaveOut */ if (!previously_muted) snd_azf3328_mixer_set_mute( @@ -1277,19 +1270,19 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, case SNDRV_PCM_TRIGGER_RESUME: snd_azf3328_dbgcodec("RESUME %s\n", codec->name); /* resume codec if we were active */ - spin_lock(&chip->reg_lock); + spin_lock(codec->lock); if (codec->running) snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, snd_azf3328_codec_inw( codec, IDX_IO_CODEC_DMA_FLAGS ) | DMA_RESUME ); - spin_unlock(&chip->reg_lock); + spin_unlock(codec->lock); break; case SNDRV_PCM_TRIGGER_STOP: snd_azf3328_dbgcodec("STOP %s\n", codec->name); - if (is_playback_codec) { + if (is_main_mixer_playback_codec) { /* mute WaveOut (avoid clicking during setup) */ previously_muted = snd_azf3328_mixer_set_mute( @@ -1297,7 +1290,7 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, ); } - spin_lock(&chip->reg_lock); + spin_lock(codec->lock); /* first, remember current value: */ flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); @@ -1312,10 +1305,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, flags1 &= ~DMA_RUN_SOMETHING1; snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1); - spin_unlock(&chip->reg_lock); - snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); + spin_unlock(codec->lock); + snd_azf3328_ctrl_codec_activity(chip, codec->type, 0); - if (is_playback_codec) { + if (is_main_mixer_playback_codec) { /* now unmute WaveOut */ if (!previously_muted) snd_azf3328_mixer_set_mute( @@ -1349,31 +1342,12 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, return result; } -static int -snd_azf3328_codec_playback_trigger(struct snd_pcm_substream *substream, int cmd) -{ - return snd_azf3328_codec_trigger(AZF_CODEC_PLAYBACK, substream, cmd); -} - -static int -snd_azf3328_codec_capture_trigger(struct snd_pcm_substream *substream, int cmd) -{ - return snd_azf3328_codec_trigger(AZF_CODEC_CAPTURE, substream, cmd); -} - -static int -snd_azf3328_codec_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd) -{ - return snd_azf3328_codec_trigger(AZF_CODEC_I2S_OUT, substream, cmd); -} - static snd_pcm_uframes_t -snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, - enum snd_azf3328_codec_type codec_type +snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream ) { - const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); - const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; + const struct snd_azf3328_codec_data *codec = + substream->runtime->private_data; unsigned long result; snd_pcm_uframes_t frmres; @@ -1391,24 +1365,6 @@ snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, return frmres; } -static snd_pcm_uframes_t -snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream) -{ - return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK); -} - -static snd_pcm_uframes_t -snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream) -{ - return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE); -} - -static snd_pcm_uframes_t -snd_azf3328_codec_i2s_out_pointer(struct snd_pcm_substream *substream) -{ - return snd_azf3328_codec_pointer(substream, AZF_CODEC_I2S_OUT); -} - /******************************************************************/ #ifdef SUPPORT_GAMEPORT @@ -1642,29 +1598,29 @@ snd_azf3328_irq_log_unknown_type(u8 which) } static inline void -snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status) +snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec, + u8 status +) { u8 which; enum snd_azf3328_codec_type codec_type; - const struct snd_azf3328_codec_data *codec; + const struct snd_azf3328_codec_data *codec = first_codec; for (codec_type = AZF_CODEC_PLAYBACK; codec_type <= AZF_CODEC_I2S_OUT; - ++codec_type) { + ++codec_type, ++codec) { /* skip codec if there's no interrupt for it */ if (!(status & (1 << codec_type))) continue; - codec = &chip->codecs[codec_type]; - - spin_lock(&chip->reg_lock); + spin_lock(codec->lock); which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE); /* ack all IRQ types immediately */ snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which); - spin_unlock(&chip->reg_lock); + spin_unlock(codec->lock); - if ((chip->pcm[codec_type]) && (codec->substream)) { + if (codec->substream) { snd_pcm_period_elapsed(codec->substream); snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n", codec->name, @@ -1719,7 +1675,7 @@ snd_azf3328_interrupt(int irq, void *dev_id) } if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT)) - snd_azf3328_codec_interrupt(chip, status); + snd_azf3328_pcm_interrupt(chip->codecs, status); if (status & IRQ_GAMEPORT) snd_azf3328_gameport_interrupt(chip); @@ -1807,101 +1763,85 @@ snd_azf3328_pcm_open(struct snd_pcm_substream *substream, { struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; snd_azf3328_dbgcallenter(); - chip->codecs[codec_type].substream = substream; + codec->substream = substream; /* same parameters for all our codecs - at least we think so... */ runtime->hw = snd_azf3328_hardware; snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &snd_azf3328_hw_constraints_rates); + runtime->private_data = codec; snd_azf3328_dbgcallleave(); return 0; } static int -snd_azf3328_playback_open(struct snd_pcm_substream *substream) +snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream) { return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK); } static int -snd_azf3328_capture_open(struct snd_pcm_substream *substream) +snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream) { return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE); } static int -snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream) +snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream) { return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT); } static int -snd_azf3328_pcm_close(struct snd_pcm_substream *substream, - enum snd_azf3328_codec_type codec_type +snd_azf3328_pcm_close(struct snd_pcm_substream *substream ) { - struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); + struct snd_azf3328_codec_data *codec = + substream->runtime->private_data; snd_azf3328_dbgcallenter(); - chip->codecs[codec_type].substream = NULL; + codec->substream = NULL; snd_azf3328_dbgcallleave(); return 0; } -static int -snd_azf3328_playback_close(struct snd_pcm_substream *substream) -{ - return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK); -} - -static int -snd_azf3328_capture_close(struct snd_pcm_substream *substream) -{ - return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE); -} - -static int -snd_azf3328_i2s_out_close(struct snd_pcm_substream *substream) -{ - return snd_azf3328_pcm_close(substream, AZF_CODEC_I2S_OUT); -} - /******************************************************************/ static struct snd_pcm_ops snd_azf3328_playback_ops = { - .open = snd_azf3328_playback_open, - .close = snd_azf3328_playback_close, + .open = snd_azf3328_pcm_playback_open, + .close = snd_azf3328_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_azf3328_hw_params, .hw_free = snd_azf3328_hw_free, - .prepare = snd_azf3328_codec_prepare, - .trigger = snd_azf3328_codec_playback_trigger, - .pointer = snd_azf3328_codec_playback_pointer + .prepare = snd_azf3328_pcm_prepare, + .trigger = snd_azf3328_pcm_trigger, + .pointer = snd_azf3328_pcm_pointer }; static struct snd_pcm_ops snd_azf3328_capture_ops = { - .open = snd_azf3328_capture_open, - .close = snd_azf3328_capture_close, + .open = snd_azf3328_pcm_capture_open, + .close = snd_azf3328_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_azf3328_hw_params, .hw_free = snd_azf3328_hw_free, - .prepare = snd_azf3328_codec_prepare, - .trigger = snd_azf3328_codec_capture_trigger, - .pointer = snd_azf3328_codec_capture_pointer + .prepare = snd_azf3328_pcm_prepare, + .trigger = snd_azf3328_pcm_trigger, + .pointer = snd_azf3328_pcm_pointer }; static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { - .open = snd_azf3328_i2s_out_open, - .close = snd_azf3328_i2s_out_close, + .open = snd_azf3328_pcm_i2s_out_open, + .close = snd_azf3328_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_azf3328_hw_params, .hw_free = snd_azf3328_hw_free, - .prepare = snd_azf3328_codec_prepare, - .trigger = snd_azf3328_codec_i2s_out_trigger, - .pointer = snd_azf3328_codec_i2s_out_pointer + .prepare = snd_azf3328_pcm_prepare, + .trigger = snd_azf3328_pcm_trigger, + .pointer = snd_azf3328_pcm_pointer }; static int __devinit @@ -2198,7 +2138,7 @@ snd_azf3328_create(struct snd_card *card, }; u8 dma_init; enum snd_azf3328_codec_type codec_type; - struct snd_azf3328_codec *codec_setup; + struct snd_azf3328_codec_data *codec_setup; *rchip = NULL; @@ -2238,14 +2178,20 @@ snd_azf3328_create(struct snd_card *card, codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK]; codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; + codec_setup->lock = &chip->reg_lock; + codec_setup->type = AZF_CODEC_PLAYBACK; codec_setup->name = "PLAYBACK"; codec_setup = &chip->codecs[AZF_CODEC_CAPTURE]; codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; + codec_setup->lock = &chip->reg_lock; + codec_setup->type = AZF_CODEC_CAPTURE; codec_setup->name = "CAPTURE"; codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT]; codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; + codec_setup->lock = &chip->reg_lock; + codec_setup->type = AZF_CODEC_I2S_OUT; codec_setup->name = "I2S_OUT"; if (request_irq(pci->irq, snd_azf3328_interrupt, @@ -2283,10 +2229,10 @@ snd_azf3328_create(struct snd_card *card, codec->running = 1; snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); - spin_lock_irq(&chip->reg_lock); + spin_lock_irq(codec->lock); snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS, dma_init); - spin_unlock_irq(&chip->reg_lock); + spin_unlock_irq(codec->lock); } snd_card_set_dev(card, &pci->dev); -- cgit v1.2.3 From 689c69120ea3c8db069e11a7065ceffee90d0460 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 27 Dec 2010 21:17:35 +0100 Subject: ALSA: azt3328: improve snd_azf3328_codec_setdmaa() - add some WARN_ONCE - add multi-I/O helper (and use helper struct) - fix off-by-1 DMA length bug - better variable naming Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 66 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 15 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 76ff5fdb4838..6117595fc075 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -175,6 +175,7 @@ #include #include +#include /* WARN_ONCE */ #include #include #include @@ -421,6 +422,21 @@ snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec, outl(value, codec->io_base + reg); } +static inline void +snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec, + unsigned reg, const void *buffer, int count +) +{ + unsigned long addr = codec->io_base + reg; + if (count) { + const u32 *buf = buffer; + do { + outl(*buf++, addr); + addr += 4; + } while (--count); + } +} + static inline u32 snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg) { @@ -1124,34 +1140,54 @@ snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip, static void snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec, unsigned long addr, - unsigned int count, - unsigned int size + unsigned int period_bytes, + unsigned int buffer_bytes ) { snd_azf3328_dbgcallenter(); + WARN_ONCE(period_bytes & 1, "odd period length!?\n"); + WARN_ONCE(buffer_bytes != 2 * period_bytes, + "missed our input expectations! %u vs. %u\n", + buffer_bytes, period_bytes); if (!codec->running) { /* AZF3328 uses a two buffer pointer DMA transfer approach */ - unsigned long flags, addr_area2; + unsigned long flags; /* width 32bit (prevent overflow): */ - u32 count_areas, lengths; + u32 area_length; + struct codec_setup_io { + u32 dma_start_1; + u32 dma_start_2; + u32 dma_lengths; + } __attribute__((packed)) setup_io; - count_areas = size/2; - addr_area2 = addr+count_areas; - snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", - addr, count_areas, addr_area2, count_areas); + area_length = buffer_bytes/2; - count_areas--; /* max. index */ + setup_io.dma_start_1 = addr; + setup_io.dma_start_2 = addr+area_length; + + snd_azf3328_dbgcodec( + "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n", + setup_io.dma_start_1, area_length, + setup_io.dma_start_2, area_length, + period_bytes, buffer_bytes); + + /* Hmm, are we really supposed to decrement this by 1?? + Most definitely certainly not: configuring full length does + work properly (i.e. likely better), and BTW we + violated possibly differing frame sizes with this... + + area_length--; |* max. index *| + */ /* build combined I/O buffer length word */ - lengths = (count_areas << 16) | (count_areas); + setup_io.dma_lengths = (area_length << 16) | (area_length); + spin_lock_irqsave(codec->lock, flags); - snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr); - snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2, - addr_area2); - snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS, - lengths); + snd_azf3328_codec_outl_multi( + codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3 + ); spin_unlock_irqrestore(codec->lock, flags); } snd_azf3328_dbgcallleave(); -- cgit v1.2.3 From bdfe6f452f9005731a6784c88503432864343240 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 4 Jan 2011 06:30:53 +0100 Subject: ALSA: HDA: Add internal mic for IDT 92HD88B BugLink: http://bugs.launchpad.net/bugs/696493 According to datasheet (and real-world testing), IDT 92HD88B can have internal mics at NID 0x11 and 0x20, so enable them accordingly. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6131a92f0898..c8d812ecb943 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -389,6 +389,9 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 0x11, 0x20, 0 }; +#define STAC92HD88XXX_NUM_DMICS STAC92HD83XXX_NUM_DMICS +#define stac92hd88xxx_dmic_nids stac92hd83xxx_dmic_nids + #define STAC92HD87B_NUM_DMICS 1 static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { 0x11, 0 @@ -5462,11 +5465,18 @@ again: spec->num_dmics = stac92xx_connected_ports(codec, stac92hd87b_dmic_nids, STAC92HD87B_NUM_DMICS); - /* Fall through */ + spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); + spec->pin_nids = stac92hd88xxx_pin_nids; + spec->mono_nid = 0; + spec->num_pwrs = 0; + break; case 0x111d7666: case 0x111d7667: case 0x111d7668: case 0x111d7669: + spec->num_dmics = stac92xx_connected_ports(codec, + stac92hd88xxx_dmic_nids, + STAC92HD88XXX_NUM_DMICS); spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); spec->pin_nids = stac92hd88xxx_pin_nids; spec->mono_nid = 0; -- cgit v1.2.3 From 5f99f86a801f937ed51deedc36ad4efc47d95cdd Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 4 Jan 2011 15:24:24 +0100 Subject: ALSA: HDA: Rename "Mic Boost" to "Mic Boost Volume" BugLink: http://bugs.launchpad.net/bugs/697240 If the "Volume" suffix is not given, alsa-lib gets confused and loses the dB information at the simple element level. Boosts generally affects both playback and capture, as they are applied early in the chain. Hence no "Playback" or "Capture" in the suffix. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 72 ++++++------- sound/pci/hda/patch_conexant.c | 2 +- sound/pci/hda/patch_realtek.c | 222 ++++++++++++++++++++--------------------- 3 files changed, 148 insertions(+), 148 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f7ff3f7ccb8e..46780670162b 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -666,7 +666,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = { HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), @@ -729,7 +729,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), /* HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ @@ -775,7 +775,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), { @@ -1358,7 +1358,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), { @@ -1515,8 +1515,8 @@ static struct snd_kcontrol_new ad1981_mixers[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), { @@ -1726,8 +1726,8 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), #endif - HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), { @@ -1774,7 +1774,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), { @@ -2160,8 +2160,8 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -2203,8 +2203,8 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -2232,7 +2232,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = { HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -2902,7 +2902,7 @@ static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin, idx = ad1988_pin_idx(pin); bnid = ad1988_boost_nids[idx]; if (bnid) { - sprintf(name, "%s Boost", ctlname); + sprintf(name, "%s Boost Volume", ctlname); return add_control(spec, AD_CTL_WIDGET_VOL, name, HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT)); @@ -3300,8 +3300,8 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), @@ -3499,9 +3499,9 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), @@ -3560,8 +3560,8 @@ static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), @@ -3745,9 +3745,9 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), @@ -3888,9 +3888,9 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT), HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), { } /* end */ @@ -4126,8 +4126,8 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), { @@ -4255,8 +4255,8 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT), { } /* end */ }; @@ -4494,9 +4494,9 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = { HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), @@ -4547,7 +4547,7 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), - HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT), { } /* end */ }; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 74291f744c68..33962449f15c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1376,7 +1376,7 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, static struct snd_kcontrol_new cxt5047_base_mixers[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x1a, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f39efa440c0f..18d53d2036a3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2232,7 +2232,7 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -2250,7 +2250,7 @@ static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -7896,10 +7896,10 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -7923,8 +7923,8 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = { HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), { } /* end */ }; @@ -7941,8 +7941,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT), { } /* end */ }; @@ -7957,7 +7957,7 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = { HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), - HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), { } /* end */ }; @@ -7976,7 +7976,7 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -7991,10 +7991,10 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -8014,7 +8014,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), { } /* end */ }; @@ -8027,7 +8027,7 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -8808,10 +8808,10 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = { HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8822,10 +8822,10 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8836,10 +8836,10 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8853,10 +8853,10 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8876,10 +8876,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8900,10 +8900,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 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, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -8924,10 +8924,10 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 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, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -8947,10 +8947,10 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8971,7 +8971,7 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -8984,10 +8984,10 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8996,7 +8996,7 @@ static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -9008,7 +9008,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -9069,7 +9069,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -9082,7 +9082,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -9104,10 +9104,10 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -9128,8 +9128,8 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = { HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), /* Boost mixers */ - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), /* Input mixers */ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), @@ -9143,7 +9143,7 @@ static struct snd_kcontrol_new alc883_vaiott_mixer[] = { HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -9173,7 +9173,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 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_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -10834,7 +10834,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) type_idx++; else type_idx = 0; - snprintf(label, sizeof(label), "%s Boost", + snprintf(label, sizeof(label), "%s Boost Volume", hda_get_autocfg_input_label(codec, cfg, i)); err = add_control(spec, ALC_CTL_WIDGET_VOL, label, type_idx, @@ -11079,10 +11079,10 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), @@ -11183,10 +11183,10 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, 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("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11208,7 +11208,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { HDA_OUTPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11219,7 +11219,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), { } /* end */ }; @@ -11239,7 +11239,7 @@ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), { } /* end */ }; @@ -11346,10 +11346,10 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -11363,10 +11363,10 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -11434,10 +11434,10 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -11621,7 +11621,7 @@ static struct snd_kcontrol_new alc262_nec_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -11828,10 +11828,10 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { }, HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ @@ -11864,10 +11864,10 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { }, HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ @@ -11878,10 +11878,10 @@ static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { ALC262_HIPPO_MASTER_SWITCH, HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -11907,8 +11907,8 @@ static struct snd_kcontrol_new alc262_ultra_mixer[] = { HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT), { } /* end */ }; @@ -12985,9 +12985,9 @@ static struct snd_kcontrol_new alc268_base_mixer[] = { HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), { } }; @@ -12996,9 +12996,9 @@ static struct snd_kcontrol_new alc268_toshiba_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), { } }; @@ -13102,9 +13102,9 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { .put = alc268_acer_master_sw_put, .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }, - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), { } }; @@ -13120,8 +13120,8 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { .put = alc268_acer_master_sw_put, .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }, - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), { } }; @@ -13213,8 +13213,8 @@ static struct snd_kcontrol_new alc268_dell_mixer[] = { HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), { } }; @@ -13247,8 +13247,8 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), { } }; @@ -14071,10 +14071,10 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), { } /* end */ @@ -14094,10 +14094,10 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { }, HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), { } }; @@ -14115,13 +14115,13 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { }, HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT), { } }; @@ -14151,30 +14151,30 @@ static struct snd_kcontrol_new alc269_asus_mixer[] = { static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), { } /* end */ }; static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), { } /* end */ }; static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), { } /* end */ }; static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), { } /* end */ }; @@ -16473,11 +16473,11 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -16496,11 +16496,11 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -16520,11 +16520,11 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -16542,10 +16542,10 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ @@ -17547,11 +17547,11 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ @@ -18543,11 +18543,11 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("Mic/LineIn Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ @@ -18562,11 +18562,11 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -19609,9 +19609,9 @@ static struct snd_kcontrol_new alc680_base_mixer[] = { HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x12, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT), { } }; -- cgit v1.2.3 From 5322bf2790fb91328aac1783bb1963ea3a172bcf Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 5 Jan 2011 11:03:56 +0100 Subject: ALSA: HDA: Fix volume control indices for Mics (Realtek) If more than one mic is present with different locations, e g "Front Mic" and "Rear Mic", they can use the same index (0), since their names are different. Previous behavior was to have "Front Mic" as index 1, causing it to be ignored by e g PulseAudio. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 18d53d2036a3..b4f78952381a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5200,7 +5200,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec, { struct alc_spec *spec = codec->spec; struct hda_input_mux *imux = &spec->private_imux[0]; - int i, err, idx, type, type_idx = 0; + int i, err, idx, type_idx = 0; + const char *prev_label = NULL; for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t pin; @@ -5210,12 +5211,13 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec, if (!alc_is_input_pin(codec, pin)) continue; - type = cfg->inputs[i].type; - if (i > 0 && type == cfg->inputs[i - 1].type) + label = hda_get_autocfg_input_label(codec, cfg, i); + if (prev_label && !strcmp(label, prev_label)) type_idx++; else type_idx = 0; - label = hda_get_autocfg_input_label(codec, cfg, i); + prev_label = label; + if (mixer) { idx = get_connection_index(codec, mixer, pin); if (idx >= 0) { @@ -10819,25 +10821,30 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - int i, err, type; + int i, err; int type_idx = 0; hda_nid_t nid; + const char *prev_label = NULL; for (i = 0; i < cfg->num_inputs; i++) { if (cfg->inputs[i].type > AUTO_PIN_MIC) break; nid = cfg->inputs[i].pin; if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { - char label[32]; - type = cfg->inputs[i].type; - if (i > 0 && type == cfg->inputs[i - 1].type) + const char *label; + char boost_label[32]; + + label = hda_get_autocfg_input_label(codec, cfg, i); + if (prev_label && !strcmp(label, prev_label)) type_idx++; else type_idx = 0; - snprintf(label, sizeof(label), "%s Boost Volume", - hda_get_autocfg_input_label(codec, cfg, i)); - err = add_control(spec, ALC_CTL_WIDGET_VOL, label, - type_idx, + prev_label = label; + + snprintf(boost_label, sizeof(boost_label), + "%s Boost Volume", label); + err = add_control(spec, ALC_CTL_WIDGET_VOL, + boost_label, type_idx, HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); if (err < 0) return err; -- cgit v1.2.3 From 22f21d51bb20e7aef1167b71c4c3c0ff0efa9bf6 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Fri, 7 Jan 2011 07:53:39 +0100 Subject: ALSA: HDA: Add Lenovo vendor quirk for Conexant 205xx BugLink: http://bugs.launchpad.net/bugs/689036 Many new Lenovos need the ideapad quirk. Also, since the auto parser for this chip is far from optimal, the regression risk is low (although not zero). Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 33962449f15c..2c5e74eedf39 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3109,16 +3109,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { CXT5066_LAPTOP), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), - SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), - SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), - SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), - SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), - SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), - SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD), - SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), - SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), + SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ {} }; -- cgit v1.2.3 From ca6cd851d7d22767d68b674590d836f468d1913a Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sat, 8 Jan 2011 18:25:27 -0500 Subject: ALSA: hda: Use vostro model quirk for Dell Vostro 1014 BugLink: https://bugtrack.alsa-project.org/alsa-bug/view.php?id=5184 A user reported on the alsa-devel mailing list that he needs to use the vostro model quirk to have audible playback, so apply it for his PCI SSID. Reported-and-tested-by: Fernando Lemos Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2c5e74eedf39..e96581fcdbdb 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3098,6 +3098,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), -- cgit v1.2.3 From b2d0576055bd1cafcd91a23cf85064815f1396cd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Jan 2011 14:47:35 +0100 Subject: ALSA: hda - Fix multi-headphone handling for Realtek codecs When multiple headphone pins are defined without line-out pins, the driver takes them as primary outputs. But it forgot to set line_out_type to HP by assuming there is some rest of HP pins. This results in some mis-handling of these pins for Realtek codec parser. It takes as if these are pure line-out jacks. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/hda_codec.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 98b6d02a36c9..05e5ec88c2d9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4571,6 +4571,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, } memset(cfg->hp_pins + cfg->hp_outs, 0, sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs)); + if (!cfg->hp_outs) + cfg->line_out_type = AUTO_PIN_HP_OUT; + } /* sort by sequence */ -- cgit v1.2.3 From bcb2f0f517ebae7350526bbde8912ad187147e2d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 10 Jan 2011 15:45:23 +0100 Subject: ALSA: hda - Add support for multiple headphone/speaker controls for Realtek So far, Realtek auto-parser assumed that the multiple pins are only for line-outs, and assigned the channel names like Front, Surround, etc for the multiple outputs. But, there are devices that have multiple headphones, and these can be better controlled with the corresponding control-name like "Headphone" with indicies. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 137 +++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 69 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b4f78952381a..0ecd75e2d28f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5068,6 +5068,25 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, return 0; } +static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, + bool can_be_master) +{ + if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) + return "Master"; + + switch (cfg->line_out_type) { + case AUTO_PIN_SPEAKER_OUT: + return "Speaker"; + case AUTO_PIN_HP_OUT: + return "Headphone"; + default: + if (cfg->line_outs == 1) + return "PCM"; + break; + } + return NULL; +} + /* add playback controls from the parsed DAC table */ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) @@ -5075,6 +5094,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + const char *pfx = alc_get_line_out_pfx(cfg, false); hda_nid_t nid; int i, err; @@ -5082,7 +5102,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, if (!spec->multiout.dac_nids[i]) continue; nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); - if (i == 2) { + if (!pfx && i == 2) { /* Center/LFE */ err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Center", @@ -5109,18 +5129,17 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, if (err < 0) return err; } else { - const char *pfx; - if (cfg->line_outs == 1 && - cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) - pfx = "Speaker"; - else - pfx = chname[i]; - err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, + const char *name = pfx; + if (!name) + name = chname[i]; + err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, + name, i, HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); if (err < 0) return err; - err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, + err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, + name, i, HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); if (err < 0) @@ -12085,13 +12104,8 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, spec->multiout.dac_nids = spec->private_dac_nids; spec->multiout.dac_nids[0] = 2; - if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) - pfx = "Master"; - else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) - pfx = "Speaker"; - else if (cfg->line_out_type == AUTO_PIN_HP_OUT) - pfx = "Headphone"; - else + pfx = alc_get_line_out_pfx(cfg, true); + if (!pfx) pfx = "Front"; for (i = 0; i < 2; i++) { err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); @@ -15885,13 +15899,16 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec, return 0; } -static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, - hda_nid_t nid, unsigned int chs) +static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx, + hda_nid_t nid, int idx, unsigned int chs) { - return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, + return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx, HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); } +#define alc861_create_out_sw(codec, pfx, nid, chs) \ + __alc861_create_out_sw(codec, pfx, nid, 0, chs) + /* add playback controls from the parsed DAC table */ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) @@ -15900,26 +15917,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + const char *pfx = alc_get_line_out_pfx(cfg, true); hda_nid_t nid; int i, err; - if (cfg->line_outs == 1) { - const char *pfx = NULL; - if (!cfg->hp_outs) - pfx = "Master"; - else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) - pfx = "Speaker"; - if (pfx) { - nid = spec->multiout.dac_nids[0]; - return alc861_create_out_sw(codec, pfx, nid, 3); - } - } - for (i = 0; i < cfg->line_outs; i++) { nid = spec->multiout.dac_nids[i]; if (!nid) continue; - if (i == 2) { + if (!pfx && i == 2) { /* Center/LFE */ err = alc861_create_out_sw(codec, "Center", nid, 1); if (err < 0) @@ -15928,7 +15934,10 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, if (err < 0) return err; } else { - err = alc861_create_out_sw(codec, chname[i], nid, 3); + const char *name = pfx; + if (!name) + name = chname[i]; + err = __alc861_create_out_sw(codec, name, nid, i, 3); if (err < 0) return err; } @@ -17033,6 +17042,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; + const char *pfx = alc_get_line_out_pfx(cfg, true); hda_nid_t nid_v, nid_s; int i, err; @@ -17046,7 +17056,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, alc880_dac_to_idx( spec->multiout.dac_nids[i])); - if (i == 2) { + if (!pfx && i == 2) { /* Center/LFE */ err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Center", @@ -17073,24 +17083,17 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, if (err < 0) return err; } else { - const char *pfx; - if (cfg->line_outs == 1 && - cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { - if (!cfg->hp_pins) - pfx = "Speaker"; - else - pfx = "PCM"; - } else - pfx = chname[i]; - err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, + const char *name = pfx; + if (!name) + name = chname[i]; + err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, + name, i, HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); if (err < 0) return err; - if (cfg->line_outs == 1 && - cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) - pfx = "Speaker"; - err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, + err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, + name, i, HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); if (err < 0) @@ -19078,20 +19081,24 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec, return 0; } -static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, - hda_nid_t nid, unsigned int chs) +static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, + hda_nid_t nid, int idx, unsigned int chs) { - return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, + return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); } -static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, - hda_nid_t nid, unsigned int chs) +static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, + hda_nid_t nid, int idx, unsigned int chs) { - return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, + return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); } +#define alc662_add_vol_ctl(spec, pfx, nid, chs) \ + __alc662_add_vol_ctl(spec, pfx, nid, 0, chs) +#define alc662_add_sw_ctl(spec, pfx, nid, chs) \ + __alc662_add_sw_ctl(spec, pfx, nid, 0, chs) #define alc662_add_stereo_vol(spec, pfx, nid) \ alc662_add_vol_ctl(spec, pfx, nid, 3) #define alc662_add_stereo_sw(spec, pfx, nid) \ @@ -19105,6 +19112,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + const char *pfx = alc_get_line_out_pfx(cfg, true); hda_nid_t nid, mix; int i, err; @@ -19115,7 +19123,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); if (!mix) continue; - if (i == 2) { + if (!pfx && i == 2) { /* Center/LFE */ err = alc662_add_vol_ctl(spec, "Center", nid, 1); if (err < 0) @@ -19130,22 +19138,13 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, if (err < 0) return err; } else { - const char *pfx; - if (cfg->line_outs == 1 && - cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { - if (cfg->hp_outs) - pfx = "Speaker"; - else - pfx = "PCM"; - } else - pfx = chname[i]; - err = alc662_add_vol_ctl(spec, pfx, nid, 3); + const char *name = pfx; + if (!name) + name = chname[i]; + err = __alc662_add_vol_ctl(spec, name, nid, i, 3); if (err < 0) return err; - if (cfg->line_outs == 1 && - cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) - pfx = "Speaker"; - err = alc662_add_sw_ctl(spec, pfx, mix, 3); + err = __alc662_add_sw_ctl(spec, name, mix, i, 3); if (err < 0) return err; } -- cgit v1.2.3 From 1f4d7be7293aecd5f8469a46f606f62f0f05d84c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 15:59:38 +0100 Subject: ALSA: oxygen: allow different number of PCM and mixer channels For cards like the Xonar HDAV1.3, differentiate between the number of PCM channels that can be played and the number of channels whose volume can be adjusted. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 8 +++++--- sound/pci/oxygen/oxygen.h | 3 ++- sound/pci/oxygen/oxygen_mixer.c | 8 ++++---- sound/pci/oxygen/oxygen_pcm.c | 2 +- sound/pci/oxygen/xonar_cs43xx.c | 3 ++- sound/pci/oxygen/xonar_pcm179x.c | 13 +++++++++---- sound/pci/oxygen/xonar_wm87x6.c | 3 ++- 7 files changed, 25 insertions(+), 15 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index dc47977becae..fe7ed4fc9f46 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -185,7 +185,7 @@ static void ak4396_init(struct oxygen *chip) { struct generic_data *data = chip->model_data; - data->dacs = chip->model.dac_channels / 2; + data->dacs = chip->model.dac_channels_pcm / 2; data->ak4396_regs[0][AK4396_CONTROL_2] = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; ak4396_registers_init(chip); @@ -583,7 +583,8 @@ static const struct oxygen_model model_generic = { CAPTURE_1_FROM_SPDIF | CAPTURE_2_FROM_AC97_1 | AC97_CD_INPUT, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 0, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI | @@ -643,7 +644,8 @@ static int __devinit get_oxygen_model(struct oxygen *chip, PLAYBACK_1_TO_SPDIF; if (id->driver_data == MODEL_FANTASIA) chip->model.device_config |= CAPTURE_0_FROM_I2S_1; - chip->model.dac_channels = 2; + chip->model.dac_channels_pcm = 2; + chip->model.dac_channels_mixer = 2; break; } if (id->driver_data == MODEL_MERIDIAN || diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index b8fbc15b89a3..3d9535c2debb 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -100,7 +100,8 @@ struct oxygen_model { unsigned long private_data; size_t model_data_size; unsigned int device_config; - u8 dac_channels; + u8 dac_channels_pcm; + u8 dac_channels_mixer; u8 dac_volume_min; u8 dac_volume_max; u8 misc_flags; diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 605e84b9e1ec..242c1cac69b8 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -31,7 +31,7 @@ static int dac_volume_info(struct snd_kcontrol *ctl, struct oxygen *chip = ctl->private_data; info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = chip->model.dac_channels; + info->count = chip->model.dac_channels_mixer; info->value.integer.min = chip->model.dac_volume_min; info->value.integer.max = chip->model.dac_volume_max; return 0; @@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl, unsigned int i; mutex_lock(&chip->mutex); - for (i = 0; i < chip->model.dac_channels; ++i) + for (i = 0; i < chip->model.dac_channels_mixer; ++i) value->value.integer.value[i] = chip->dac_volume[i]; mutex_unlock(&chip->mutex); return 0; @@ -59,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl, changed = 0; mutex_lock(&chip->mutex); - for (i = 0; i < chip->model.dac_channels; ++i) + for (i = 0; i < chip->model.dac_channels_mixer; ++i) if (value->value.integer.value[i] != chip->dac_volume[i]) { chip->dac_volume[i] = value->value.integer.value[i]; changed = 1; @@ -1022,7 +1022,7 @@ static int add_controls(struct oxygen *chip, continue; } if (!strcmp(template.name, "Stereo Upmixing") && - chip->model.dac_channels == 2) + chip->model.dac_channels_pcm == 2) continue; if (!strcmp(template.name, "Mic Source Capture Enum") && !(chip->model.device_config & AC97_FMIC_SWITCH)) diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 60e4aa00c042..dc3c68f76df4 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -143,7 +143,7 @@ static int oxygen_open(struct snd_pcm_substream *substream, runtime->hw.rate_min = 44100; break; case PCM_MULTICH: - runtime->hw.channels_max = chip->model.dac_channels; + runtime->hw.channels_max = chip->model.dac_channels_pcm; break; } if (chip->model.pcm_hardware_filter) diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index de32895b3172..a25197ca39a1 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -426,7 +426,8 @@ static const struct oxygen_model model_xonar_d1 = { PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | AC97_FMIC_SWITCH, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 127 - 60, .dac_volume_max = 127, .function_flags = OXYGEN_FUNCTION_2WIRE, diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index bf357c01afd2..b55149e9be81 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -1094,7 +1094,8 @@ static const struct oxygen_model model_xonar_d2 = { MIDI_OUTPUT | MIDI_INPUT | AC97_CD_INPUT, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .misc_flags = OXYGEN_MISC_MIDI, @@ -1127,7 +1128,8 @@ static const struct oxygen_model model_xonar_hdav = { PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 2, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .misc_flags = OXYGEN_MISC_MIDI, @@ -1157,7 +1159,8 @@ static const struct oxygen_model model_xonar_st = { PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | AC97_FMIC_SWITCH, - .dac_channels = 2, + .dac_channels_pcm = 2, + .dac_channels_mixer = 2, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_2WIRE, @@ -1187,6 +1190,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, break; case GPIO_DB_H6: chip->model.shortname = "Xonar HDAV1.3+H6"; + chip->model.dac_channels_mixer = 8; chip->model.private_data = 1; break; } @@ -1200,7 +1204,8 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, break; case GPIO_DB_H6: chip->model.shortname = "Xonar ST+H6"; - chip->model.dac_channels = 8; + chip->model.dac_channels_pcm = 8; + chip->model.dac_channels_mixer = 8; chip->model.private_data = 1; break; } diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 1705d1e93115..da92cc24eed2 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -1135,7 +1135,8 @@ static const struct oxygen_model model_xonar_ds = { .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_1, - .dac_channels = 8, + .dac_channels_pcm = 8, + .dac_channels_mixer = 8, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI, -- cgit v1.2.3 From d2119c05e9aee7e44055220726bb8814a2e242c3 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:00:34 +0100 Subject: ALSA: oxygen: remove oxygen_model::private_data field The number of DACs can now be deduced from the dac_channels_mixer field, so the private_data field is no longer needed. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.h | 1 - sound/pci/oxygen/xonar_pcm179x.c | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 3d9535c2debb..70eff3747158 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -97,7 +97,6 @@ struct oxygen_model { void (*dump_registers)(struct oxygen *chip, struct snd_info_buffer *buffer); const unsigned int *dac_tlv; - unsigned long private_data; size_t model_data_size; unsigned int device_config; u8 dac_channels_pcm; diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index b55149e9be81..5ec8be3bf7c7 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -381,7 +381,7 @@ static void xonar_hdav_init(struct oxygen *chip) data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA; data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER; - data->pcm179x.dacs = chip->model.private_data ? 4 : 1; + data->pcm179x.dacs = chip->model.dac_channels_mixer / 2; pcm1796_init(chip); @@ -411,7 +411,7 @@ static void xonar_st_init_common(struct oxygen *chip) struct xonar_pcm179x *data = chip->model_data; data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; - data->dacs = chip->model.private_data ? 4 : 1; + data->dacs = chip->model.dac_channels_mixer / 2; data->hp_gain_offset = 2*-18; pcm1796_init(chip); @@ -1191,7 +1191,6 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, case GPIO_DB_H6: chip->model.shortname = "Xonar HDAV1.3+H6"; chip->model.dac_channels_mixer = 8; - chip->model.private_data = 1; break; } break; @@ -1206,7 +1205,6 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, chip->model.shortname = "Xonar ST+H6"; chip->model.dac_channels_pcm = 8; chip->model.dac_channels_mixer = 8; - chip->model.private_data = 1; break; } break; -- cgit v1.2.3 From 5ea310ff8d651246cf001ebc894d2f294123328a Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:01:17 +0100 Subject: ALSA: oxygen: fix SPI clocks slower than 6.25 MHz Fix wrong register bits for SPI clock cycle times longer than 160 ns, and adjust the polling loop timeout for these speeds. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_io.c | 4 ++-- sound/pci/oxygen/oxygen_regs.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c index 09b2b2a36df5..f5164b1e1c80 100644 --- a/sound/pci/oxygen/oxygen_io.c +++ b/sound/pci/oxygen/oxygen_io.c @@ -197,11 +197,11 @@ void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data) { unsigned int count; - /* should not need more than 7.68 us (24 * 320 ns) */ + /* should not need more than 30.72 us (24 * 1.28 us) */ count = 10; while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY) && count > 0) { - udelay(1); + udelay(4); --count; } diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h index 4dcd41b78258..331d3d96fa21 100644 --- a/sound/pci/oxygen/oxygen_regs.h +++ b/sound/pci/oxygen/oxygen_regs.h @@ -238,11 +238,11 @@ #define OXYGEN_SPI_DATA_LENGTH_MASK 0x02 #define OXYGEN_SPI_DATA_LENGTH_2 0x00 #define OXYGEN_SPI_DATA_LENGTH_3 0x02 -#define OXYGEN_SPI_CLOCK_MASK 0xc0 +#define OXYGEN_SPI_CLOCK_MASK 0x0c #define OXYGEN_SPI_CLOCK_160 0x00 /* ns */ -#define OXYGEN_SPI_CLOCK_320 0x40 -#define OXYGEN_SPI_CLOCK_640 0x80 -#define OXYGEN_SPI_CLOCK_1280 0xc0 +#define OXYGEN_SPI_CLOCK_320 0x04 +#define OXYGEN_SPI_CLOCK_640 0x08 +#define OXYGEN_SPI_CLOCK_1280 0x0c #define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */ #define OXYGEN_SPI_CODEC_SHIFT 4 #define OXYGEN_SPI_CEN_MASK 0x80 -- cgit v1.2.3 From 4106055cedea86596391f36deacd05616333fbb3 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:01:57 +0100 Subject: ALSA: virtuoso: do not use fast I2C speed To make the I2C communication reliable when using the H6 daughterboard, reduce the I2C clock frequency. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 5ec8be3bf7c7..49898d39f875 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -374,7 +374,7 @@ static void xonar_hdav_init(struct oxygen *chip) oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, OXYGEN_2WIRE_LENGTH_8 | OXYGEN_2WIRE_INTERRUPT_MASK | - OXYGEN_2WIRE_SPEED_FAST); + OXYGEN_2WIRE_SPEED_STANDARD); data->pcm179x.generic.anti_pop_delay = 100; data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE; @@ -403,7 +403,7 @@ static void xonar_st_init_i2c(struct oxygen *chip) oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, OXYGEN_2WIRE_LENGTH_8 | OXYGEN_2WIRE_INTERRUPT_MASK | - OXYGEN_2WIRE_SPEED_FAST); + OXYGEN_2WIRE_SPEED_STANDARD); } static void xonar_st_init_common(struct oxygen *chip) -- cgit v1.2.3 From 79815e004c75dcc2be6433737b5678cee80035db Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:02:32 +0100 Subject: ALSA: virtuoso: wait for PCM1796 clock to become stable The PCM1796 needs the master clock for I2C communication to work, so add delays after clock changes to ensure that the clock is stable when we try to write the DACs' registers. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 49898d39f875..5ec164a70cf2 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -303,6 +303,7 @@ static void pcm1796_registers_init(struct oxygen *chip) unsigned int i; s8 gain_offset; + msleep(1); gain_offset = data->hp_active ? data->hp_gain_offset : 0; for (i = 0; i < data->dacs; ++i) { /* set ATLD before ATL/ATR */ @@ -451,6 +452,7 @@ static void cs2000_registers_init(struct oxygen *chip) data->cs2000_regs[CS2000_FUN_CFG_1]); cs2000_write(chip, CS2000_FUN_CFG_2, 0); cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2); + msleep(3); /* PLL lock delay */ } static void xonar_st_init(struct oxygen *chip) @@ -592,6 +594,7 @@ static void set_pcm1796_params(struct oxygen *chip, { struct xonar_pcm179x *data = chip->model_data; + msleep(1); data->current_rate = params_rate(params); update_pcm1796_oversampling(chip); } @@ -669,6 +672,7 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate) else reg = CS2000_REF_CLK_DIV_2; cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg); + msleep(3); /* PLL lock delay */ } static void set_st_params(struct oxygen *chip, @@ -796,6 +800,7 @@ static int os_128_put(struct snd_kcontrol *ctl, oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, mclk_from_rate(chip, data->current_rate), OXYGEN_I2S_MCLK_MASK); + msleep(1); update_pcm1796_oversampling(chip); } mutex_unlock(&chip->mutex); -- cgit v1.2.3 From 03ff959dd4e290ed909fd57dec79ccd0262c4095 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:03:17 +0100 Subject: ALSA: virtuoso: change PCM1796 format to I2S Change the PCM format used for the PCM1796 from left-justified to I2S to ensure that the correct format is used even for the Essence ST Deluxe's center/LFE DAC, where I2C does not work because of an address conflict with the CS2000 chip. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 5ec164a70cf2..051554e2f928 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -326,7 +326,7 @@ static void pcm1796_init(struct oxygen *chip) struct xonar_pcm179x *data = chip->model_data; data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE | - PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; + PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = PCM1796_FLT_SHARP | PCM1796_ATS_1; data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64; @@ -620,7 +620,7 @@ static void update_pcm1796_mute(struct oxygen *chip) unsigned int i; u8 value; - value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; + value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; if (chip->dac_mute) value |= PCM1796_MUTE; for (i = 0; i < data->dacs; ++i) @@ -1106,7 +1106,7 @@ static const struct oxygen_model model_xonar_d2 = { .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1139,7 +1139,7 @@ static const struct oxygen_model model_xonar_hdav = { .dac_volume_max = 255, .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_2WIRE, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1169,7 +1169,7 @@ static const struct oxygen_model model_xonar_st = { .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_2WIRE, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; -- cgit v1.2.3 From dd203fa97bd5df18dbb0af5acf3e9a8beea33f74 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:05:38 +0100 Subject: ALSA: virtuoso: remove non-working controls on Essence ST Deluxe On the Xonar Essence ST Deluxe, remove all mixer controls that would require I2C communication with the third DAC, which does not work because of an addressing conflict with the CS2000 chip. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 051554e2f928..2e31b81fc49f 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -228,6 +228,7 @@ struct xonar_pcm179x { s8 hp_gain_offset; bool has_cs2000; u8 cs2000_regs[0x1f]; + bool broken_i2c; }; struct xonar_hdav { @@ -462,6 +463,7 @@ static void xonar_st_init(struct oxygen *chip) data->generic.anti_pop_delay = 100; data->has_cs2000 = 1; data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1; + data->broken_i2c = true; oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | @@ -980,16 +982,29 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template) return 0; } +static int xonar_st_h6_control_filter(struct snd_kcontrol_new *template) +{ + if (!strncmp(template->name, "Master Playback ", 16)) + /* no volume/mute, as I²C to the third DAC does not work */ + return 1; + return 0; +} + static int add_pcm1796_controls(struct oxygen *chip) { + struct xonar_pcm179x *data = chip->model_data; int err; - err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); - if (err < 0) - return err; - err = snd_ctl_add(chip->card, snd_ctl_new1(&os_128_control, chip)); - if (err < 0) - return err; + if (!data->broken_i2c) { + err = snd_ctl_add(chip->card, + snd_ctl_new1(&rolloff_control, chip)); + if (err < 0) + return err; + err = snd_ctl_add(chip->card, + snd_ctl_new1(&os_128_control, chip)); + if (err < 0) + return err; + } return 0; } @@ -1208,6 +1223,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, break; case GPIO_DB_H6: chip->model.shortname = "Xonar ST+H6"; + chip->model.control_filter = xonar_st_h6_control_filter; chip->model.dac_channels_pcm = 8; chip->model.dac_channels_mixer = 8; break; -- cgit v1.2.3 From d353eaa9a8133cdad8c1da23c84f9f529a23f0c2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:07:11 +0100 Subject: ALSA: virtuoso: configure correct master clock frequency on the CS2000 The clock output of the CS2000, which is used as master clock for the DACs, was using half the actual master clock frequency for some reason. Using the theoretically correct frequency seems also to work in practice. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 2e31b81fc49f..fce55fa5b0b0 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -467,7 +467,7 @@ static void xonar_st_init(struct oxygen *chip) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | - OXYGEN_I2S_MCLK_128 | OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); xonar_st_init_i2c(chip); @@ -635,41 +635,40 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate) u8 rate_mclk, reg; switch (rate) { - /* XXX Why is the I2S A MCLK half the actual I2S MCLK? */ case 32000: - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; break; case 44100: if (data->os_128) - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; else - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_128; + rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; break; default: /* 48000 */ if (data->os_128) - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; else - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_128; + rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; break; case 64000: - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; break; case 88200: - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; break; case 96000: - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; break; case 176400: - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; break; case 192000: - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; break; } oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); - if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_128) + if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_256) reg = CS2000_REF_CLK_DIV_1; else reg = CS2000_REF_CLK_DIV_2; -- cgit v1.2.3 From 00b8dd7dd71ef129176731d5fa24f5e298797599 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:09:23 +0100 Subject: ALSA: virtuoso: use lower master clock with H6 daughterboard Because of the unshielded connector cable, it is important to use as low a master clock frequency as possible with the H6. For double rate modes (64-96 kHz), the MCLK rate is unconditionally lowered from 512x to 256x because the higher rate would not improve anything. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index fce55fa5b0b0..2a50a55cbbb1 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -224,6 +224,7 @@ struct xonar_pcm179x { u8 pcm1796_regs[4][5]; unsigned int current_rate; bool os_128; + bool h6; bool hp_active; s8 hp_gain_offset; bool has_cs2000; @@ -384,6 +385,7 @@ static void xonar_hdav_init(struct oxygen *chip) data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER; data->pcm179x.dacs = chip->model.dac_channels_mixer / 2; + data->pcm179x.h6 = chip->model.dac_channels_mixer > 2; pcm1796_init(chip); @@ -461,6 +463,7 @@ static void xonar_st_init(struct oxygen *chip) struct xonar_pcm179x *data = chip->model_data; data->generic.anti_pop_delay = 100; + data->h6 = chip->model.dac_channels_mixer > 2; data->has_cs2000 = 1; data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1; data->broken_i2c = true; @@ -554,11 +557,10 @@ static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate) struct xonar_pcm179x *data = chip->model_data; if (rate <= 32000) - return OXYGEN_I2S_MCLK_512; - else if (rate <= 48000 && data->os_128) - return OXYGEN_I2S_MCLK_512; - else if (rate <= 96000) - return OXYGEN_I2S_MCLK_256; + return data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512; + else if (rate <= 48000) + return data->os_128 && !data->h6 + ? OXYGEN_I2S_MCLK_512 : OXYGEN_I2S_MCLK_256; else return OXYGEN_I2S_MCLK_128; } @@ -579,9 +581,9 @@ static void update_pcm1796_oversampling(struct oxygen *chip) unsigned int i; u8 reg; - if (data->current_rate <= 32000) + if (data->current_rate <= 32000 && !data->h6) reg = PCM1796_OS_128; - else if (data->current_rate <= 48000 && data->os_128) + else if (data->current_rate <= 48000 && data->os_128 && !data->h6) reg = PCM1796_OS_128; else if (data->current_rate <= 96000 || data->os_128) reg = PCM1796_OS_64; @@ -636,28 +638,31 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate) switch (rate) { case 32000: - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; + if (data->h6) + rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; + else + rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; break; case 44100: - if (data->os_128) + if (data->os_128 && !data->h6) rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; else rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; break; default: /* 48000 */ - if (data->os_128) + if (data->os_128 && !data->h6) rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; else rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; break; case 64000: - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; + rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; break; case 88200: - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; + rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; break; case 96000: - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; + rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; break; case 176400: rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; -- cgit v1.2.3 From c97e2dc48457642e2f1c6183b986549b7fa0113a Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:11:05 +0100 Subject: ALSA: virtuoso: handle DAC oversampling automatically Remove the DAC Oversampling mixer control because this setting does not make much sense. For cards with the H6 daughterboard, 128x oversampling was disabled anyway because these high MCLK frequency would not be compatible with the connector cable. For cards without the H6 daughterboard, 128x gives a slightly higher output quality; there is no reason to reduce it to 64x except for saving power, but then these cards have not been designed to be power efficient anyway (the D2's blinkenlights cannot be disabled). Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 100 ++++++++------------------------------- 1 file changed, 21 insertions(+), 79 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 2a50a55cbbb1..2d0a634a7239 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -223,7 +223,6 @@ struct xonar_pcm179x { unsigned int dacs; u8 pcm1796_regs[4][5]; unsigned int current_rate; - bool os_128; bool h6; bool hp_active; s8 hp_gain_offset; @@ -331,9 +330,14 @@ static void pcm1796_init(struct oxygen *chip) PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = PCM1796_FLT_SHARP | PCM1796_ATS_1; - data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64; + data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = + data->h6 ? PCM1796_OS_64 : PCM1796_OS_128; pcm1796_registers_init(chip); data->current_rate = 48000; + if (!data->h6) + oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, + OXYGEN_I2S_MCLK_512, + OXYGEN_I2S_MCLK_MASK); } static void xonar_d2_init(struct oxygen *chip) @@ -469,9 +473,12 @@ static void xonar_st_init(struct oxygen *chip) data->broken_i2c = true; oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, - OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | - OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | - OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); + OXYGEN_RATE_48000 | + OXYGEN_I2S_FORMAT_I2S | + (data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512) | + OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MASTER | + OXYGEN_I2S_BCLK_64); xonar_st_init_i2c(chip); cs2000_registers_init(chip); @@ -556,11 +563,8 @@ static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate) { struct xonar_pcm179x *data = chip->model_data; - if (rate <= 32000) + if (rate <= 48000) return data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512; - else if (rate <= 48000) - return data->os_128 && !data->h6 - ? OXYGEN_I2S_MCLK_512 : OXYGEN_I2S_MCLK_256; else return OXYGEN_I2S_MCLK_128; } @@ -581,14 +585,10 @@ static void update_pcm1796_oversampling(struct oxygen *chip) unsigned int i; u8 reg; - if (data->current_rate <= 32000 && !data->h6) + if (data->current_rate <= 48000 && !data->h6) reg = PCM1796_OS_128; - else if (data->current_rate <= 48000 && data->os_128 && !data->h6) - reg = PCM1796_OS_128; - else if (data->current_rate <= 96000 || data->os_128) - reg = PCM1796_OS_64; else - reg = PCM1796_OS_32; + reg = PCM1796_OS_64; for (i = 0; i < data->dacs; ++i) pcm1796_write_cached(chip, i, 20, reg); } @@ -644,16 +644,16 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate) rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; break; case 44100: - if (data->os_128 && !data->h6) - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; - else + if (data->h6) rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; + else + rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; break; default: /* 48000 */ - if (data->os_128 && !data->h6) - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; - else + if (data->h6) rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; + else + rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; break; case 64000: rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; @@ -767,60 +767,6 @@ static const struct snd_kcontrol_new rolloff_control = { .put = rolloff_put, }; -static int os_128_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) -{ - static const char *const names[2] = { "64x", "128x" }; - - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - if (info->value.enumerated.item >= 2) - info->value.enumerated.item = 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; -} - -static int os_128_get(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) -{ - struct oxygen *chip = ctl->private_data; - struct xonar_pcm179x *data = chip->model_data; - - value->value.enumerated.item[0] = data->os_128; - return 0; -} - -static int os_128_put(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) -{ - struct oxygen *chip = ctl->private_data; - struct xonar_pcm179x *data = chip->model_data; - int changed; - - mutex_lock(&chip->mutex); - changed = value->value.enumerated.item[0] != data->os_128; - if (changed) { - data->os_128 = value->value.enumerated.item[0]; - if (data->has_cs2000) - update_cs2000_rate(chip, data->current_rate); - oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, - mclk_from_rate(chip, data->current_rate), - OXYGEN_I2S_MCLK_MASK); - msleep(1); - update_pcm1796_oversampling(chip); - } - mutex_unlock(&chip->mutex); - return changed; -} - -static const struct snd_kcontrol_new os_128_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Oversampling Playback Enum", - .info = os_128_info, - .get = os_128_get, - .put = os_128_put, -}; - static const struct snd_kcontrol_new hdav_hdmi_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "HDMI Playback Switch", @@ -1004,10 +950,6 @@ static int add_pcm1796_controls(struct oxygen *chip) snd_ctl_new1(&rolloff_control, chip)); if (err < 0) return err; - err = snd_ctl_add(chip->card, - snd_ctl_new1(&os_128_control, chip)); - if (err < 0) - return err; } return 0; } -- cgit v1.2.3 From bc29e262c3062682c6099bd455ae8544916f723e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:11:32 +0100 Subject: ALSA: virtuoso: use headphone gain setting only on front DAC Do not apply the headphone gain offset to any but the front DAC. These DACs would not be used in headphone mode, so this saves a few register writes. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_pcm179x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 2d0a634a7239..e15ecee2ccf7 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -319,6 +319,7 @@ static void pcm1796_registers_init(struct oxygen *chip) pcm1796_write(chip, i, 20, data->pcm1796_regs[0][20 - PCM1796_REG_BASE]); pcm1796_write(chip, i, 21, 0); + gain_offset = 0; } } @@ -615,6 +616,7 @@ static void update_pcm1796_volume(struct oxygen *chip) + gain_offset); pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1] + gain_offset); + gain_offset = 0; } } -- cgit v1.2.3 From 5b8bf2a54fb13e40519ee846ce27bc8a2d7a7878 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:14:52 +0100 Subject: ALSA: oxygen: simplify model-specific MCLK handling Replace the get_i2s_mclk callback with tables of MCLK values. This simplifies the MCLK-handling code in both the framework and the model- specific drivers. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 3 +- sound/pci/oxygen/oxygen.h | 10 +++-- sound/pci/oxygen/oxygen_lib.c | 36 ++++++++++++------ sound/pci/oxygen/oxygen_pcm.c | 39 +++++++++++-------- sound/pci/oxygen/oxygen_regs.h | 8 ++-- sound/pci/oxygen/xonar_cs43xx.c | 3 +- sound/pci/oxygen/xonar_pcm179x.c | 82 ++++++++++++---------------------------- sound/pci/oxygen/xonar_wm87x6.c | 3 +- 8 files changed, 89 insertions(+), 95 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index fe7ed4fc9f46..784d500c700f 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -568,7 +568,6 @@ static const struct oxygen_model model_generic = { .mixer_init = generic_wm8785_mixer_init, .cleanup = generic_cleanup, .resume = generic_resume, - .get_i2s_mclk = oxygen_default_i2s_mclk, .set_dac_params = set_ak4396_params, .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, @@ -589,6 +588,8 @@ static const struct oxygen_model model_generic = { .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5, + .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 70eff3747158..2c5fb9edcb11 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -16,6 +16,10 @@ #define PCM_AC97 5 #define PCM_COUNT 6 +#define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \ + (MCLK_##f_double << 2) | \ + (MCLK_##f_quad << 4)) + #define OXYGEN_IO_SIZE 0x100 #define OXYGEN_EEPROM_ID 0x434d /* "CM" */ @@ -81,8 +85,6 @@ struct oxygen_model { void (*resume)(struct oxygen *chip); void (*pcm_hardware_filter)(unsigned int channel, struct snd_pcm_hardware *hardware); - unsigned int (*get_i2s_mclk)(struct oxygen *chip, unsigned int channel, - struct snd_pcm_hw_params *hw_params); void (*set_dac_params)(struct oxygen *chip, struct snd_pcm_hw_params *params); void (*set_adc_params)(struct oxygen *chip, @@ -105,6 +107,8 @@ struct oxygen_model { u8 dac_volume_max; u8 misc_flags; u8 function_flags; + u8 dac_mclks; + u8 adc_mclks; u16 dac_i2s_format; u16 adc_i2s_format; }; @@ -171,8 +175,6 @@ void oxygen_update_spdif_source(struct oxygen *chip); /* oxygen_pcm.c */ int oxygen_pcm_init(struct oxygen *chip); -unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, unsigned int channel, - struct snd_pcm_hw_params *hw_params); /* oxygen_io.c */ diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index c44c91e6fb18..77e1f0805633 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -414,28 +414,40 @@ static void oxygen_init(struct oxygen *chip) (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, - OXYGEN_RATE_48000 | chip->model.dac_i2s_format | - OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | - OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); + OXYGEN_RATE_48000 | + chip->model.dac_i2s_format | + OXYGEN_I2S_MCLK(chip->model.dac_mclks) | + OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MASTER | + OXYGEN_I2S_BCLK_64); if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, - OXYGEN_RATE_48000 | chip->model.adc_i2s_format | - OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | - OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); + OXYGEN_RATE_48000 | + chip->model.adc_i2s_format | + OXYGEN_I2S_MCLK(chip->model.adc_mclks) | + OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MASTER | + OXYGEN_I2S_BCLK_64); else oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, - OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); + OXYGEN_I2S_MASTER | + OXYGEN_I2S_MUTE_MCLK); if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 | CAPTURE_2_FROM_I2S_2)) oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, - OXYGEN_RATE_48000 | chip->model.adc_i2s_format | - OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | - OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); + OXYGEN_RATE_48000 | + chip->model.adc_i2s_format | + OXYGEN_I2S_MCLK(chip->model.adc_mclks) | + OXYGEN_I2S_BITS_16 | + OXYGEN_I2S_MASTER | + OXYGEN_I2S_BCLK_64); else oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, - OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); + OXYGEN_I2S_MASTER | + OXYGEN_I2S_MUTE_MCLK); oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, - OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); + OXYGEN_I2S_MASTER | + OXYGEN_I2S_MUTE_MCLK); oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_OUT_ENABLE | OXYGEN_SPDIF_LOOPBACK); diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index dc3c68f76df4..d5533e34ece9 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -274,17 +274,6 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params) } } -unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, - unsigned int channel, - struct snd_pcm_hw_params *hw_params) -{ - if (params_rate(hw_params) <= 96000) - return OXYGEN_I2S_MCLK_256; - else - return OXYGEN_I2S_MCLK_128; -} -EXPORT_SYMBOL(oxygen_default_i2s_mclk); - static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) { if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE) @@ -344,6 +333,26 @@ static int oxygen_hw_params(struct snd_pcm_substream *substream, return 0; } +static u16 get_mclk(struct oxygen *chip, unsigned int channel, + struct snd_pcm_hw_params *params) +{ + unsigned int mclks, shift; + + if (channel == PCM_MULTICH) + mclks = chip->model.dac_mclks; + else + mclks = chip->model.adc_mclks; + + if (params_rate(params) <= 48000) + shift = 0; + else if (params_rate(params) <= 96000) + shift = 2; + else + shift = 4; + + return OXYGEN_I2S_MCLK(mclks >> shift); +} + static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { @@ -360,8 +369,8 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, OXYGEN_REC_FORMAT_A_MASK); oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, oxygen_rate(hw_params) | - chip->model.get_i2s_mclk(chip, PCM_A, hw_params) | chip->model.adc_i2s_format | + get_mclk(chip, PCM_A, hw_params) | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | @@ -396,9 +405,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, if (!is_ac97) oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, oxygen_rate(hw_params) | - chip->model.get_i2s_mclk(chip, PCM_B, - hw_params) | chip->model.adc_i2s_format | + get_mclk(chip, PCM_B, hw_params) | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | @@ -479,8 +487,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream, oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, oxygen_rate(hw_params) | chip->model.dac_i2s_format | - chip->model.get_i2s_mclk(chip, PCM_MULTICH, - hw_params) | + get_mclk(chip, PCM_MULTICH, hw_params) | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h index 331d3d96fa21..63dc7a0ab555 100644 --- a/sound/pci/oxygen/oxygen_regs.h +++ b/sound/pci/oxygen/oxygen_regs.h @@ -139,9 +139,11 @@ #define OXYGEN_I2S_FORMAT_I2S 0x0000 #define OXYGEN_I2S_FORMAT_LJUST 0x0008 #define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */ -#define OXYGEN_I2S_MCLK_128 0x0000 -#define OXYGEN_I2S_MCLK_256 0x0010 -#define OXYGEN_I2S_MCLK_512 0x0020 +#define OXYGEN_I2S_MCLK_SHIFT 4 +#define MCLK_128 0 +#define MCLK_256 1 +#define MCLK_512 2 +#define OXYGEN_I2S_MCLK(f) (((f) & 3) << OXYGEN_I2S_MCLK_SHIFT) #define OXYGEN_I2S_BITS_MASK 0x00c0 #define OXYGEN_I2S_BITS_16 0x0000 #define OXYGEN_I2S_BITS_20 0x0040 diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index a25197ca39a1..b651938f3248 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -412,7 +412,6 @@ static const struct oxygen_model model_xonar_d1 = { .cleanup = xonar_d1_cleanup, .suspend = xonar_d1_suspend, .resume = xonar_d1_resume, - .get_i2s_mclk = oxygen_default_i2s_mclk, .set_dac_params = set_cs43xx_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_cs43xx_volume, @@ -431,6 +430,8 @@ static const struct oxygen_model model_xonar_d1 = { .dac_volume_min = 127 - 60, .dac_volume_max = 127, .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index e15ecee2ccf7..9787193f6ed3 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -335,10 +335,6 @@ static void pcm1796_init(struct oxygen *chip) data->h6 ? PCM1796_OS_64 : PCM1796_OS_128; pcm1796_registers_init(chip); data->current_rate = 48000; - if (!data->h6) - oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, - OXYGEN_I2S_MCLK_512, - OXYGEN_I2S_MCLK_MASK); } static void xonar_d2_init(struct oxygen *chip) @@ -476,7 +472,7 @@ static void xonar_st_init(struct oxygen *chip) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | - (data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512) | + OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); @@ -560,26 +556,6 @@ static void xonar_st_resume(struct oxygen *chip) xonar_stx_resume(chip); } -static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate) -{ - struct xonar_pcm179x *data = chip->model_data; - - if (rate <= 48000) - return data->h6 ? OXYGEN_I2S_MCLK_256 : OXYGEN_I2S_MCLK_512; - else - return OXYGEN_I2S_MCLK_128; -} - -static unsigned int get_pcm1796_i2s_mclk(struct oxygen *chip, - unsigned int channel, - struct snd_pcm_hw_params *params) -{ - if (channel == PCM_MULTICH) - return mclk_from_rate(chip, params_rate(params)); - else - return oxygen_default_i2s_mclk(chip, channel, params); -} - static void update_pcm1796_oversampling(struct oxygen *chip) { struct xonar_pcm179x *data = chip->model_data; @@ -640,45 +616,32 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate) switch (rate) { case 32000: - if (data->h6) - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; - else - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_512; - break; - case 44100: - if (data->h6) - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; - else - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; - break; - default: /* 48000 */ - if (data->h6) - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; - else - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; - break; case 64000: - rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; + rate_mclk = OXYGEN_RATE_32000; break; + case 44100: case 88200: - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; - break; - case 96000: - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; - break; case 176400: - rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_512; + rate_mclk = OXYGEN_RATE_44100; break; + default: + case 48000: + case 96000: case 192000: - rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_512; + rate_mclk = OXYGEN_RATE_48000; break; } - oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, - OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); - if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_256) + + if (rate <= 96000 && (rate > 48000 || data->h6)) { + rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256); reg = CS2000_REF_CLK_DIV_1; - else + } else { + rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512); reg = CS2000_REF_CLK_DIV_2; + } + + oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, + OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg); msleep(3); /* PLL lock delay */ } @@ -1047,7 +1010,6 @@ static const struct oxygen_model model_xonar_d2 = { .cleanup = xonar_d2_cleanup, .suspend = xonar_d2_suspend, .resume = xonar_d2_resume, - .get_i2s_mclk = get_pcm1796_i2s_mclk, .set_dac_params = set_pcm1796_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -1069,6 +1031,8 @@ static const struct oxygen_model model_xonar_d2 = { .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5, + .dac_mclks = OXYGEN_MCLKS(512, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1082,7 +1046,6 @@ static const struct oxygen_model model_xonar_hdav = { .suspend = xonar_hdav_suspend, .resume = xonar_hdav_resume, .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter, - .get_i2s_mclk = get_pcm1796_i2s_mclk, .set_dac_params = set_hdav_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -1102,6 +1065,8 @@ static const struct oxygen_model model_xonar_hdav = { .dac_volume_max = 255, .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_mclks = OXYGEN_MCLKS(512, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1114,7 +1079,6 @@ static const struct oxygen_model model_xonar_st = { .cleanup = xonar_st_cleanup, .suspend = xonar_st_suspend, .resume = xonar_st_resume, - .get_i2s_mclk = get_pcm1796_i2s_mclk, .set_dac_params = set_st_params, .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, @@ -1132,6 +1096,8 @@ static const struct oxygen_model model_xonar_st = { .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_mclks = OXYGEN_MCLKS(512, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1159,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, case GPIO_DB_H6: chip->model.shortname = "Xonar HDAV1.3+H6"; chip->model.dac_channels_mixer = 8; + chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); break; } break; @@ -1174,6 +1141,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, chip->model.control_filter = xonar_st_h6_control_filter; chip->model.dac_channels_pcm = 8; chip->model.dac_channels_mixer = 8; + chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128); break; } break; diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index da92cc24eed2..4f9657084603 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -1122,7 +1122,6 @@ static const struct oxygen_model model_xonar_ds = { .suspend = xonar_ds_suspend, .resume = xonar_ds_resume, .pcm_hardware_filter = wm8776_adc_hardware_filter, - .get_i2s_mclk = oxygen_default_i2s_mclk, .set_dac_params = set_wm87x6_dac_params, .set_adc_params = set_wm8776_adc_params, .update_dac_volume = update_wm87x6_volume, @@ -1140,6 +1139,8 @@ static const struct oxygen_model model_xonar_ds = { .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI, + .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; -- cgit v1.2.3 From ce2c492090aa55ff2764f473abdb3c5a76b4a7c4 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:16:08 +0100 Subject: ALSA: virtuoso: reduce MCLK in double rate modes For the CSxxxx and AKxxxx DAC/ADC chips, the MCLK factor in double rate modes (64-96 kHz) can be reduced to 128x without reducing sound quality. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 6 ++++-- sound/pci/oxygen/xonar_cs43xx.c | 4 ++-- sound/pci/oxygen/xonar_pcm179x.c | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 784d500c700f..2316884afd25 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -588,7 +588,7 @@ static const struct oxygen_model model_generic = { .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .dac_mclks = OXYGEN_MCLKS(256, 128, 128), .adc_mclks = OXYGEN_MCLKS(256, 256, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, @@ -643,8 +643,10 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.dump_registers = dump_ak4396_registers; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF; - if (id->driver_data == MODEL_FANTASIA) + if (id->driver_data == MODEL_FANTASIA) { chip->model.device_config |= CAPTURE_0_FROM_I2S_1; + chip->model.adc_mclks = OXYGEN_MCLKS(256, 128, 128); + } chip->model.dac_channels_pcm = 2; chip->model.dac_channels_mixer = 2; break; diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index b651938f3248..55c52c7e19b2 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -430,8 +430,8 @@ static const struct oxygen_model model_xonar_d1 = { .dac_volume_min = 127 - 60, .dac_volume_max = 127, .function_flags = OXYGEN_FUNCTION_2WIRE, - .dac_mclks = OXYGEN_MCLKS(256, 256, 128), - .adc_mclks = OXYGEN_MCLKS(256, 256, 128), + .dac_mclks = OXYGEN_MCLKS(256, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 128, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 9787193f6ed3..003c4800400b 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -1032,7 +1032,7 @@ static const struct oxygen_model model_xonar_d2 = { .function_flags = OXYGEN_FUNCTION_SPI | OXYGEN_FUNCTION_ENABLE_SPI_4_5, .dac_mclks = OXYGEN_MCLKS(512, 128, 128), - .adc_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 128, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1066,7 +1066,7 @@ static const struct oxygen_model model_xonar_hdav = { .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_2WIRE, .dac_mclks = OXYGEN_MCLKS(512, 128, 128), - .adc_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 128, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; @@ -1097,7 +1097,7 @@ static const struct oxygen_model model_xonar_st = { .dac_volume_max = 255, .function_flags = OXYGEN_FUNCTION_2WIRE, .dac_mclks = OXYGEN_MCLKS(512, 128, 128), - .adc_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 128, 128), .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; -- cgit v1.2.3 From 8c50b75979a198194a38d38d855f9d7e9cac2889 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:16:32 +0100 Subject: ALSA: oxygen: add more PCI IDs Add PCI IDs for some unknown models. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 2316884afd25..e187c951b6a0 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -84,6 +84,7 @@ enum { static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { /* C-Media's reference design */ { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x10b0, 0x0217), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, @@ -91,6 +92,8 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, + /* PCI 2.0 HD Audio */ + { OXYGEN_PCI_SUBID(0x13f6, 0x8782), .driver_data = MODEL_2CH_OUTPUT }, /* Kuroutoshikou CMI8787-HG2PCI */ { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_2CH_OUTPUT }, /* TempoTec HiFier Fantasia */ -- cgit v1.2.3 From 8443d2eb81e30dcc027e531eaa442cdb2477c5ab Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:17:26 +0100 Subject: ALSA: oxygen: add X-Meridian 2G support Add support for the AuzenTech X-Meridian 7.1 2G sound card. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/Kconfig | 1 + sound/pci/oxygen/oxygen.c | 2 ++ 3 files changed, 4 insertions(+) (limited to 'sound/pci') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 7124340038ea..5cd5c9623127 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1527,6 +1527,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for sound cards based on the C-Media CMI8787/8788 chip: * Asound A-8788 * AuzenTech X-Meridian + * AuzenTech X-Meridian 2G * Bgears b-Enspirer * Club3D Theatron DTS * HT-Omega Claro (plus) diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 7b2678a25ca0..ddb5e6969bb4 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -218,6 +218,7 @@ config SND_OXYGEN C-Media CMI8788 (Oxygen HD Audio) chip: * Asound A-8788 * AuzenTech X-Meridian + * AuzenTech X-Meridian 2G * Bgears b-Enspirer * Club3D Theatron DTS * HT-Omega Claro (plus) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index e187c951b6a0..304f1a5681f3 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -102,6 +102,8 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_2CH_OUTPUT }, /* AuzenTech X-Meridian */ { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, + /* AuzenTech X-Meridian 2G */ + { OXYGEN_PCI_SUBID(0x5431, 0x017a), .driver_data = MODEL_MERIDIAN }, /* HT-Omega Claro */ { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, /* HT-Omega Claro halo */ -- cgit v1.2.3 From 66410bfdf14f7c2ad3b2d4a8adeab41d368b6f05 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:20:29 +0100 Subject: ALSA: oxygen: add Xonar DG support Add experimental support for the Asus Xonar DG sound card. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 3 +- sound/pci/Kconfig | 3 +- sound/pci/oxygen/Makefile | 2 +- sound/pci/oxygen/cs4245.h | 107 +++++ sound/pci/oxygen/oxygen.c | 11 +- sound/pci/oxygen/oxygen_mixer.c | 14 +- sound/pci/oxygen/xonar_dg.c | 593 ++++++++++++++++++++++++ sound/pci/oxygen/xonar_dg.h | 8 + 8 files changed, 735 insertions(+), 6 deletions(-) create mode 100644 sound/pci/oxygen/cs4245.h create mode 100644 sound/pci/oxygen/xonar_dg.c create mode 100644 sound/pci/oxygen/xonar_dg.h (limited to 'sound/pci') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 5cd5c9623127..805ce9124c3f 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1524,8 +1524,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-oxygen ----------------- - Module for sound cards based on the C-Media CMI8787/8788 chip: + Module for sound cards based on the C-Media CMI8786/8787/8788 chip: * Asound A-8788 + * Asus Xonar DG * AuzenTech X-Meridian * AuzenTech X-Meridian 2G * Bgears b-Enspirer diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index ddb5e6969bb4..f0bcf689de24 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -209,7 +209,7 @@ config SND_OXYGEN_LIB tristate config SND_OXYGEN - tristate "C-Media 8787, 8788 (Oxygen)" + tristate "C-Media 8786, 8787, 8788 (Oxygen)" select SND_OXYGEN_LIB select SND_PCM select SND_MPU401_UART @@ -217,6 +217,7 @@ config SND_OXYGEN Say Y here to include support for sound cards based on the C-Media CMI8788 (Oxygen HD Audio) chip: * Asound A-8788 + * Asus Xonar DG * AuzenTech X-Meridian * AuzenTech X-Meridian 2G * Bgears b-Enspirer diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile index bd67c0d7779c..0f8726551fde 100644 --- a/sound/pci/oxygen/Makefile +++ b/sound/pci/oxygen/Makefile @@ -1,5 +1,5 @@ snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o -snd-oxygen-objs := oxygen.o +snd-oxygen-objs := oxygen.o xonar_dg.o snd-virtuoso-objs := virtuoso.o xonar_lib.o \ xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o diff --git a/sound/pci/oxygen/cs4245.h b/sound/pci/oxygen/cs4245.h new file mode 100644 index 000000000000..5e0197e07dd1 --- /dev/null +++ b/sound/pci/oxygen/cs4245.h @@ -0,0 +1,107 @@ +#define CS4245_CHIP_ID 0x01 +#define CS4245_POWER_CTRL 0x02 +#define CS4245_DAC_CTRL_1 0x03 +#define CS4245_ADC_CTRL 0x04 +#define CS4245_MCLK_FREQ 0x05 +#define CS4245_SIGNAL_SEL 0x06 +#define CS4245_PGA_B_CTRL 0x07 +#define CS4245_PGA_A_CTRL 0x08 +#define CS4245_ANALOG_IN 0x09 +#define CS4245_DAC_A_CTRL 0x0a +#define CS4245_DAC_B_CTRL 0x0b +#define CS4245_DAC_CTRL_2 0x0c +#define CS4245_INT_STATUS 0x0d +#define CS4245_INT_MASK 0x0e +#define CS4245_INT_MODE_MSB 0x0f +#define CS4245_INT_MODE_LSB 0x10 + +/* Chip ID */ +#define CS4245_CHIP_PART_MASK 0xf0 +#define CS4245_CHIP_REV_MASK 0x0f + +/* Power Control */ +#define CS4245_FREEZE 0x80 +#define CS4245_PDN_MIC 0x08 +#define CS4245_PDN_ADC 0x04 +#define CS4245_PDN_DAC 0x02 +#define CS4245_PDN 0x01 + +/* DAC Control */ +#define CS4245_DAC_FM_MASK 0xc0 +#define CS4245_DAC_FM_SINGLE 0x00 +#define CS4245_DAC_FM_DOUBLE 0x40 +#define CS4245_DAC_FM_QUAD 0x80 +#define CS4245_DAC_DIF_MASK 0x30 +#define CS4245_DAC_DIF_LJUST 0x00 +#define CS4245_DAC_DIF_I2S 0x10 +#define CS4245_DAC_DIF_RJUST_16 0x20 +#define CS4245_DAC_DIF_RJUST_24 0x30 +#define CS4245_RESERVED_1 0x08 +#define CS4245_MUTE_DAC 0x04 +#define CS4245_DEEMPH 0x02 +#define CS4245_DAC_MASTER 0x01 + +/* ADC Control */ +#define CS4245_ADC_FM_MASK 0xc0 +#define CS4245_ADC_FM_SINGLE 0x00 +#define CS4245_ADC_FM_DOUBLE 0x40 +#define CS4245_ADC_FM_QUAD 0x80 +#define CS4245_ADC_DIF_MASK 0x10 +#define CS4245_ADC_DIF_LJUST 0x00 +#define CS4245_ADC_DIF_I2S 0x10 +#define CS4245_MUTE_ADC 0x04 +#define CS4245_HPF_FREEZE 0x02 +#define CS4245_ADC_MASTER 0x01 + +/* MCLK Frequency */ +#define CS4245_MCLK1_MASK 0x70 +#define CS4245_MCLK1_SHIFT 4 +#define CS4245_MCLK2_MASK 0x07 +#define CS4245_MCLK2_SHIFT 0 +#define CS4245_MCLK_1 0 +#define CS4245_MCLK_1_5 1 +#define CS4245_MCLK_2 2 +#define CS4245_MCLK_3 3 +#define CS4245_MCLK_4 4 + +/* Signal Selection */ +#define CS4245_A_OUT_SEL_MASK 0x60 +#define CS4245_A_OUT_SEL_HIZ 0x00 +#define CS4245_A_OUT_SEL_DAC 0x20 +#define CS4245_A_OUT_SEL_PGA 0x40 +#define CS4245_LOOP 0x02 +#define CS4245_ASYNCH 0x01 + +/* Channel B/A PGA Control */ +#define CS4245_PGA_GAIN_MASK 0x3f + +/* ADC Input Control */ +#define CS4245_PGA_SOFT 0x10 +#define CS4245_PGA_ZERO 0x08 +#define CS4245_SEL_MASK 0x07 +#define CS4245_SEL_MIC 0x00 +#define CS4245_SEL_INPUT_1 0x01 +#define CS4245_SEL_INPUT_2 0x02 +#define CS4245_SEL_INPUT_3 0x03 +#define CS4245_SEL_INPUT_4 0x04 +#define CS4245_SEL_INPUT_5 0x05 +#define CS4245_SEL_INPUT_6 0x06 + +/* DAC Channel A/B Volume Control */ +#define CS4245_VOL_MASK 0xff + +/* DAC Control 2 */ +#define CS4245_DAC_SOFT 0x80 +#define CS4245_DAC_ZERO 0x40 +#define CS4245_INVERT_DAC 0x20 +#define CS4245_INT_ACTIVE_HIGH 0x01 + +/* Interrupt Status/Mask/Mode */ +#define CS4245_ADC_CLK_ERR 0x08 +#define CS4245_DAC_CLK_ERR 0x04 +#define CS4245_ADC_OVFL 0x02 +#define CS4245_ADC_UNDRFL 0x01 + + +#define CS4245_SPI_ADDRESS (0x9e << 16) +#define CS4245_SPI_WRITE (0 << 16) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 304f1a5681f3..b59aeefd14db 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -53,13 +53,16 @@ #include #include #include "oxygen.h" +#include "xonar_dg.h" #include "ak4396.h" #include "wm8785.h" MODULE_AUTHOR("Clemens Ladisch "); MODULE_DESCRIPTION("C-Media CMI8788 driver"); MODULE_LICENSE("GPL v2"); -MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); +MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8786}" + ",{C-Media,CMI8787}" + ",{C-Media,CMI8788}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; @@ -79,6 +82,7 @@ enum { MODEL_CLARO_HALO, MODEL_FANTASIA, MODEL_2CH_OUTPUT, + MODEL_XONAR_DG, }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { @@ -92,6 +96,8 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, + /* Asus Xonar DG */ + { OXYGEN_PCI_SUBID(0x1043, 0x8467), .driver_data = MODEL_XONAR_DG }, /* PCI 2.0 HD Audio */ { OXYGEN_PCI_SUBID(0x13f6, 0x8782), .driver_data = MODEL_2CH_OUTPUT }, /* Kuroutoshikou CMI8787-HG2PCI */ @@ -655,6 +661,9 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.dac_channels_pcm = 2; chip->model.dac_channels_mixer = 2; break; + case MODEL_XONAR_DG: + chip->model = model_xonar_dg; + break; } if (id->driver_data == MODEL_MERIDIAN || id->driver_data == MODEL_CLARO_HALO) { diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 242c1cac69b8..d327c36fbddf 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -97,6 +97,16 @@ static int dac_mute_put(struct snd_kcontrol *ctl, return changed; } +static unsigned int upmix_item_count(struct oxygen *chip) +{ + if (chip->model.dac_channels_pcm < 8) + return 2; + else if (chip->model.update_center_lfe_mix) + return 5; + else + return 3; +} + static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { static const char *const names[5] = { @@ -107,7 +117,7 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) "Front+Surround+Center/LFE+Back", }; struct oxygen *chip = ctl->private_data; - unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; + unsigned int count = upmix_item_count(chip); info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; info->count = 1; @@ -188,7 +198,7 @@ void oxygen_update_dac_routing(struct oxygen *chip) static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; - unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; + unsigned int count = upmix_item_count(chip); int changed; if (value->value.enumerated.item[0] >= count) diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c new file mode 100644 index 000000000000..7ed3284d7d5b --- /dev/null +++ b/sound/pci/oxygen/xonar_dg.c @@ -0,0 +1,593 @@ +/* + * card driver for the Xonar DG + * + * Copyright (c) Clemens Ladisch + * + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this driver; if not, see . + */ + +/* + * Xonar DG + * -------- + * + * CMI8788: + * + * SPI 0 -> CS4245 + * + * GPIO 3 <- ? + * GPIO 4 <- headphone detect + * GPIO 5 -> route input jack to line-in (0) or mic-in (1) + * GPIO 6 -> route input jack to line-in (0) or mic-in (1) + * GPIO 7 -> enable rear headphone amp + * GPIO 8 -> enable output to speakers + * + * CS4245: + * + * input 1 <- aux + * input 2 <- front mic + * input 4 <- line/mic + * aux out -> front panel headphones + */ + +#include +#include +#include +#include +#include +#include +#include "oxygen.h" +#include "xonar_dg.h" +#include "cs4245.h" + +#define GPIO_MAGIC 0x0008 +#define GPIO_HP_DETECT 0x0010 +#define GPIO_INPUT_ROUTE 0x0060 +#define GPIO_HP_REAR 0x0080 +#define GPIO_OUTPUT_ENABLE 0x0100 + +struct dg { + unsigned int output_sel; + s8 input_vol[4][2]; + unsigned int input_sel; + u8 hp_vol_att; + u8 cs4245_regs[0x11]; +}; + +static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value) +{ + struct dg *data = chip->model_data; + + oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | + OXYGEN_SPI_DATA_LENGTH_3 | + OXYGEN_SPI_CLOCK_1280 | + (0 << OXYGEN_SPI_CODEC_SHIFT) | + OXYGEN_SPI_CEN_LATCH_CLOCK_HI, + CS4245_SPI_ADDRESS | + CS4245_SPI_WRITE | + (value << 8) | reg); + data->cs4245_regs[reg] = value; +} + +static void cs4245_write_cached(struct oxygen *chip, unsigned int reg, u8 value) +{ + struct dg *data = chip->model_data; + + if (value != data->cs4245_regs[reg]) + cs4245_write(chip, reg, value); +} + +static void cs4245_registers_init(struct oxygen *chip) +{ + struct dg *data = chip->model_data; + + cs4245_write(chip, CS4245_POWER_CTRL, CS4245_PDN); + cs4245_write(chip, CS4245_DAC_CTRL_1, + data->cs4245_regs[CS4245_DAC_CTRL_1]); + cs4245_write(chip, CS4245_ADC_CTRL, + data->cs4245_regs[CS4245_ADC_CTRL]); + cs4245_write(chip, CS4245_SIGNAL_SEL, + data->cs4245_regs[CS4245_SIGNAL_SEL]); + cs4245_write(chip, CS4245_PGA_B_CTRL, + data->cs4245_regs[CS4245_PGA_B_CTRL]); + cs4245_write(chip, CS4245_PGA_A_CTRL, + data->cs4245_regs[CS4245_PGA_A_CTRL]); + cs4245_write(chip, CS4245_ANALOG_IN, + data->cs4245_regs[CS4245_ANALOG_IN]); + cs4245_write(chip, CS4245_DAC_A_CTRL, + data->cs4245_regs[CS4245_DAC_A_CTRL]); + cs4245_write(chip, CS4245_DAC_B_CTRL, + data->cs4245_regs[CS4245_DAC_B_CTRL]); + cs4245_write(chip, CS4245_DAC_CTRL_2, + CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC); + cs4245_write(chip, CS4245_INT_MASK, 0); + cs4245_write(chip, CS4245_POWER_CTRL, 0); +} + +static void cs4245_init(struct oxygen *chip) +{ + struct dg *data = chip->model_data; + + data->cs4245_regs[CS4245_DAC_CTRL_1] = + CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST; + data->cs4245_regs[CS4245_ADC_CTRL] = + CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST; + data->cs4245_regs[CS4245_SIGNAL_SEL] = + CS4245_A_OUT_SEL_HIZ | CS4245_ASYNCH; + data->cs4245_regs[CS4245_PGA_B_CTRL] = 0; + data->cs4245_regs[CS4245_PGA_A_CTRL] = 0; + data->cs4245_regs[CS4245_ANALOG_IN] = + CS4245_PGA_SOFT | CS4245_PGA_ZERO | CS4245_SEL_INPUT_4; + data->cs4245_regs[CS4245_DAC_A_CTRL] = 0; + data->cs4245_regs[CS4245_DAC_B_CTRL] = 0; + cs4245_registers_init(chip); + snd_component_add(chip->card, "CS4245"); +} + +static void dg_output_enable(struct oxygen *chip) +{ + msleep(2500); + oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); +} + +static void dg_init(struct oxygen *chip) +{ + struct dg *data = chip->model_data; + + data->output_sel = 0; + data->input_sel = 3; + data->hp_vol_att = 2 * 16; + + cs4245_init(chip); + + oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_MAGIC | GPIO_HP_DETECT); + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_INPUT_ROUTE | GPIO_HP_REAR | GPIO_OUTPUT_ENABLE); + oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, + GPIO_INPUT_ROUTE | GPIO_HP_REAR); + dg_output_enable(chip); +} + +static void dg_cleanup(struct oxygen *chip) +{ + oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); +} + +static void dg_suspend(struct oxygen *chip) +{ + dg_cleanup(chip); +} + +static void dg_resume(struct oxygen *chip) +{ + cs4245_registers_init(chip); + dg_output_enable(chip); +} + +static void set_cs4245_dac_params(struct oxygen *chip, + struct snd_pcm_hw_params *params) +{ + struct dg *data = chip->model_data; + u8 value; + + value = data->cs4245_regs[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK; + if (params_rate(params) <= 50000) + value |= CS4245_DAC_FM_SINGLE; + else if (params_rate(params) <= 100000) + value |= CS4245_DAC_FM_DOUBLE; + else + value |= CS4245_DAC_FM_QUAD; + cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value); +} + +static void set_cs4245_adc_params(struct oxygen *chip, + struct snd_pcm_hw_params *params) +{ + struct dg *data = chip->model_data; + u8 value; + + value = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK; + if (params_rate(params) <= 50000) + value |= CS4245_ADC_FM_SINGLE; + else if (params_rate(params) <= 100000) + value |= CS4245_ADC_FM_DOUBLE; + else + value |= CS4245_ADC_FM_QUAD; + cs4245_write_cached(chip, CS4245_ADC_CTRL, value); +} + +static int output_switch_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) +{ + static const char *const names[3] = { + "Speakers", "Headphones", "FP Headphones" + }; + + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = 1; + info->value.enumerated.items = 3; + if (info->value.enumerated.item >= 3) + info->value.enumerated.item = 2; + strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); + return 0; +} + +static int output_switch_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + + mutex_lock(&chip->mutex); + value->value.enumerated.item[0] = data->output_sel; + mutex_unlock(&chip->mutex); + return 0; +} + +static int output_switch_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + u8 reg; + int changed; + + if (value->value.enumerated.item[0] > 2) + return -EINVAL; + + mutex_lock(&chip->mutex); + changed = value->value.enumerated.item[0] != data->output_sel; + if (changed) { + data->output_sel = value->value.enumerated.item[0]; + + reg = data->cs4245_regs[CS4245_SIGNAL_SEL] & + ~CS4245_A_OUT_SEL_MASK; + reg |= data->output_sel == 2 ? + CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ; + cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg); + + cs4245_write_cached(chip, CS4245_DAC_A_CTRL, + data->output_sel ? data->hp_vol_att : 0); + cs4245_write_cached(chip, CS4245_DAC_B_CTRL, + data->output_sel ? data->hp_vol_att : 0); + + oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, + data->output_sel == 1 ? GPIO_HP_REAR : 0, + GPIO_HP_REAR); + } + mutex_unlock(&chip->mutex); + return changed; +} + +static int hp_volume_offset_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) +{ + static const char *const names[3] = { + "< 64 ohms", "64-150 ohms", "150-300 ohms" + }; + + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = 1; + info->value.enumerated.items = 3; + if (info->value.enumerated.item >= 3) + info->value.enumerated.item = 2; + strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); + return 0; +} + +static int hp_volume_offset_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + + mutex_lock(&chip->mutex); + if (data->hp_vol_att > 2 * 7) + value->value.enumerated.item[0] = 0; + else if (data->hp_vol_att > 0) + value->value.enumerated.item[0] = 1; + else + value->value.enumerated.item[0] = 2; + mutex_unlock(&chip->mutex); + return 0; +} + +static int hp_volume_offset_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + static const s8 atts[3] = { 2 * 16, 2 * 7, 0 }; + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + s8 att; + int changed; + + if (value->value.enumerated.item[0] > 2) + return -EINVAL; + att = atts[value->value.enumerated.item[0]]; + mutex_lock(&chip->mutex); + changed = att != data->hp_vol_att; + if (changed) { + data->hp_vol_att = att; + if (data->output_sel) { + cs4245_write_cached(chip, CS4245_DAC_A_CTRL, att); + cs4245_write_cached(chip, CS4245_DAC_B_CTRL, att); + } + } + mutex_unlock(&chip->mutex); + return changed; +} + +static int input_vol_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) +{ + info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + info->count = 2; + info->value.integer.min = 2 * -12; + info->value.integer.max = 2 * 12; + return 0; +} + +static int input_vol_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + unsigned int idx = ctl->private_value; + + mutex_lock(&chip->mutex); + value->value.integer.value[0] = data->input_vol[idx][0]; + value->value.integer.value[1] = data->input_vol[idx][1]; + mutex_unlock(&chip->mutex); + return 0; +} + +static int input_vol_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + unsigned int idx = ctl->private_value; + int changed = 0; + + if (value->value.integer.value[0] < 2 * -12 || + value->value.integer.value[0] > 2 * 12 || + value->value.integer.value[1] < 2 * -12 || + value->value.integer.value[1] > 2 * 12) + return -EINVAL; + mutex_lock(&chip->mutex); + changed = data->input_vol[idx][0] != value->value.integer.value[0] || + data->input_vol[idx][1] != value->value.integer.value[1]; + if (changed) { + data->input_vol[idx][0] = value->value.integer.value[0]; + data->input_vol[idx][1] = value->value.integer.value[1]; + if (idx == data->input_sel) { + cs4245_write_cached(chip, CS4245_PGA_A_CTRL, + data->input_vol[idx][0]); + cs4245_write_cached(chip, CS4245_PGA_B_CTRL, + data->input_vol[idx][1]); + } + } + mutex_unlock(&chip->mutex); + return changed; +} + +static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0); + +static int input_sel_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) +{ + static const char *const names[4] = { + "Mic", "Aux", "Front Mic", "Line" + }; + + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = 1; + info->value.enumerated.items = 4; + info->value.enumerated.item &= 3; + strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); + return 0; +} + +static int input_sel_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + + mutex_lock(&chip->mutex); + value->value.enumerated.item[0] = data->input_sel; + mutex_unlock(&chip->mutex); + return 0; +} + +static int input_sel_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + static const u8 sel_values[4] = { + CS4245_SEL_MIC, + CS4245_SEL_INPUT_1, + CS4245_SEL_INPUT_2, + CS4245_SEL_INPUT_4 + }; + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + int changed; + + if (value->value.enumerated.item[0] > 3) + return -EINVAL; + + mutex_lock(&chip->mutex); + changed = value->value.enumerated.item[0] != data->input_sel; + if (changed) { + data->input_sel = value->value.enumerated.item[0]; + + cs4245_write(chip, CS4245_ANALOG_IN, + (data->cs4245_regs[CS4245_ANALOG_IN] & + ~CS4245_SEL_MASK) | + sel_values[data->input_sel]); + + cs4245_write_cached(chip, CS4245_PGA_A_CTRL, + data->input_vol[data->input_sel][0]); + cs4245_write_cached(chip, CS4245_PGA_B_CTRL, + data->input_vol[data->input_sel][1]); + + oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, + data->input_sel ? 0 : GPIO_INPUT_ROUTE, + GPIO_INPUT_ROUTE); + } + mutex_unlock(&chip->mutex); + return changed; +} + +static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) +{ + static const char *const names[2] = { "Active", "Frozen" }; + + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = 1; + info->value.enumerated.items = 2; + info->value.enumerated.item &= 1; + strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); + return 0; +} + +static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + + value->value.enumerated.item[0] = + !!(data->cs4245_regs[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE); + return 0; +} + +static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct dg *data = chip->model_data; + u8 reg; + int changed; + + mutex_lock(&chip->mutex); + reg = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE; + if (value->value.enumerated.item[0]) + reg |= CS4245_HPF_FREEZE; + changed = reg != data->cs4245_regs[CS4245_ADC_CTRL]; + if (changed) + cs4245_write(chip, CS4245_ADC_CTRL, reg); + mutex_unlock(&chip->mutex); + return changed; +} + +#define INPUT_VOLUME(xname, index) { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .info = input_vol_info, \ + .get = input_vol_get, \ + .put = input_vol_put, \ + .tlv = { .p = cs4245_pga_db_scale }, \ + .private_value = index, \ +} +static const struct snd_kcontrol_new dg_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Analog Output Playback Enum", + .info = output_switch_info, + .get = output_switch_get, + .put = output_switch_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Headphones Impedance Playback Enum", + .info = hp_volume_offset_info, + .get = hp_volume_offset_get, + .put = hp_volume_offset_put, + }, + INPUT_VOLUME("Mic Capture Volume", 0), + INPUT_VOLUME("Aux Capture Volume", 1), + INPUT_VOLUME("Front Mic Capture Volume", 2), + INPUT_VOLUME("Line Capture Volume", 3), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = input_sel_info, + .get = input_sel_get, + .put = input_sel_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "ADC High-pass Filter Capture Enum", + .info = hpf_info, + .get = hpf_get, + .put = hpf_put, + }, +}; + +static int dg_control_filter(struct snd_kcontrol_new *template) +{ + if (!strncmp(template->name, "Master Playback ", 16)) + return 1; + return 0; +} + +static int dg_mixer_init(struct oxygen *chip) +{ + unsigned int i; + int err; + + for (i = 0; i < ARRAY_SIZE(dg_controls); ++i) { + err = snd_ctl_add(chip->card, + snd_ctl_new1(&dg_controls[i], chip)); + if (err < 0) + return err; + } + return 0; +} + +static void dump_cs4245_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct dg *data = chip->model_data; + unsigned int i; + + snd_iprintf(buffer, "\nCS4245:"); + for (i = 1; i <= 0x10; ++i) + snd_iprintf(buffer, " %02x", data->cs4245_regs[i]); + snd_iprintf(buffer, "\n"); +} + +struct oxygen_model model_xonar_dg = { + .shortname = "Xonar DG", + .longname = "C-Media Oxygen HD Audio", + .chip = "CMI8786", + .init = dg_init, + .control_filter = dg_control_filter, + .mixer_init = dg_mixer_init, + .cleanup = dg_cleanup, + .suspend = dg_suspend, + .resume = dg_resume, + .set_dac_params = set_cs4245_dac_params, + .set_adc_params = set_cs4245_adc_params, + .dump_registers = dump_cs4245_registers, + .model_data_size = sizeof(struct dg), + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_1, + .dac_channels_pcm = 6, + .dac_channels_mixer = 0, + .function_flags = OXYGEN_FUNCTION_SPI, + .dac_mclks = OXYGEN_MCLKS(256, 128, 128), + .adc_mclks = OXYGEN_MCLKS(256, 128, 128), + .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, +}; diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h new file mode 100644 index 000000000000..5688d78609a9 --- /dev/null +++ b/sound/pci/oxygen/xonar_dg.h @@ -0,0 +1,8 @@ +#ifndef XONAR_DG_H_INCLUDED +#define XONAR_DG_H_INCLUDED + +#include "oxygen.h" + +extern struct oxygen_model model_xonar_dg; + +#endif -- cgit v1.2.3 From b532d6b8d3aa163e1dc143bc729e9ee92f75baf5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:23:57 +0100 Subject: ALSA: virtuoso: add Xonar HDAV1.3 Slim support Add experimental support for the Asus Xonar HDAV1.3 Slim sound card. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 6 +- sound/pci/Kconfig | 4 +- sound/pci/oxygen/xonar_hdmi.c | 2 +- sound/pci/oxygen/xonar_pcm179x.c | 3 - sound/pci/oxygen/xonar_wm87x6.c | 213 ++++++++++++++++++++++-- 5 files changed, 209 insertions(+), 19 deletions(-) (limited to 'sound/pci') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 805ce9124c3f..3c1eddd9fcc7 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -2004,9 +2004,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-virtuoso ------------------- - Module for sound cards based on the Asus AV100/AV200 chips, - i.e., Xonar D1, DX, D2, D2X, DS, HDAV1.3 (Deluxe), Essence ST - (Deluxe) and Essence STX. + Module for sound cards based on the Asus AV66/AV100/AV200 chips, + i.e., Xonar D1, DX, D2, D2X, DS, Essence ST (Deluxe), Essence STX, + HDAV1.3 (Deluxe), and HDAV1.3 Slim. This module supports autoprobe and multiple cards. diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index f0bcf689de24..9823d59d7ad7 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -819,8 +819,8 @@ config SND_VIRTUOSO Say Y here to include support for sound cards based on the Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, Essence ST (Deluxe), and Essence STX. - Support for the HDAV1.3 (Deluxe) is experimental; for the - HDAV1.3 Slim and Xense, missing. + Support for the HDAV1.3 (Deluxe) and HDAV1.3 Slim is experimental; + for the Xense, missing. To compile this driver as a module, choose M here: the module will be called snd-virtuoso. diff --git a/sound/pci/oxygen/xonar_hdmi.c b/sound/pci/oxygen/xonar_hdmi.c index b12db1f1cea9..136dac6a3964 100644 --- a/sound/pci/oxygen/xonar_hdmi.c +++ b/sound/pci/oxygen/xonar_hdmi.c @@ -1,5 +1,5 @@ /* - * helper functions for HDMI models (Xonar HDAV1.3) + * helper functions for HDMI models (Xonar HDAV1.3/HDAV1.3 Slim) * * Copyright (c) Clemens Ladisch * diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 003c4800400b..bf4fd4bb1359 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -1152,9 +1152,6 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip, chip->model.resume = xonar_stx_resume; chip->model.set_dac_params = set_pcm1796_params; break; - case 0x835e: - snd_printk(KERN_ERR "the HDAV1.3 Slim is not supported\n"); - return -ENODEV; default: return -EINVAL; } diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 4f9657084603..ad48356c54e4 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -1,5 +1,5 @@ /* - * card driver for models with WM8776/WM8766 DACs (Xonar DS) + * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim) * * Copyright (c) Clemens Ladisch * @@ -77,6 +77,13 @@ #define GPIO_DS_OUTPUT_FRONTLR 0x0080 #define GPIO_DS_OUTPUT_ENABLE 0x0100 +#define GPIO_SLIM_HDMI_DISABLE 0x0001 +#define GPIO_SLIM_OUTPUT_ENABLE 0x0002 +#define GPIO_SLIM_FIRMWARE_CLK 0x0040 +#define GPIO_SLIM_FIRMWARE_DATA 0x0080 + +#define I2C_DEVICE_WM8776 0x34 /* 001101, 0, /W=0 */ + #define LC_CONTROL_LIMITER 0x40000000 #define LC_CONTROL_ALC 0x20000000 @@ -88,19 +95,37 @@ struct xonar_wm87x6 { struct snd_kcontrol *mic_adcmux_control; struct snd_kcontrol *lc_controls[13]; struct snd_jack *hp_jack; + struct xonar_hdmi hdmi; }; -static void wm8776_write(struct oxygen *chip, - unsigned int reg, unsigned int value) +static void wm8776_write_spi(struct oxygen *chip, + unsigned int reg, unsigned int value) { - struct xonar_wm87x6 *data = chip->model_data; - oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | OXYGEN_SPI_DATA_LENGTH_2 | OXYGEN_SPI_CLOCK_160 | (1 << OXYGEN_SPI_CODEC_SHIFT) | OXYGEN_SPI_CEN_LATCH_CLOCK_LO, (reg << 9) | value); +} + +static void wm8776_write_i2c(struct oxygen *chip, + unsigned int reg, unsigned int value) +{ + oxygen_write_i2c(chip, I2C_DEVICE_WM8776, + (reg << 1) | (value >> 8), value); +} + +static void wm8776_write(struct oxygen *chip, + unsigned int reg, unsigned int value) +{ + struct xonar_wm87x6 *data = chip->model_data; + + if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) == + OXYGEN_FUNCTION_SPI) + wm8776_write_spi(chip, reg, value); + else + wm8776_write_i2c(chip, reg, value); if (reg < ARRAY_SIZE(data->wm8776_regs)) { if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) value &= ~WM8776_UPDATE; @@ -267,17 +292,50 @@ static void xonar_ds_init(struct oxygen *chip) snd_component_add(chip->card, "WM8766"); } +static void xonar_hdav_slim_init(struct oxygen *chip) +{ + struct xonar_wm87x6 *data = chip->model_data; + + data->generic.anti_pop_delay = 300; + data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE; + + wm8776_init(chip); + + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_SLIM_HDMI_DISABLE | + GPIO_SLIM_FIRMWARE_CLK | + GPIO_SLIM_FIRMWARE_DATA); + + xonar_hdmi_init(chip, &data->hdmi); + xonar_enable_output(chip); + + snd_component_add(chip->card, "WM8776"); +} + static void xonar_ds_cleanup(struct oxygen *chip) { xonar_disable_output(chip); wm8776_write(chip, WM8776_RESET, 0); } +static void xonar_hdav_slim_cleanup(struct oxygen *chip) +{ + xonar_hdmi_cleanup(chip); + xonar_disable_output(chip); + wm8776_write(chip, WM8776_RESET, 0); + msleep(2); +} + static void xonar_ds_suspend(struct oxygen *chip) { xonar_ds_cleanup(chip); } +static void xonar_hdav_slim_suspend(struct oxygen *chip) +{ + xonar_hdav_slim_cleanup(chip); +} + static void xonar_ds_resume(struct oxygen *chip) { wm8776_registers_init(chip); @@ -286,6 +344,15 @@ static void xonar_ds_resume(struct oxygen *chip) xonar_ds_handle_hp_jack(chip); } +static void xonar_hdav_slim_resume(struct oxygen *chip) +{ + struct xonar_wm87x6 *data = chip->model_data; + + wm8776_registers_init(chip); + xonar_hdmi_resume(chip, &data->hdmi); + xonar_enable_output(chip); +} + static void wm8776_adc_hardware_filter(unsigned int channel, struct snd_pcm_hardware *hardware) { @@ -300,6 +367,13 @@ static void wm8776_adc_hardware_filter(unsigned int channel, } } +static void xonar_hdav_slim_hardware_filter(unsigned int channel, + struct snd_pcm_hardware *hardware) +{ + wm8776_adc_hardware_filter(channel, hardware); + xonar_hdmi_pcm_hardware_filter(channel, hardware); +} + static void set_wm87x6_dac_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -316,6 +390,14 @@ static void set_wm8776_adc_params(struct oxygen *chip, wm8776_write_cached(chip, WM8776_MSTRCTRL, reg); } +static void set_hdav_slim_dac_params(struct oxygen *chip, + struct snd_pcm_hw_params *params) +{ + struct xonar_wm87x6 *data = chip->model_data; + + xonar_set_hdmi_params(chip, &data->hdmi, params); +} + static void update_wm8776_volume(struct oxygen *chip) { struct xonar_wm87x6 *data = chip->model_data; @@ -1007,6 +1089,53 @@ static const struct snd_kcontrol_new ds_controls[] = { .private_value = 0, }, }; +static const struct snd_kcontrol_new hdav_slim_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "HDMI Playback Switch", + .info = snd_ctl_boolean_mono_info, + .get = xonar_gpio_bit_switch_get, + .put = xonar_gpio_bit_switch_put, + .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Headphone Playback Volume", + .info = wm8776_hp_vol_info, + .get = wm8776_hp_vol_get, + .put = wm8776_hp_vol_put, + .tlv = { .p = wm8776_hp_db_scale }, + }, + WM8776_BIT_SWITCH("Headphone Playback Switch", + WM8776_PWRDOWN, WM8776_HPPD, 1, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input Capture Volume", + .info = wm8776_input_vol_info, + .get = wm8776_input_vol_get, + .put = wm8776_input_vol_put, + .tlv = { .p = wm8776_adc_db_scale }, + }, + WM8776_BIT_SWITCH("Mic Capture Switch", + WM8776_ADCMUX, 1 << 0, 0, 0), + WM8776_BIT_SWITCH("Aux Capture Switch", + WM8776_ADCMUX, 1 << 1, 0, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "ADC Filter Capture Enum", + .info = hpf_info, + .get = hpf_get, + .put = hpf_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Level Control Capture Enum", + .info = wm8776_level_control_info, + .get = wm8776_level_control_get, + .put = wm8776_level_control_put, + .private_value = 0, + }, +}; static const struct snd_kcontrol_new lc_controls[] = { WM8776_FIELD_CTL_VOLUME("Limiter Threshold", WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, @@ -1050,6 +1179,26 @@ static const struct snd_kcontrol_new lc_controls[] = { LC_CONTROL_ALC, wm8776_ngth_db_scale), }; +static int add_lc_controls(struct oxygen *chip) +{ + struct xonar_wm87x6 *data = chip->model_data; + unsigned int i; + struct snd_kcontrol *ctl; + int err; + + BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); + for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { + ctl = snd_ctl_new1(&lc_controls[i], chip); + if (!ctl) + return -ENOMEM; + err = snd_ctl_add(chip->card, ctl); + if (err < 0) + return err; + data->lc_controls[i] = ctl; + } + return 0; +} + static int xonar_ds_mixer_init(struct oxygen *chip) { struct xonar_wm87x6 *data = chip->model_data; @@ -1071,17 +1220,26 @@ static int xonar_ds_mixer_init(struct oxygen *chip) } if (!data->line_adcmux_control || !data->mic_adcmux_control) return -ENXIO; - BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); - for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { - ctl = snd_ctl_new1(&lc_controls[i], chip); + + return add_lc_controls(chip); +} + +static int xonar_hdav_slim_mixer_init(struct oxygen *chip) +{ + unsigned int i; + struct snd_kcontrol *ctl; + int err; + + for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) { + ctl = snd_ctl_new1(&hdav_slim_controls[i], chip); if (!ctl) return -ENOMEM; err = snd_ctl_add(chip->card, ctl); if (err < 0) return err; - data->lc_controls[i] = ctl; } - return 0; + + return add_lc_controls(chip); } static void dump_wm8776_registers(struct oxygen *chip, @@ -1145,6 +1303,38 @@ static const struct oxygen_model model_xonar_ds = { .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; +static const struct oxygen_model model_xonar_hdav_slim = { + .shortname = "Xonar HDAV1.3 Slim", + .longname = "Asus Virtuoso 200", + .chip = "AV200", + .init = xonar_hdav_slim_init, + .mixer_init = xonar_hdav_slim_mixer_init, + .cleanup = xonar_hdav_slim_cleanup, + .suspend = xonar_hdav_slim_suspend, + .resume = xonar_hdav_slim_resume, + .pcm_hardware_filter = xonar_hdav_slim_hardware_filter, + .set_dac_params = set_hdav_slim_dac_params, + .set_adc_params = set_wm8776_adc_params, + .update_dac_volume = update_wm8776_volume, + .update_dac_mute = update_wm8776_mute, + .uart_input = xonar_hdmi_uart_input, + .dump_registers = dump_wm8776_registers, + .dac_tlv = wm87x6_dac_db_scale, + .model_data_size = sizeof(struct xonar_wm87x6), + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_1, + .dac_channels_pcm = 8, + .dac_channels_mixer = 2, + .dac_volume_min = 255 - 2*60, + .dac_volume_max = 255, + .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_mclks = OXYGEN_MCLKS(256, 256, 128), + .adc_mclks = OXYGEN_MCLKS(256, 256, 128), + .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, +}; + int __devinit get_xonar_wm87x6_model(struct oxygen *chip, const struct pci_device_id *id) { @@ -1152,6 +1342,9 @@ int __devinit get_xonar_wm87x6_model(struct oxygen *chip, case 0x838e: chip->model = model_xonar_ds; break; + case 0x835e: + chip->model = model_xonar_hdav_slim; + break; default: return -EINVAL; } -- cgit v1.2.3 From 9600732b6caba595f34acf2abd930098ec9a0b2b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:25:44 +0100 Subject: ALSA: core, oxygen, virtuoso: add an enum control info helper Introduce the helper function snd_ctl_enum_info() to fill out the elem_info fields for an enumerated control. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- include/sound/control.h | 4 +++- sound/core/control.c | 28 +++++++++++++++++++++++++++- sound/pci/oxygen/oxygen.c | 16 ++-------------- sound/pci/oxygen/oxygen_mixer.c | 15 ++------------- sound/pci/oxygen/xonar_cs43xx.c | 8 +------- sound/pci/oxygen/xonar_dg.c | 30 ++++-------------------------- sound/pci/oxygen/xonar_pcm179x.c | 24 +++--------------------- sound/pci/oxygen/xonar_wm87x6.c | 25 ++++--------------------- 8 files changed, 46 insertions(+), 104 deletions(-) (limited to 'sound/pci') diff --git a/include/sound/control.h b/include/sound/control.h index 112374dc0c58..7715e6f00d38 100644 --- a/include/sound/control.h +++ b/include/sound/control.h @@ -160,12 +160,14 @@ static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id } /* - * Frequently used control callbacks + * Frequently used control callbacks/helpers */ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); +int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, + unsigned int items, const char *const names[]); /* * virtual master control diff --git a/sound/core/control.c b/sound/core/control.c index 45a818002d99..9ce00ed20fba 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1488,7 +1488,7 @@ int snd_ctl_create(struct snd_card *card) } /* - * Frequently used control callbacks + * Frequently used control callbacks/helpers */ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -1513,3 +1513,29 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); + +/** + * snd_ctl_enum_info - fills the info structure for an enumerated control + * @info: the structure to be filled + * @channels: the number of the control's channels; often one + * @items: the number of control values; also the size of @names + * @names: an array containing the names of all control values + * + * Sets all required fields in @info to their appropriate values. + * If the control's accessibility is not the default (readable and writable), + * the caller has to fill @info->access. + */ +int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, + unsigned int items, const char *const names[]) +{ + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = channels; + info->value.enumerated.items = items; + if (info->value.enumerated.item >= items) + info->value.enumerated.item = items - 1; + strlcpy(info->value.enumerated.name, + names[info->value.enumerated.item], + sizeof(info->value.enumerated.name)); + return 0; +} +EXPORT_SYMBOL(snd_ctl_enum_info); diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index b59aeefd14db..45427d85045e 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -415,13 +415,7 @@ static int rolloff_info(struct snd_kcontrol *ctl, "Sharp Roll-off", "Slow Roll-off" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - if (info->value.enumerated.item >= 2) - info->value.enumerated.item = 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 2, names); } static int rolloff_get(struct snd_kcontrol *ctl, @@ -473,13 +467,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) "None", "High-pass Filter" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - if (info->value.enumerated.item >= 2) - info->value.enumerated.item = 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 2, names); } static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index d327c36fbddf..821df1c9d1d0 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -119,13 +119,7 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) struct oxygen *chip = ctl->private_data; unsigned int count = upmix_item_count(chip); - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = count; - if (info->value.enumerated.item >= count) - info->value.enumerated.item = count - 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, count, names); } static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) @@ -659,12 +653,7 @@ static int mic_fmic_source_info(struct snd_kcontrol *ctl, { static const char *const names[] = { "Mic Jack", "Front Panel" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - info->value.enumerated.item &= 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 2, names); } static int mic_fmic_source_get(struct snd_kcontrol *ctl, diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 55c52c7e19b2..9f72d424969c 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -298,13 +298,7 @@ static int rolloff_info(struct snd_kcontrol *ctl, "Fast Roll-off", "Slow Roll-off" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - if (info->value.enumerated.item >= 2) - info->value.enumerated.item = 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 2, names); } static int rolloff_get(struct snd_kcontrol *ctl, diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c index 7ed3284d7d5b..cc610ac1fc19 100644 --- a/sound/pci/oxygen/xonar_dg.c +++ b/sound/pci/oxygen/xonar_dg.c @@ -213,13 +213,7 @@ static int output_switch_info(struct snd_kcontrol *ctl, "Speakers", "Headphones", "FP Headphones" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item >= 3) - info->value.enumerated.item = 2; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 3, names); } static int output_switch_get(struct snd_kcontrol *ctl, @@ -276,13 +270,7 @@ static int hp_volume_offset_info(struct snd_kcontrol *ctl, "< 64 ohms", "64-150 ohms", "150-300 ohms" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item >= 3) - info->value.enumerated.item = 2; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 3, names); } static int hp_volume_offset_get(struct snd_kcontrol *ctl, @@ -390,12 +378,7 @@ static int input_sel_info(struct snd_kcontrol *ctl, "Mic", "Aux", "Front Mic", "Line" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 4; - info->value.enumerated.item &= 3; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 4, names); } static int input_sel_get(struct snd_kcontrol *ctl, @@ -453,12 +436,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { static const char *const names[2] = { "Active", "Frozen" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - info->value.enumerated.item &= 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 2, names); } static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index bf4fd4bb1359..54cad38ec30a 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -678,13 +678,7 @@ static int rolloff_info(struct snd_kcontrol *ctl, "Sharp Roll-off", "Slow Roll-off" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - if (info->value.enumerated.item >= 2) - info->value.enumerated.item = 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 2, names); } static int rolloff_get(struct snd_kcontrol *ctl, @@ -748,13 +742,7 @@ static int st_output_switch_info(struct snd_kcontrol *ctl, "Speakers", "Headphones", "FP Headphones" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item >= 3) - info->value.enumerated.item = 2; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 3, names); } static int st_output_switch_get(struct snd_kcontrol *ctl, @@ -809,13 +797,7 @@ static int st_hp_volume_offset_info(struct snd_kcontrol *ctl, "< 64 ohms", "64-300 ohms", "300-600 ohms" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item > 2) - info->value.enumerated.item = 2; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 3, names); } static int st_hp_volume_offset_get(struct snd_kcontrol *ctl, diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index ad48356c54e4..42d1ab136217 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -577,11 +577,6 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl, const char *const *names; max = (ctl->private_value >> 12) & 0xf; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = max + 1; - if (info->value.enumerated.item > max) - info->value.enumerated.item = max; switch ((ctl->private_value >> 24) & 0x1f) { case WM8776_ALCCTRL2: names = hld; @@ -605,8 +600,7 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl, default: return -ENXIO; } - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, max + 1, names); } static int wm8776_field_volume_info(struct snd_kcontrol *ctl, @@ -863,13 +857,8 @@ static int wm8776_level_control_info(struct snd_kcontrol *ctl, static const char *const names[3] = { "None", "Peak Limiter", "Automatic Level Control" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item >= 3) - info->value.enumerated.item = 2; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + + return snd_ctl_enum_info(info, 1, 3, names); } static int wm8776_level_control_get(struct snd_kcontrol *ctl, @@ -955,13 +944,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) "None", "High-pass Filter" }; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 2; - if (info->value.enumerated.item >= 2) - info->value.enumerated.item = 1; - strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 2, names); } static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) -- cgit v1.2.3 From dd1224aa3ebfdef6cddcfb68ddcd0e682eaf9f84 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:27:26 +0100 Subject: ALSA: bt87x: use enum control info helper Simplify the info callback by using the snd_ctl_enum_info() helper function. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/bt87x.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 37e1b5df5ab8..2958a05b5293 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -637,15 +637,9 @@ static struct snd_kcontrol_new snd_bt87x_capture_boost = { static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info) { - static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"}; + static const char *const texts[3] = {"TV Tuner", "FM", "Mic/Line"}; - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item > 2) - info->value.enumerated.item = 2; - strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]); - return 0; + return snd_ctl_enum_info(info, 1, 3, texts); } static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol, -- cgit v1.2.3 From 60c4ce4a0c2ffbd37d6604f68fa4408ca7226157 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:28:19 +0100 Subject: ALSA: cmipci: use enum control info helper Simplify info callbacks by using the snd_ctl_enum_info() helper function. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/cmipci.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 329968edca9b..b5bb036ef73c 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2507,14 +2507,12 @@ static int snd_cmipci_line_in_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct cmipci *cm = snd_kcontrol_chip(kcontrol); - static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = cm->chip_version >= 39 ? 3 : 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + static const char *const texts[3] = { + "Line-In", "Rear Output", "Bass Output" + }; + + return snd_ctl_enum_info(uinfo, 1, + cm->chip_version >= 39 ? 3 : 2, texts); } static inline unsigned int get_line_in_mode(struct cmipci *cm) @@ -2564,14 +2562,9 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol, static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2] = { "Mic-In", "Center/LFE Output" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + static const char *const texts[2] = { "Mic-In", "Center/LFE Output" }; + + return snd_ctl_enum_info(uinfo, 1, 2, texts); } static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol, -- cgit v1.2.3 From bed6896d0be1de12eb6237a43a4beaaf7dcfb42c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:29:06 +0100 Subject: ALSA: ymfpci: use enum control info helper Simplify the info callback by using the snd_ctl_enum_info() helper function. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/ymfpci/ymfpci_main.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 5518371db13f..c94c051ad0c8 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1389,15 +1389,9 @@ static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata = static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info) { - static char *texts[3] = {"AC'97", "IEC958", "ZV Port"}; - - info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - info->count = 1; - info->value.enumerated.items = 3; - if (info->value.enumerated.item > 2) - info->value.enumerated.item = 2; - strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]); - return 0; + static const char *const texts[3] = {"AC'97", "IEC958", "ZV Port"}; + + return snd_ctl_enum_info(info, 1, 3, texts); } static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) -- cgit v1.2.3 From 860cffd57acff68e8bc5465f4dd3b7d338fb8e62 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:34:15 +0100 Subject: ALSA: oxygen: add digital input validity check switch Add a mixer control to prevent capturing S/PDIF samples that are not marked as valid (non-audio or corrupted samples). Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_mixer.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 821df1c9d1d0..9bff14d5895d 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -434,30 +434,31 @@ static int spdif_input_default_get(struct snd_kcontrol *ctl, return 0; } -static int spdif_loopback_get(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) +static int spdif_bit_switch_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; + u32 bit = ctl->private_value; value->value.integer.value[0] = - !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) - & OXYGEN_SPDIF_LOOPBACK); + !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit); return 0; } -static int spdif_loopback_put(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) +static int spdif_bit_switch_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; + u32 bit = ctl->private_value; u32 oldreg, newreg; int changed; spin_lock_irq(&chip->reg_lock); oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); if (value->value.integer.value[0]) - newreg = oldreg | OXYGEN_SPDIF_LOOPBACK; + newreg = oldreg | bit; else - newreg = oldreg & ~OXYGEN_SPDIF_LOOPBACK; + newreg = oldreg & ~bit; changed = newreg != oldreg; if (changed) oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg); @@ -835,8 +836,17 @@ static const struct snd_kcontrol_new spdif_input_controls[] = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH), .info = snd_ctl_boolean_mono_info, - .get = spdif_loopback_get, - .put = spdif_loopback_put, + .get = spdif_bit_switch_get, + .put = spdif_bit_switch_put, + .private_value = OXYGEN_SPDIF_LOOPBACK, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH), + .info = snd_ctl_boolean_mono_info, + .get = spdif_bit_switch_get, + .put = spdif_bit_switch_put, + .private_value = OXYGEN_SPDIF_SPDVALID, }, }; -- cgit v1.2.3 From 64878dfbf755446f025965b742e56e4739a33b37 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:35:38 +0100 Subject: ALSA: oxygen: X-Meridian: add S/PDIF source selection Add a mixer control to select between the on-board and extension board S/PDIF inputs for the X-Meridian (2G). Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 45427d85045e..22cbf3e67ac4 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -28,7 +28,13 @@ * * GPIO 0 -> DFS0 of AK5385 * GPIO 1 -> DFS1 of AK5385 - * GPIO 8 -> enable headphone amplifier on HT-Omega models + * + * X-Meridian models: + * GPIO 4 -> enable extension S/PDIF input + * GPIO 6 -> enable on-board S/PDIF input + * + * Claro models: + * GPIO 8 -> enable headphone amplifier * * CM9780: * @@ -124,6 +130,10 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); #define GPIO_AK5385_DFS_DOUBLE 0x0001 #define GPIO_AK5385_DFS_QUAD 0x0002 +#define GPIO_MERIDIAN_DIG_MASK 0x0050 +#define GPIO_MERIDIAN_DIG_EXT 0x0010 +#define GPIO_MERIDIAN_DIG_BOARD 0x0040 + #define GPIO_CLARO_HP 0x0100 struct generic_data { @@ -238,6 +248,10 @@ static void generic_init(struct oxygen *chip) static void meridian_init(struct oxygen *chip) { + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_MERIDIAN_DIG_MASK); + oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, + GPIO_MERIDIAN_DIG_BOARD, GPIO_MERIDIAN_DIG_MASK); ak4396_init(chip); ak5385_init(chip); } @@ -506,6 +520,51 @@ static const struct snd_kcontrol_new hpf_control = { .put = hpf_put, }; +static int meridian_dig_source_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) +{ + static const char *const names[2] = { "On-board", "Extension" }; + + return snd_ctl_enum_info(info, 1, 2, names); +} + +static int meridian_dig_source_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + + value->value.enumerated.item[0] = + !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & + GPIO_MERIDIAN_DIG_EXT); + return 0; +} + +static int meridian_dig_source_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + u16 old_reg, new_reg; + int changed; + + mutex_lock(&chip->mutex); + old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA); + new_reg = old_reg & ~GPIO_MERIDIAN_DIG_MASK; + if (value->value.enumerated.item[0] == 0) + new_reg |= GPIO_MERIDIAN_DIG_BOARD; + else + new_reg |= GPIO_MERIDIAN_DIG_EXT; + changed = new_reg != old_reg; + if (changed) + oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg); + mutex_unlock(&chip->mutex); + return changed; +} + +static const struct snd_kcontrol_new meridian_dig_source_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "IEC958 Source Capture Enum", + .info = meridian_dig_source_info, + .get = meridian_dig_source_get, + .put = meridian_dig_source_put, +}; + static int generic_mixer_init(struct oxygen *chip) { return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); @@ -524,6 +583,20 @@ static int generic_wm8785_mixer_init(struct oxygen *chip) return 0; } +static int meridian_mixer_init(struct oxygen *chip) +{ + int err; + + err = generic_mixer_init(chip); + if (err < 0) + return err; + err = snd_ctl_add(chip->card, + snd_ctl_new1(&meridian_dig_source_control, chip)); + if (err < 0) + return err; + return 0; +} + static void dump_ak4396_registers(struct oxygen *chip, struct snd_info_buffer *buffer) { @@ -600,7 +673,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, switch (id->driver_data) { case MODEL_MERIDIAN: chip->model.init = meridian_init; - chip->model.mixer_init = generic_mixer_init; + chip->model.mixer_init = meridian_mixer_init; chip->model.resume = meridian_resume; chip->model.set_adc_params = set_ak5385_params; chip->model.dump_registers = dump_ak4396_registers; -- cgit v1.2.3 From a1f80fcfd51c81960bb32601d9aa0acda9d62504 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:36:23 +0100 Subject: ALSA: oxygen: do not show chip revision in card longname Apparently, the revision is 2 on all sold sound cards, so this information is not actually useful. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.h | 1 - sound/pci/oxygen/oxygen_lib.c | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 2c5fb9edcb11..c2ae63d17cd2 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -129,7 +129,6 @@ struct oxygen { u8 pcm_running; u8 dac_routing; u8 spdif_playback_enable; - u8 revision; u8 has_ac97_0; u8 has_ac97_1; u32 spdif_bits; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 77e1f0805633..70b739816fcc 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -372,12 +372,7 @@ static void oxygen_init(struct oxygen *chip) (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT); chip->spdif_pcm_bits = chip->spdif_bits; - if (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2) - chip->revision = 2; - else - chip->revision = 1; - - if (chip->revision == 1) + if (!(oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2)) oxygen_set_bits8(chip, OXYGEN_MISC, OXYGEN_MISC_PCI_MEM_W_1_CLOCK); @@ -669,8 +664,8 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, strcpy(card->driver, chip->model.chip); strcpy(card->shortname, chip->model.shortname); - sprintf(card->longname, "%s (rev %u) at %#lx, irq %i", - chip->model.longname, chip->revision, chip->addr, chip->irq); + sprintf(card->longname, "%s at %#lx, irq %i", + chip->model.longname, chip->addr, chip->irq); strcpy(card->mixername, chip->model.chip); snd_component_add(card, chip->model.chip); -- cgit v1.2.3 From a4b1696916abc4a0b6b11fc4cc2cd52421a0c7ac Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 10 Jan 2011 16:37:19 +0100 Subject: ALSA: oxygen: add some card names Instead of the generic Oxygen, use the actual card name, if known. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 22cbf3e67ac4..be264d33f9b5 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -84,10 +84,13 @@ MODULE_PARM_DESC(enable, "enable card"); enum { MODEL_CMEDIA_REF, MODEL_MERIDIAN, + MODEL_MERIDIAN_2G, MODEL_CLARO, MODEL_CLARO_HALO, MODEL_FANTASIA, + MODEL_SERENADE, MODEL_2CH_OUTPUT, + MODEL_HG2PCI, MODEL_XONAR_DG, }; @@ -107,15 +110,15 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { /* PCI 2.0 HD Audio */ { OXYGEN_PCI_SUBID(0x13f6, 0x8782), .driver_data = MODEL_2CH_OUTPUT }, /* Kuroutoshikou CMI8787-HG2PCI */ - { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_2CH_OUTPUT }, + { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, /* TempoTec HiFier Fantasia */ { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA }, /* TempoTec HiFier Serenade */ - { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_2CH_OUTPUT }, + { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_SERENADE }, /* AuzenTech X-Meridian */ { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, /* AuzenTech X-Meridian 2G */ - { OXYGEN_PCI_SUBID(0x5431, 0x017a), .driver_data = MODEL_MERIDIAN }, + { OXYGEN_PCI_SUBID(0x5431, 0x017a), .driver_data = MODEL_MERIDIAN_2G }, /* HT-Omega Claro */ { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, /* HT-Omega Claro halo */ @@ -669,9 +672,20 @@ static const struct oxygen_model model_generic = { static int __devinit get_oxygen_model(struct oxygen *chip, const struct pci_device_id *id) { + static const char *const names[] = { + [MODEL_MERIDIAN] = "AuzenTech X-Meridian", + [MODEL_MERIDIAN_2G] = "AuzenTech X-Meridian 2G", + [MODEL_CLARO] = "HT-Omega Claro", + [MODEL_CLARO_HALO] = "HT-Omega Claro halo", + [MODEL_FANTASIA] = "TempoTec HiFier Fantasia", + [MODEL_SERENADE] = "TempoTec HiFier Serenade", + [MODEL_HG2PCI] = "CMI8787-HG2PCI", + }; + chip->model = model_generic; switch (id->driver_data) { case MODEL_MERIDIAN: + case MODEL_MERIDIAN_2G: chip->model.init = meridian_init; chip->model.mixer_init = meridian_mixer_init; chip->model.resume = meridian_resume; @@ -702,7 +716,9 @@ static int __devinit get_oxygen_model(struct oxygen *chip, CAPTURE_1_FROM_SPDIF; break; case MODEL_FANTASIA: + case MODEL_SERENADE: case MODEL_2CH_OUTPUT: + case MODEL_HG2PCI: chip->model.shortname = "C-Media CMI8787"; chip->model.chip = "CMI8787"; if (id->driver_data == MODEL_FANTASIA) @@ -731,6 +747,8 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.misc_flags = OXYGEN_MISC_MIDI; chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; } + if (id->driver_data < ARRAY_SIZE(names) && names[id->driver_data]) + chip->model.shortname = names[id->driver_data]; return 0; } -- cgit v1.2.3 From e92d457514c957f293c4706a06a25833061d9b88 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 11 Jan 2011 13:20:30 +1100 Subject: ALSA: include delay.h for msleep in Xonar DG support Signed-off-by: Stephen Rothwell Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_dg.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c index cc610ac1fc19..dd45cf4d9eb9 100644 --- a/sound/pci/oxygen/xonar_dg.c +++ b/sound/pci/oxygen/xonar_dg.c @@ -40,6 +40,7 @@ */ #include +#include #include #include #include -- cgit v1.2.3 From 5fc51524746430179c676297fd48aaab28e1b85f Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 11 Jan 2011 10:33:40 +0100 Subject: ALSA: oxygen: fix CD/MIDI for X-Meridian (2G) Enable the X-Meridian's CD input and the X-Meridian 2G's potential MIDI ports. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index be264d33f9b5..db39cfc3b4f3 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -695,6 +695,8 @@ static int __devinit get_oxygen_model(struct oxygen *chip, PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; + if (id->driver_data == MODEL_MERIDIAN) + chip->model.device_config |= AC97_CD_INPUT; break; case MODEL_CLARO: chip->model.init = claro_init; @@ -743,6 +745,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, break; } if (id->driver_data == MODEL_MERIDIAN || + id->driver_data == MODEL_MERIDIAN_2G || id->driver_data == MODEL_CLARO_HALO) { chip->model.misc_flags = OXYGEN_MISC_MIDI; chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; -- cgit v1.2.3 From d1d7093f3f639e693fa763eb51d8d9c349bfd606 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 11 Jan 2011 10:35:29 +0100 Subject: ALSA: oxygen: add S/PDIF source selection for Claro cards Add a mixer control to switch between the optical and coaxial S/PDIF inputs on the HT-Omega Claro and Claro halo cards. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 92 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index db39cfc3b4f3..d7e8ddd9a67b 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -34,6 +34,7 @@ * GPIO 6 -> enable on-board S/PDIF input * * Claro models: + * GPIO 6 -> S/PDIF from optical (0) or coaxial (1) input * GPIO 8 -> enable headphone amplifier * * CM9780: @@ -137,6 +138,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); #define GPIO_MERIDIAN_DIG_EXT 0x0010 #define GPIO_MERIDIAN_DIG_BOARD 0x0040 +#define GPIO_CLARO_DIG_COAX 0x0040 #define GPIO_CLARO_HP 0x0100 struct generic_data { @@ -268,6 +270,8 @@ static void claro_enable_hp(struct oxygen *chip) static void claro_init(struct oxygen *chip) { + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX); + oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX); ak4396_init(chip); wm8785_init(chip); claro_enable_hp(chip); @@ -275,6 +279,8 @@ static void claro_init(struct oxygen *chip) static void claro_halo_init(struct oxygen *chip) { + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX); + oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX); ak4396_init(chip); ak5385_init(chip); claro_enable_hp(chip); @@ -523,14 +529,24 @@ static const struct snd_kcontrol_new hpf_control = { .put = hpf_put, }; -static int meridian_dig_source_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) +static int meridian_dig_source_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) { static const char *const names[2] = { "On-board", "Extension" }; return snd_ctl_enum_info(info, 1, 2, names); } -static int meridian_dig_source_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) +static int claro_dig_source_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) +{ + static const char *const names[2] = { "Optical", "Coaxial" }; + + return snd_ctl_enum_info(info, 1, 2, names); +} + +static int meridian_dig_source_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; @@ -540,7 +556,19 @@ static int meridian_dig_source_get(struct snd_kcontrol *ctl, struct snd_ctl_elem return 0; } -static int meridian_dig_source_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) +static int claro_dig_source_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + + value->value.enumerated.item[0] = + !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & + GPIO_CLARO_DIG_COAX); + return 0; +} + +static int meridian_dig_source_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; u16 old_reg, new_reg; @@ -560,6 +588,25 @@ static int meridian_dig_source_put(struct snd_kcontrol *ctl, struct snd_ctl_elem return changed; } +static int claro_dig_source_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + u16 old_reg, new_reg; + int changed; + + mutex_lock(&chip->mutex); + old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA); + new_reg = old_reg & ~GPIO_CLARO_DIG_COAX; + if (value->value.enumerated.item[0]) + new_reg |= GPIO_CLARO_DIG_COAX; + changed = new_reg != old_reg; + if (changed) + oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg); + mutex_unlock(&chip->mutex); + return changed; +} + static const struct snd_kcontrol_new meridian_dig_source_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Source Capture Enum", @@ -568,6 +615,14 @@ static const struct snd_kcontrol_new meridian_dig_source_control = { .put = meridian_dig_source_put, }; +static const struct snd_kcontrol_new claro_dig_source_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "IEC958 Source Capture Enum", + .info = claro_dig_source_info, + .get = claro_dig_source_get, + .put = claro_dig_source_put, +}; + static int generic_mixer_init(struct oxygen *chip) { return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); @@ -600,6 +655,34 @@ static int meridian_mixer_init(struct oxygen *chip) return 0; } +static int claro_mixer_init(struct oxygen *chip) +{ + int err; + + err = generic_wm8785_mixer_init(chip); + if (err < 0) + return err; + err = snd_ctl_add(chip->card, + snd_ctl_new1(&claro_dig_source_control, chip)); + if (err < 0) + return err; + return 0; +} + +static int claro_halo_mixer_init(struct oxygen *chip) +{ + int err; + + err = generic_mixer_init(chip); + if (err < 0) + return err; + err = snd_ctl_add(chip->card, + snd_ctl_new1(&claro_dig_source_control, chip)); + if (err < 0) + return err; + return 0; +} + static void dump_ak4396_registers(struct oxygen *chip, struct snd_info_buffer *buffer) { @@ -700,13 +783,14 @@ static int __devinit get_oxygen_model(struct oxygen *chip, break; case MODEL_CLARO: chip->model.init = claro_init; + chip->model.mixer_init = claro_mixer_init; chip->model.cleanup = claro_cleanup; chip->model.suspend = claro_suspend; chip->model.resume = claro_resume; break; case MODEL_CLARO_HALO: chip->model.init = claro_halo_init; - chip->model.mixer_init = generic_mixer_init; + chip->model.mixer_init = claro_halo_mixer_init; chip->model.cleanup = claro_cleanup; chip->model.suspend = claro_suspend; chip->model.resume = claro_resume; -- cgit v1.2.3 From 6661702f2e803b55b50cc0471eb6b9254e99eef2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Jan 2011 18:07:14 +0100 Subject: ALSA: hda - Don't refer ELD when unplugged When unplugged, we shouldn't refer to ELD information for PCM open any more. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d1b1b5796c98..27e8597f66ad 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -827,7 +827,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, *codec_pars = *hinfo; eld = &spec->sink_eld[idx]; - if (eld->sad_count > 0) { + if (eld->eld_valid && eld->sad_count > 0) { hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); if (hinfo->channels_min > hinfo->channels_max || !hinfo->rates || !hinfo->formats) -- cgit v1.2.3 From 0ebaa24c6b1f62839bcd12d63fa76e3cf23b9bd0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Jan 2011 18:11:04 +0100 Subject: ALSA: hda - Add static_hdmi_pcm option to HDMI codec parser The dynamic PCM restriction based on ELD information may lead to the problem in some cases, e.g. when the receiver is turned off. Then it may send a TV HDMI default such as channels = 2. Since it's still plugged, the driver doesn't know whether it's the right configuration for future use. Now, when an app opens the device at this moment, then turn on the receiver, the app still sends channels=2. The right solution is to implement some kind of notification and automatic re-open mechanism. But, this is a goal far ahead. This patch provides a workaround for such a case by providing a new module option static_hdmi_pcm for snd-hda-codec-hdmi module. When this is set to true, the driver doesn't change PCM parameters per ELD information. For users who need the static configuration like the scenario above, set this to true. The parameter can be changed dynamically via sysfs, too. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_hdmi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 27e8597f66ad..8804c05b5fc7 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -31,10 +31,15 @@ #include #include #include +#include #include #include "hda_codec.h" #include "hda_local.h" +static bool static_hdmi_pcm; +module_param(static_hdmi_pcm, bool, 0644); +MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); + /* * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device * could support two independent pipes, each of them can be connected to one or @@ -827,7 +832,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, *codec_pars = *hinfo; eld = &spec->sink_eld[idx]; - if (eld->eld_valid && eld->sad_count > 0) { + if (!static_hdmi_pcm && eld->eld_valid && eld->sad_count > 0) { hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); if (hinfo->channels_min > hinfo->channels_max || !hinfo->rates || !hinfo->formats) -- cgit v1.2.3 From 393004b2ea49524ee41a562cae8db67f50f372a5 Mon Sep 17 00:00:00 2001 From: Nitin Daga Date: Mon, 10 Jan 2011 21:49:31 +0530 Subject: ALSA: hda: Disable 4/6 channels on some NVIDIA GPUs. Added hardware constraint in patch_hdmi.c to disable channels 4/6 which are not supported by some older NVIDIA GPUs. Signed-off-by: Nitin Daga Acked-By: Stephen Warren Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8804c05b5fc7..f29b97b5de8f 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1193,11 +1193,53 @@ static int nvhdmi_7x_init(struct hda_codec *codec) return 0; } +static unsigned int channels_2_6_8[] = { + 2, 6, 8 +}; + +static unsigned int channels_2_8[] = { + 2, 8 +}; + +static struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = { + .count = ARRAY_SIZE(channels_2_6_8), + .list = channels_2_6_8, + .mask = 0, +}; + +static struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = { + .count = ARRAY_SIZE(channels_2_8), + .list = channels_2_8, + .mask = 0, +}; + static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) { struct hdmi_spec *spec = codec->spec; + struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL; + + switch (codec->preset->id) { + case 0x10de0002: + case 0x10de0003: + case 0x10de0005: + case 0x10de0006: + hw_constraints_channels = &hw_constraints_2_8_channels; + break; + case 0x10de0007: + hw_constraints_channels = &hw_constraints_2_6_8_channels; + break; + default: + break; + } + + if (hw_constraints_channels != NULL) { + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + hw_constraints_channels); + } + return snd_hda_multi_out_dig_open(codec, &spec->multiout); } -- cgit v1.2.3 From e2e93296c50fe13dd2ca60a0e44b5502e9b8c58e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 12 Jan 2011 08:03:39 +0100 Subject: ALSA: hda - Fix missing EAPD for Acer 4930G The proper initializatio of NID 0x15 EAPD is missing in the quirk for Acer 4930G. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0ecd75e2d28f..a8e3eeda0457 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2026,6 +2026,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } }; -- cgit v1.2.3 From 357f915ece53aa4c8759087888346145848ea753 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Wed, 12 Jan 2011 08:12:52 +0100 Subject: ALSA: hda - Fix EAPD on Lenovo NB ALC269 to low Lenovo NB 0x9e54 use the external AMP in an inverted manner. Set EAPD to low will enable the AMP. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a8e3eeda0457..114d3d0f56aa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14821,6 +14821,7 @@ enum { ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, + ALC269_FIXUP_LENOVO_EAPD, }; static const struct alc_fixup alc269_fixups[] = { @@ -14855,6 +14856,12 @@ static const struct alc_fixup alc269_fixups[] = { { } } }, + [ALC269_FIXUP_LENOVO_EAPD] = { + .verbs = (const struct hda_verb[]) { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, + {} + } + }, }; static struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -14866,6 +14873,7 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), + SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), {} }; -- cgit v1.2.3 From c386735264da97e6b6d15aa56361e9ef188b26ab Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 12 Jan 2011 08:30:12 +0100 Subject: ALSA: oxygen: fix Xonar DG input Apparently, this card uses the other I2S input. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_dg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c index dd45cf4d9eb9..e4de0b8d087a 100644 --- a/sound/pci/oxygen/xonar_dg.c +++ b/sound/pci/oxygen/xonar_dg.c @@ -561,7 +561,7 @@ struct oxygen_model model_xonar_dg = { .model_data_size = sizeof(struct dg), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1, + CAPTURE_0_FROM_I2S_2, .dac_channels_pcm = 6, .dac_channels_mixer = 0, .function_flags = OXYGEN_FUNCTION_SPI, -- cgit v1.2.3 From 1a99d4a46c4d08da3418a2079b78ec5daa2a6408 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Wed, 12 Jan 2011 09:01:23 +0100 Subject: ALSA: hda - Fix ALC275 enable hardware EQ for SONY VAIO SONY VAIO ALC275 default BIOS verb set the hardware EQ to disable. Enable it when driver is loading. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 114d3d0f56aa..f44d0e355835 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14815,6 +14815,15 @@ static int alc269_resume(struct hda_codec *codec) } #endif /* SND_HDA_NEEDS_RESUME */ +static void alc269_fixup_hweq(struct hda_codec *codec, + const struct alc_fixup *fix, int pre_init) +{ + int coef; + + coef = alc_read_coef_idx(codec, 0x1e); + alc_write_coef_idx(codec, 0x1e, coef | 0x80); +} + enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIX_SONY_VAIO_GPIO2, @@ -14822,6 +14831,7 @@ enum { ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, ALC269_FIXUP_LENOVO_EAPD, + ALC275_FIXUP_SONY_HWEQ, }; static const struct alc_fixup alc269_fixups[] = { @@ -14862,12 +14872,22 @@ static const struct alc_fixup alc269_fixups[] = { {} } }, + [ALC275_FIXUP_SONY_HWEQ] = { + .func = alc269_fixup_hweq, + .verbs = (const struct hda_verb[]) { + {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, + { } + } + } }; static struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), - SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), - SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), + SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), + SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), -- cgit v1.2.3 From 700b65cee958d81b16c48378d5759c46d01e24d0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 12 Jan 2011 09:03:05 +0100 Subject: ALSA: hda - Add missing NID 0x19 fixup for Sony VAIO With GPIO2-fixup, another fixup for NID 0x19 was missing because the fixup is applied only once. Add the corresponding verb to the entry. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f44d0e355835..98c9cd8f6471 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14846,6 +14846,7 @@ static const struct alc_fixup alc269_fixups[] = { {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, { } } }, -- cgit v1.2.3 From 80c678526d7da73bde4d46a4622449c2b3c88409 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Jan 2011 08:08:08 +0100 Subject: ALSA: hda - Fix NULL-derefence with a single mic in STAC auto-mic detection When only one mic is available and it's an analog mic, the current IDT/STAC parser may give an Oops. Reference: bko#25692 https://bugzilla.kernel.org/show_bug.cgi?id=25692 Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c8d812ecb943..4ab019d0924e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3594,7 +3594,7 @@ static int stac_check_auto_mic(struct hda_codec *codec) if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext, &dock)) return 0; - if (!fixed && !ext && !dock) + if (!fixed || (!ext && !dock)) return 0; /* no input to switch */ if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) return 0; /* no unsol support */ -- cgit v1.2.3