From b595076a180a56d1bb170e6eceda6eb9d76f4cd3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 1 Nov 2010 15:38:34 -0400 Subject: tree-wide: fix comment/printk typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "gadget", "through", "command", "maintain", "maintain", "controller", "address", "between", "initiali[zs]e", "instead", "function", "select", "already", "equal", "access", "management", "hierarchy", "registration", "interest", "relative", "memory", "offset", "already", Signed-off-by: Uwe Kleine-König Signed-off-by: Jiri Kosina --- sound/pci/ca0106/ca0106.h | 2 +- sound/pci/emu10k1/emu10k1x.c | 2 +- sound/pci/emu10k1/p16v.h | 2 +- sound/pci/es1968.c | 2 +- sound/pci/rme9652/hdspm.c | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index f19c11077255..fc53b9bca26d 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h @@ -188,7 +188,7 @@ #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ /* PTR[5:0], Default: 0x0 */ #define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */ -#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ +#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ /* DMA[31:0], Default: 0x0 */ #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ /* SIZE[31:16], Default: 0x0 */ diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index df47f738098d..0c701e4ec8a5 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -114,7 +114,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard."); */ #define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ -#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ +#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */ #define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */ #define PLAYBACK_UNKNOWN1 0x07 diff --git a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h index 153214940336..00f4817533b1 100644 --- a/sound/pci/emu10k1/p16v.h +++ b/sound/pci/emu10k1/p16v.h @@ -96,7 +96,7 @@ #define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ #define PLAYBACK_UNKNOWN3 0x03 /* Not used */ -#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ +#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ #define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */ #define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */ diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 23a58f0d6cb9..7c17f45d876d 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -220,7 +220,7 @@ MODULE_PARM_DESC(joystick, "Enable joystick."); #define RINGB_EN_2CODEC 0x0020 #define RINGB_SING_BIT_DUAL 0x0040 -/* ****Port Adresses**** */ +/* ****Port Addresses**** */ /* Write & Read */ #define ESM_INDEX 0x02 diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 0c98ef9156d8..f5eadfc0672a 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -487,7 +487,7 @@ struct hdspm { struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; /* but input to much, so not used */ struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; - /* full mixer accessable over mixer ioctl or hwdep-device */ + /* full mixer accessible over mixer ioctl or hwdep-device */ struct hdspm_mixer *mixer; }; @@ -550,7 +550,7 @@ static inline int HDSPM_bit2freq(int n) return bit2freq_tab[n]; } -/* Write/read to/from HDSPM with Adresses in Bytes +/* Write/read to/from HDSPM with Addresses in Bytes not words but only 32Bit writes are allowed */ static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg, @@ -2908,7 +2908,7 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm /* Channel playback mixer as default control Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, - thats too * big for any alsamixer they are accesible via special + thats too * big for any alsamixer they are accessible via special IOCTL on hwdep and the mixer 2dimensional mixer control */ -- cgit v1.2.3 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 --- Documentation/sound/alsa/ALSA-Configuration.txt | 10 +- sound/pci/Kconfig | 15 +- sound/pci/oxygen/Makefile | 2 - sound/pci/oxygen/hifier.c | 239 ------------------------ sound/pci/oxygen/oxygen.c | 43 ++++- 5 files changed, 42 insertions(+), 267 deletions(-) delete mode 100644 sound/pci/oxygen/hifier.c (limited to 'sound/pci') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d0eb696d32e8..f1a1787e71e5 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -974,13 +974,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. See hdspm.txt for details. - Module snd-hifier - ----------------- - - Module for the MediaTek/TempoTec HiFier Fantasia sound card. - - This module supports autoprobe and multiple cards. - Module snd-ice1712 ------------------ @@ -1531,7 +1524,7 @@ 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 CMI8788 chip: + Module for sound cards based on the C-Media CMI8787/8788 chip: * Asound A-8788 * AuzenTech X-Meridian * Bgears b-Enspirer @@ -1540,6 +1533,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * HT-Omega Claro halo (XT) * Razer Barracuda AC-1 * Sondigo Inferno + * TempoTec HiFier Fantasia This module supports autoprobe and multiple cards. 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 89feca1a16b05651d9c500e5572c0d6882873396 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 13 Oct 2010 15:48:24 +0200 Subject: ALSA: HDA: Enable digital mic on IDT 92HD87B BugLink: http://launchpad.net/bugs/673075 According to the datasheet of 92HD87B, there is a digital mic at nid 0x11, so enable it in order to be able to use the mic. Cc: stable@kernel.org Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 93fa59cc60ef..cfd73afad882 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -389,6 +389,11 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 0x11, 0x20, 0 }; +#define STAC92HD87B_NUM_DMICS 1 +static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { + 0x11, 0 +}; + #define STAC92HD83XXX_NUM_CAPS 2 static unsigned long stac92hd83xxx_capvols[] = { HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), @@ -5452,12 +5457,17 @@ again: stac92hd83xxx_brd_tbl[spec->board_config]); switch (codec->vendor_id) { + case 0x111d76d1: + case 0x111d76d9: + spec->dmic_nids = stac92hd87b_dmic_nids; + spec->num_dmics = stac92xx_connected_ports(codec, + stac92hd87b_dmic_nids, + STAC92HD87B_NUM_DMICS); + /* Fall through */ case 0x111d7666: case 0x111d7667: case 0x111d7668: case 0x111d7669: - case 0x111d76d1: - case 0x111d76d9: spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); spec->pin_nids = stac92hd88xxx_pin_nids; spec->mono_nid = 0; -- cgit v1.2.3 From e9161512017f11050ef2b826cbb10be1673554c6 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 9 Nov 2010 18:29:08 +0100 Subject: ALSA: sound/mixart: avoid redefining {readl,write}_{le,be} accessors If the platform already provides a definition for these accessors do not redefine them. The warning was caught on MIPS. Signed-off-by: Florian Fainelli Signed-off-by: Takashi Iwai --- sound/pci/mixart/mixart_hwdep.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/mixart/mixart_hwdep.h b/sound/pci/mixart/mixart_hwdep.h index a46f5083db99..812e288ef2e7 100644 --- a/sound/pci/mixart/mixart_hwdep.h +++ b/sound/pci/mixart/mixart_hwdep.h @@ -25,11 +25,21 @@ #include +#ifndef readl_be #define readl_be(x) be32_to_cpu(__raw_readl(x)) +#endif + +#ifndef writel_be #define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr) +#endif +#ifndef readl_le #define readl_le(x) le32_to_cpu(__raw_readl(x)) +#endif + +#ifndef writel_le #define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr) +#endif #define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x)) #define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x)) -- cgit v1.2.3 From fa2b30af84e84129b8d4cf955890ad167cc20cf0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 9 Nov 2010 23:00:41 +0100 Subject: ALSA: sound/pci/ctxfi/ctpcm.c: Remove potential for use after free In each function, the value apcm is stored in the private_data field of runtime. At the same time the function ct_atc_pcm_free_substream is stored in the private_free field of the same structure. ct_atc_pcm_free_substream dereferences and ultimately frees the value in the private_data field. But each function can exit in an error case with apcm having been freed, in which case a subsequent call to the private_free function would perform a dereference after free. On the other hand, if the private_free field is not initialized, it is NULL, and not invoked (see snd_pcm_detach_substream in sound/core/pcm.c). To avoid the introduction of a dangling pointer, the initializations of the private_data and private_free fields are moved to the end of the function, past any possible free of apcm. This is safe because the previous calls to snd_pcm_hw_constraint_integer and snd_pcm_hw_constraint_minmax, which take runtime as an argument, do not refer to either of these fields. In each function, there is one error case where apcm needs to be freed, and a call to kfree is added. The sematic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e,e1,e2,e3; identifier f,free1,free2; expression a; @@ *e->f = a ... when != e->f = e1 when any if (...) { ... when != free1(...,e,...) when != e->f = e2 * kfree(a) ... when != free2(...,e,...) when != e->f = e3 } // Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctpcm.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 85ab43e89212..457d21189b0d 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -129,8 +129,6 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) apcm->substream = substream; apcm->interrupt = ct_atc_pcm_interrupt; - runtime->private_data = apcm; - runtime->private_free = ct_atc_pcm_free_substream; if (IEC958 == substream->pcm->device) { runtime->hw = ct_spdif_passthru_playback_hw; atc->spdif_out_passthru(atc, 1); @@ -155,8 +153,12 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) } apcm->timer = ct_timer_instance_new(atc->timer, apcm); - if (!apcm->timer) + if (!apcm->timer) { + kfree(apcm); return -ENOMEM; + } + runtime->private_data = apcm; + runtime->private_free = ct_atc_pcm_free_substream; return 0; } @@ -278,8 +280,6 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) apcm->started = 0; apcm->substream = substream; apcm->interrupt = ct_atc_pcm_interrupt; - runtime->private_data = apcm; - runtime->private_free = ct_atc_pcm_free_substream; runtime->hw = ct_pcm_capture_hw; runtime->hw.rate_max = atc->rsr * atc->msr; @@ -298,8 +298,12 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) } apcm->timer = ct_timer_instance_new(atc->timer, apcm); - if (!apcm->timer) + if (!apcm->timer) { + kfree(apcm); return -ENOMEM; + } + runtime->private_data = apcm; + runtime->private_free = ct_atc_pcm_free_substream; return 0; } -- cgit v1.2.3 From 0613a59456980161d0cd468bae6c63d772743102 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Mon, 1 Nov 2010 01:14:51 -0400 Subject: ALSA: ac97: Apply quirk for Dell Latitude D610 binding Master and Headphone controls BugLink: https://launchpad.net/bugs/669279 The original reporter states: "The Master mixer does not change the volume from the headphone output (which is affected by the headphone mixer). Instead it only seems to control the on-board speaker volume. This confuses PulseAudio greatly as the Master channel is merged into the volume mix." Fix this symptom by applying the hp_only quirk for the reporter's SSID. The fix is applicable to all stable kernels. Reported-and-tested-by: Ben Gamari Cc: [2.6.32+] Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 400f9ebd243e..629a5494347a 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1864,6 +1864,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .name = "Dell Inspiron 8600", /* STAC9750/51 */ .type = AC97_TUNE_HP_ONLY }, + { + .subvendor = 0x1028, + .subdevice = 0x0182, + .name = "Dell Latitude D610", /* STAC9750/51 */ + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x1028, .subdevice = 0x0186, -- cgit v1.2.3 From 5dbea6b1f2113f764999b39fd3d79b1354c193d9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 12:14:02 -0800 Subject: ALSA: sound/pci/asihpi/hpioctl.c: Remove unnecessary casts of pci_get_drvdata Signed-off-by: Joe Perches Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 62895a719fcb..22dbd91811a4 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -435,7 +435,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) struct hpi_message hm; struct hpi_response hr; struct hpi_adapter *pa; - pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev); + pa = pci_get_drvdata(pci_dev); hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_DELETE_ADAPTER); -- 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 a0e90acc657990511c83bc69965bfd3c63386d45 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 5f00589cb791..1a7703a49655 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19298,6 +19298,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 78ac07b0d2b09b1ccb7a41a2e25f71d60b652920 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 673f7a8984c3a9e2cb1108ce221da1ebbd9e5d09 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 01e0f1378c47947b825eac05c98697ab1be1c86f Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Mon, 22 Nov 2010 10:59:36 +0100 Subject: ALSA: hda - Fixed ALC887-VD initial error ALC887-VD is like ALC888-VD. It can not be initialized as ALC882. Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1a7703a49655..564e6c136ddd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19420,7 +19420,10 @@ static int patch_alc888(struct hda_codec *codec) { if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ kfree(codec->chip_name); - codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); + if (codec->vendor_id == 0x10ec0887) + codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL); + else + codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); if (!codec->chip_name) { alc_free(codec); return -ENOMEM; @@ -19910,7 +19913,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", .patch = patch_alc882 }, { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, - { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, + { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 }, { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", .patch = patch_alc882 }, { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, -- 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 d090f5976dfcac4935286676825d64e081335e09 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 23 Nov 2010 07:39:58 +0100 Subject: ALSA: Revert "ALSA: hda - Fix switching between dmic and mic using the same mux on IDT/STAC" This reverts commit f41cc2a85d52ac6971299922084ac5ac59dc339d. The patch broke the digital mic pin handling wrongly. Reference: bko#23162 https://bugzilla.kernel.org/show_bug.cgi?id=23162 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index cfd73afad882..5c710807dfe5 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3491,10 +3491,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, return err; } - if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) { + if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) snd_hda_add_imux_item(imux, label, index, NULL); - spec->num_analog_muxes++; - } } return 0; -- cgit v1.2.3 From 6027277e77df2d2893d906c42f5c9f9abcb731e0 Mon Sep 17 00:00:00 2001 From: Manoj Iyer Date: Tue, 23 Nov 2010 07:43:44 +0100 Subject: ALSA: hda - Enable jack sense for Thinkpad Edge 11 Add a quirk entry for Thinkpad Edge 11 as well as other TP Edge models. Signed-off-by: Manoj Iyer 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 3cfb31e77b16..846d1ead47fd 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3111,6 +3111,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), 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), -- cgit v1.2.3 From 1657cbd87125a623d28ce8a7ef5ff6959098d425 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 23 Nov 2010 08:53:32 +0100 Subject: ALSA: hda - Fix wrong ALC269 variant check The refactoring commit d433a67831ab2c470cc53a3ff9b60f656767be15 ALSA: hda - Optimize the check of ALC269 codec variants introduced a wrong check for ALC269-vb type. This patch corrects it. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 564e6c136ddd..38b63fb79cbd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15104,7 +15104,7 @@ static int patch_alc269(struct hda_codec *codec) spec->stream_digital_capture = &alc269_pcm_digital_capture; if (!spec->adc_nids) { /* wasn't filled automatically? use default */ - if (spec->codec_variant != ALC269_TYPE_NORMAL) { + if (spec->codec_variant == ALC269_TYPE_NORMAL) { spec->adc_nids = alc269_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); spec->capsrc_nids = alc269_capsrc_nids; -- cgit v1.2.3 From 48c88e820fb3e35c5925e4743fd13f200891b7b5 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 23 Nov 2010 08:56:16 +0100 Subject: ALSA: hda - Identify more variants for ALC269 Give more correct chip names for ALC269-variant codecs. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 38b63fb79cbd..0ac6aed0c889 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14623,7 +14623,10 @@ static int alc275_setup_dual_adc(struct hda_codec *codec) /* different alc269-variants */ enum { ALC269_TYPE_NORMAL, + ALC269_TYPE_ALC258, ALC269_TYPE_ALC259, + ALC269_TYPE_ALC269VB, + ALC269_TYPE_ALC270, ALC269_TYPE_ALC271X, }; @@ -15023,7 +15026,7 @@ static int alc269_fill_coef(struct hda_codec *codec) static int patch_alc269(struct hda_codec *codec) { struct alc_spec *spec; - int board_config; + int board_config, coef; int err; spec = kzalloc(sizeof(*spec), GFP_KERNEL); @@ -15034,14 +15037,23 @@ static int patch_alc269(struct hda_codec *codec) alc_auto_parse_customize_define(codec); - if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ + coef = alc_read_coef_idx(codec, 0); + if ((coef & 0x00f0) == 0x0010) { if (codec->bus->pci->subsystem_vendor == 0x1025 && spec->cdefine.platform_type == 1) { alc_codec_rename(codec, "ALC271X"); spec->codec_variant = ALC269_TYPE_ALC271X; - } else { + } else if ((coef & 0xf000) == 0x1000) { + spec->codec_variant = ALC269_TYPE_ALC270; + } else if ((coef & 0xf000) == 0x2000) { alc_codec_rename(codec, "ALC259"); spec->codec_variant = ALC269_TYPE_ALC259; + } else if ((coef & 0xf000) == 0x3000) { + alc_codec_rename(codec, "ALC258"); + spec->codec_variant = ALC269_TYPE_ALC258; + } else { + alc_codec_rename(codec, "ALC269VB"); + spec->codec_variant = ALC269_TYPE_ALC269VB; } } else alc_fix_pll_init(codec, 0x20, 0x04, 15); -- cgit v1.2.3 From d94772070acc5a8f312ab4650cbbf5e78ea9dda2 Mon Sep 17 00:00:00 2001 From: Denis Kuplyakov Date: Wed, 24 Nov 2010 06:01:09 +0100 Subject: ALSA: hda - Fix Acer 7730G support Fixes automatic EAPD configuration on Acer 7730G laptop. Signed-off-by: Denis Kuplyakov Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 49 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0ac6aed0c889..8f7530fc7644 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2013,6 +2013,36 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { { } }; +/* + *ALC888 Acer Aspire 7730G model + */ + +static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { +/* Bias voltage on for external mic port */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, +/* Front Mic: set to PIN_IN (empty by default) */ + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, +/* Unselect Front Mic by default in input mixer 3 */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, +/* Enable unsolicited event for HP jack */ + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, +/* Enable speaker output */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, +/* Enable headphone output */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, +/*Enable internal subwoofer */ + {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, + {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + /* * ALC889 Acer Aspire 8930G model */ @@ -2200,6 +2230,16 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[2] = 0x17; } +static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x14; + spec->autocfg.speaker_pins[1] = 0x16; + spec->autocfg.speaker_pins[2] = 0x17; +} + static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -9524,13 +9564,6 @@ static struct hda_verb alc883_acer_eapd_verbs[] = { { } }; -static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - static void alc888_6st_dell_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -10328,7 +10361,7 @@ static struct alc_config_preset alc882_presets[] = { .const_channel_count = 6, .input_mux = &alc883_capture_source, .unsol_event = alc_automute_amp_unsol_event, - .setup = alc888_acer_aspire_6530g_setup, + .setup = alc888_acer_aspire_7730g_setup, .init_hook = alc_automute_amp, }, [ALC883_MEDION] = { -- cgit v1.2.3 From cc1c452e509aefc28f7ad2deed75bc69d4f915f7 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 24 Nov 2010 14:17:47 +0100 Subject: ALSA: HDA: Add an extra DAC for Realtek ALC887-VD The patch enables ALC887-VD to use the DAC at nid 0x26, which makes it possible to use this DAC for e g Headphone volume. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8f7530fc7644..b0e6b8b47fa9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -18997,6 +18997,8 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) return 0x02; else if (nid >= 0x0c && nid <= 0x0e) return nid - 0x0c + 0x02; + else if (nid == 0x26) /* ALC887-VD has this DAC too */ + return 0x25; else return 0; } @@ -19005,7 +19007,7 @@ static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) { - hda_nid_t mix[4]; + hda_nid_t mix[5]; int i, num; num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); -- cgit v1.2.3 From 7167594a3da7dcc33203b85d62e519594baee390 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Thu, 25 Nov 2010 00:08:01 -0200 Subject: ALSA: hda - Fix ALC660-VD/ALC861-VD capture/playback mixers The mixer nids passed to alc_auto_create_input_ctls are wrong: 0x15 is a pin, and 0x09 is the ADC on both ALC660-VD/ALC861-VD. Thus with current code, input playback volume/switches and input source mixer controls are not created, and recording doesn't work. Select correct mixers, 0x0b (input playback mixer) and 0x22 (capture source mixer). Reference: https://qa.mandriva.com/show_bug.cgi?id=61159 Signed-off-by: Herton Ronaldo Krzesinski Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b0e6b8b47fa9..81a2a49b862c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -16943,7 +16943,7 @@ static struct alc_config_preset alc861vd_presets[] = { static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); + return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0); } -- cgit v1.2.3 From 5a8cfb4e8ae317d283f84122ed20faa069c5e0c4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 26 Nov 2010 17:11:18 +0100 Subject: ALSA: hda - Use ALC_INIT_DEFAULT for really default initialization When SKU assid gives no valid bits for 0x38, the driver didn't take any action, so far. This resulted in the missing initialization for external amps, etc, thus the silent output in the end. Especially users hit this problem on ALC888 newly since 2.6.35, where the driver doesn't force to use ALC_INIT_DEFAULT any more. This patch sets the default initialization scheme to use ALC_INIT_DEFAULT when no valid bits are set for SKU assid. Reference: https://bugzilla.redhat.com/show_bug.cgi?id=657388 Reported-and-tested-by: Kyle McMartin Cc: 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 81a2a49b862c..886d7c72936e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1614,6 +1614,7 @@ do_sku: spec->init_amp = ALC_INIT_GPIO3; break; case 5: + default: spec->init_amp = ALC_INIT_DEFAULT; break; } -- cgit v1.2.3 From ac70eb1305d5a81efd1e32327d7e79be15a63a5a Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sat, 27 Nov 2010 13:58:04 -0500 Subject: ALSA: hda: Use BIOS auto-parsing instead of existing model quirk for MEDION MD2 BugLink: https://launchpad.net/bugs/682199 A 2.6.35 (Ubuntu Maverick) user, burningphantom1, reported a regression in audio: playback was inaudible through both speakers and headphones. In commit 272a527c04 of sound-2.6.git, a new model was added with this machine's PCI SSID. Fortunately, it is now sufficient to use the auto model for BIOS auto-parsing instead of the existing quirk. Playback, capture, and jack sense were verified working for both 2.6.35 and the alsa-driver snapshot from 2010-11-27 when model=auto is used. Reported-and-tested-by: burningphantom1 Cc: [2.6.35+] Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 886d7c72936e..8fddc9d08726 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9865,7 +9865,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), - SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), -- 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 0defe09ca70daccdc83abd9c3c24cd89ae6a1141 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Wed, 1 Dec 2010 19:16:07 -0500 Subject: ALSA: hda: Use "alienware" model quirk for another SSID BugLink: https://launchpad.net/bugs/683695 The original reporter states that headphone jacks do not appear to work. Upon inspecting his codec dump, and upon further testing, it is confirmed that the "alienware" model quirk is correct. Reported-and-tested-by: Cody Thierauf Cc: [2.6.32+] Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 5c710807dfe5..efa4225f5fd6 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1627,6 +1627,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, "Alienware M17x", STAC_ALIENWARE_M17X), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, + "Alienware M17x", STAC_ALIENWARE_M17X), {} /* terminator */ }; -- cgit v1.2.3 From 77c4d5cdb81d25a45fbdfb84dd3348121219a072 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Thu, 2 Dec 2010 22:45:45 -0500 Subject: ALSA: hda: Use model=lg quirk for LG P1 Express to enable playback and capture BugLink: https://launchpad.net/bugs/595482 The original reporter states that audible playback from the internal speaker is inaudible despite the hardware being properly detected. To work around this symptom, he uses the model=lg quirk to properly enable both playback, capture, and jack sense. Another user corroborates this workaround on separate hardware. Add this PCI SSID to the quirk table to enable it for further LG P1 Expresses. Reported-and-tested-by: Philip Peitsch Tested-by: nikhov Cc: [2.6.32+] 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 8fddc9d08726..2d7d7de8498a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4595,6 +4595,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), + SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), -- cgit v1.2.3 From 3a253445e327d0295bbe51bcbec5f44f86b54a8c Mon Sep 17 00:00:00 2001 From: John Baboval Date: Thu, 2 Dec 2010 11:21:31 -0500 Subject: ALSA: hda - Fix ThinkPad T410[s] docking station line-out On the docking station for the Lenovo T410 and T410s, the line-out doesn't work. The trouble seems to be that it generates a plug event, but then doesn't report that the jack is connected. So automute mutes the jack when you plug something into it. The following patch (next message) fixes it. Signed-off-by: John Baboval Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 846d1ead47fd..e652b34b1bd9 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -2116,8 +2116,8 @@ static void cxt5066_update_speaker(struct hda_codec *codec) struct conexant_spec *spec = codec->spec; unsigned int pinctl; - snd_printdd("CXT5066: update speaker, hp_present=%d\n", - spec->hp_present); + snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n", + spec->hp_present, spec->cur_eapd); /* Port A (HP) */ pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; @@ -2125,11 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec) pinctl); /* Port D (HP/LO) */ - pinctl = ((spec->hp_present & 2) && spec->cur_eapd) - ? spec->port_d_mode : 0; - /* Mute if Port A is connected on Thinkpad */ - if (spec->thinkpad && (spec->hp_present & 1)) - pinctl = 0; + 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 = 0; + } else { + pinctl = ((spec->hp_present & 2) && spec->cur_eapd) + ? spec->port_d_mode : 0; + } snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); @@ -2137,14 +2146,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec) pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); - - if (spec->dell_automute) { - /* DELL AIO Port Rule: PortA > PortD > IntSpk */ - pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) - ? PIN_OUT : 0; - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); - } } /* turn on/off EAPD (+ mute HP) as a master switch */ -- 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 ef61d4e6d88da80dc2b417cf8ad3c77aa94f0c8f Mon Sep 17 00:00:00 2001 From: Manoj Iyer Date: Fri, 3 Dec 2010 18:43:55 -0600 Subject: ALSA: hda - Enable jack sense for Thinkpad Edge 13 Added a quirk to cxt5066_cfg_tbl to enable jack sense for ThinkPad Edge 13. Reference: http://launchpad.net/bugs/685015 Signed-off-by: Manoj Iyer 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 e652b34b1bd9..4ab5ea9f0530 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3110,6 +3110,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 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), -- 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 dd5a089edfa51a74692604b4b427953d8e16bc35 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 5 Dec 2010 08:43:14 -0500 Subject: ALSA: hda: Use position_fix=1 for Acer Aspire 5538 to enable capture on internal mic BugLink: https://launchpad.net/bugs/685161 The reporter of the bug states that he must use position_fix=1 to enable capture for the internal microphone, so set it for his machine's PCI SSID. Verified using 2.6.35 and the 2010-12-04 alsa-driver build. Reported-and-tested-by: Ralph Wabel Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21aa9b0e28f6..b030c8eba21f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2296,6 +2296,7 @@ static int azx_dev_free(struct snd_device *device) */ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), -- 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 4b0dbdb17f846a8887e5f7fbeea2deb0703236bd Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 7 Dec 2010 18:41:35 +0200 Subject: ALSA: hda - Do not wrongly restrict min_channels based on ELD Commit bbbe33900d1f3c added functionality to restrict PCM parameters based on ELD info (derived from EDID data) of the audio sink. However, it wrongly assumes that the bits 0-2 of the first byte of CEA Short Audio Descriptors mean a supported number of channels. In reality, they mean the maximum number of channels (as per CEA-861-D 7.5.2). This means that the channel count can only be used to restrict max_channels, not min_channels. Restricting min_channels causes us to deny opening the device in stereo mode if the sink only has SADs that declare larger numbers of channels (like Primare SP32 AV Processor does). Fix that by not restricting min_channels based on ELD information. Signed-off-by: Anssi Hannula Reported-by: Jean-Yves Avenard Tested-by: Jean-Yves Avenard Cc: stable@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 4 ---- sound/pci/hda/patch_hdmi.c | 1 - 2 files changed, 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index cb0c23a6b473..47ef8aa4a844 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -601,13 +601,10 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, pcm->rates = 0; pcm->formats = 0; pcm->maxbps = 0; - pcm->channels_min = -1; pcm->channels_max = 0; for (i = 0; i < eld->sad_count; i++) { struct cea_sad *a = &eld->sad[i]; pcm->rates |= a->rates; - if (a->channels < pcm->channels_min) - pcm->channels_min = a->channels; if (a->channels > pcm->channels_max) pcm->channels_max = a->channels; if (a->format == AUDIO_CODING_TYPE_LPCM) { @@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, /* restrict the parameters by the values the codec provides */ pcm->rates &= codec_pars->rates; pcm->formats &= codec_pars->formats; - pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min); pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); } diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d3e49aa5b9ec..31df7747990d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, return -ENODEV; } else { /* fallback to the codec default */ - hinfo->channels_min = codec_pars->channels_min; hinfo->channels_max = codec_pars->channels_max; hinfo->rates = codec_pars->rates; hinfo->formats = codec_pars->formats; -- cgit v1.2.3 From 3dc86429032910bdf762adeb2969112bb303924c Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 7 Dec 2010 20:56:19 +0200 Subject: ALSA: hda - Always allow basic audio irrespective of ELD info Commit bbbe33900d1f3c added functionality to restrict PCM parameters based on ELD info (derived from EDID data) of the audio sink. However, according to CEA-861-D no SAD is needed for basic audio (32/44.1/48kHz stereo 16-bit audio), which is instead indicated with a basic audio flag in the CEA EDID Extension. The flag is not present in ELD. However, as all audio capable sinks are required to support basic audio, we can assume it to be always available. Fix allowed audio formats with sinks that have SADs (Short Audio Descriptors) which do not completely overlap with the basic audio formats (there are no reports of affected devices so far) by always assuming that basic audio is supported. Reported-by: Stephen Warren Signed-off-by: Anssi Hannula Cc: stable@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 47ef8aa4a844..009031fae2ba 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -598,21 +598,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, { int i; - pcm->rates = 0; - pcm->formats = 0; - pcm->maxbps = 0; - pcm->channels_max = 0; + /* assume basic audio support (the basic audio flag is not in ELD; + * however, all audio capable sinks are required to support basic + * audio) */ + pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; + pcm->formats = SNDRV_PCM_FMTBIT_S16_LE; + pcm->maxbps = 16; + pcm->channels_max = 2; for (i = 0; i < eld->sad_count; i++) { struct cea_sad *a = &eld->sad[i]; pcm->rates |= a->rates; if (a->channels > pcm->channels_max) pcm->channels_max = a->channels; if (a->format == AUDIO_CODING_TYPE_LPCM) { - if (a->sample_bits & AC_SUPPCM_BITS_16) { - pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE; - if (pcm->maxbps < 16) - pcm->maxbps = 16; - } if (a->sample_bits & AC_SUPPCM_BITS_20) { pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; if (pcm->maxbps < 20) -- cgit v1.2.3 From 0bbaee3a58c379c4f7bab9635c71d7bad9c422a2 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 7 Dec 2010 21:19:23 +0200 Subject: ALSA: hda - Reset sample sizes and max bitrates when reading ELD When a new HDMI/DP device is plugged in, hdmi_update_short_audio_desc() is called for every SAD (Short Audio Descriptor) in the ELD data. For LPCM coding type SAD defines the supported sample sizes. For several other coding types (such as AC-3), a maximum bitrate is defined. The maximum bitrate and sample size fields are not always cleared. Therefore, if a device is unplugged and a different one is plugged in, and the coding types of some SAD positions differ between the devices, the old max_bitrate or sample_bits values will persist if the new SADs do not define those values. The leftover max_bitrate and sample_bits do not cause any issues other than wrongly showing up in eld#X.Y procfs file and kernel log. Fix that by always clearing sample_bits and max_bitrate when reading SADs. Signed-off-by: Anssi Hannula Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 009031fae2ba..4a663471dadc 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, a->channels = GRAB_BITS(buf, 0, 0, 3); a->channels++; + a->sample_bits = 0; + a->max_bitrate = 0; + a->format = GRAB_BITS(buf, 0, 3, 4); switch (a->format) { case AUDIO_CODING_TYPE_REF_STREAM_HEADER: @@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, case AUDIO_CODING_TYPE_LPCM: val = GRAB_BITS(buf, 2, 0, 3); - a->sample_bits = 0; for (i = 0; i < 3; i++) if (val & (1 << i)) a->sample_bits |= cea_sample_sizes[i + 1]; -- 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 8a96b1e02029aa512199b1b6d281dcede9ed81f1 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Thu, 9 Dec 2010 07:17:27 +0100 Subject: ALSA: HDA: Quirk for Dell Vostro 320 to make microphone work BugLink: http://launchpad.net/497546 Confirmed that the ideapad model works better than the current quirk for Dell Vostro 320. Cc: stable@kernel.org (2.6.35+) Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 4ab5ea9f0530..76bd58a0e2b6 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3096,8 +3096,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { 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", - CXT5066_DELL_LAPTOP), + SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), 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 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 fe67b24010c66a14d84117ac67d23ed1bcb18a71 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 15 Dec 2010 08:01:46 +0100 Subject: ALSA: HDA: Fix auto-mute on Lenovo Edge 14 BugLink: http://launchpad.net/bugs/690530 The SKU value of this machine dictates that auto-mute should be disabled. Since the SKU value is similar to the PCI SSID, the most likely conclusion is that the SKU value should be ignored. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2d7d7de8498a..e5fbd00293f7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14800,6 +14800,7 @@ static int alc269_resume(struct hda_codec *codec) enum { ALC269_FIXUP_SONY_VAIO, ALC269_FIXUP_DELL_M101Z, + ALC269_FIXUP_LENOVO_EDGE14, }; static const struct alc_fixup alc269_fixups[] = { @@ -14817,11 +14818,15 @@ static const struct alc_fixup alc269_fixups[] = { {} } }, + [ALC269_FIXUP_LENOVO_EDGE14] = { + .sku = ALC_FIXUP_SKU_IGNORE, + }, }; static struct snd_pci_quirk alc269_fixup_tbl[] = { 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_LENOVO_EDGE14), {} }; -- cgit v1.2.3 From ac612407932be18697b5ae9da0a80f138b8bea8e Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 15 Dec 2010 09:18:18 +0100 Subject: ALSA: HDA: Enable subwoofer on Asus G73Jw Set default association/sequence right on pin 0x17 in order for the automatic parser to recognize the subwoofer correctly. Signed-off-by: David Henningsson 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 e5fbd00293f7..8e7948f56106 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14801,6 +14801,7 @@ enum { ALC269_FIXUP_SONY_VAIO, ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_LENOVO_EDGE14, + ALC269_FIXUP_ASUS_G73JW, }; static const struct alc_fixup alc269_fixups[] = { @@ -14821,12 +14822,19 @@ static const struct alc_fixup alc269_fixups[] = { [ALC269_FIXUP_LENOVO_EDGE14] = { .sku = ALC_FIXUP_SKU_IGNORE, }, + [ALC269_FIXUP_ASUS_G73JW] = { + .pins = (const struct alc_pincfg[]) { + { 0x17, 0x99130111 }, /* subwoofer */ + { } + } + }, }; static struct snd_pci_quirk alc269_fixup_tbl[] = { 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_LENOVO_EDGE14), + SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), {} }; -- 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 53e8c3239bcc7b89c76179fd33fb6faa3413c00d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Dec 2010 15:23:41 +0100 Subject: ALSA: hda - Fix conflict of Mic Boot controls Due to the recent change for multiple mics assignment, we need to handle the index of each Mic Boost control respectively. Otherwise the driver gets the control element conflicts, and gives the unsable state. Reference: kernel bug 25002 https://bugzilla.kernel.org/show_bug.cgi?id=25002 Reported-and-tested-by: Adam Williamson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8e7948f56106..427da45d7906 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10830,7 +10830,8 @@ 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; + int i, err, type; + int type_idx = 0; hda_nid_t nid; for (i = 0; i < cfg->num_inputs; i++) { @@ -10839,9 +10840,15 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) 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) + type_idx++; + else + type_idx = 0; snprintf(label, sizeof(label), "%s Boost", hda_get_autocfg_input_label(codec, cfg, i)); - err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, + err = add_control(spec, ALC_CTL_WIDGET_VOL, label, + type_idx, HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); if (err < 0) return err; -- cgit v1.2.3 From 022c92befa539174125b0a1b5e52dd57affefe9f Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Fri, 17 Dec 2010 20:43:04 +0100 Subject: ALSA: HDA: Add auto-mute for Thinkpad SL410/SL510 BugLink: http://launchpad.net/bugs/580006 SKU turns off auto-mute for these machines, so ignore the SKU. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 427da45d7906..dd56d8833ad2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14807,7 +14807,7 @@ static int alc269_resume(struct hda_codec *codec) enum { ALC269_FIXUP_SONY_VAIO, ALC269_FIXUP_DELL_M101Z, - ALC269_FIXUP_LENOVO_EDGE14, + ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, }; @@ -14826,7 +14826,7 @@ static const struct alc_fixup alc269_fixups[] = { {} } }, - [ALC269_FIXUP_LENOVO_EDGE14] = { + [ALC269_FIXUP_SKU_IGNORE] = { .sku = ALC_FIXUP_SKU_IGNORE, }, [ALC269_FIXUP_ASUS_G73JW] = { @@ -14840,7 +14840,8 @@ static const struct alc_fixup alc269_fixups[] = { static struct snd_pci_quirk alc269_fixup_tbl[] = { 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_LENOVO_EDGE14), + 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), {} }; -- 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 2785591a9760c677a7ee6f541e751c23086f5bfd Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 21 Dec 2010 09:09:53 +0100 Subject: ALSA: hda - Add fix-up for Sony VAIO with ALC275 codecs Set GPIO2 for some Sony VAIO with ALC275 to fix speaker output. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index dd56d8833ad2..c9af538323ea 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14806,6 +14806,7 @@ static int alc269_resume(struct hda_codec *codec) enum { ALC269_FIXUP_SONY_VAIO, + ALC275_FIX_SONY_VAIO_GPIO2, ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, @@ -14818,6 +14819,14 @@ static const struct alc_fixup alc269_fixups[] = { {} } }, + [ALC275_FIX_SONY_VAIO_GPIO2] = { + .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}, + { } + } + }, [ALC269_FIXUP_DELL_M101Z] = { .verbs = (const struct hda_verb[]) { /* Enables internal speaker */ @@ -14839,6 +14848,9 @@ static const struct alc_fixup alc269_fixups[] = { static struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), + 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(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), -- cgit v1.2.3 From c793bec550c68a1da1034090b43a886e8fee5eb0 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 21 Dec 2010 09:14:13 +0100 Subject: ALSA: hda - Don't apply ALC269-specific initialization to ALC275 ALC275 doesn't require the ALC269 (and its variants) specific init sequences. Add the check of codec id. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 45 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c9af538323ea..69aa62eb9548 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15104,28 +15104,29 @@ static int patch_alc269(struct hda_codec *codec) alc_auto_parse_customize_define(codec); - coef = alc_read_coef_idx(codec, 0); - if ((coef & 0x00f0) == 0x0010) { - if (codec->bus->pci->subsystem_vendor == 0x1025 && - spec->cdefine.platform_type == 1) { - alc_codec_rename(codec, "ALC271X"); - spec->codec_variant = ALC269_TYPE_ALC271X; - } else if ((coef & 0xf000) == 0x1000) { - spec->codec_variant = ALC269_TYPE_ALC270; - } else if ((coef & 0xf000) == 0x2000) { - alc_codec_rename(codec, "ALC259"); - spec->codec_variant = ALC269_TYPE_ALC259; - } else if ((coef & 0xf000) == 0x3000) { - alc_codec_rename(codec, "ALC258"); - spec->codec_variant = ALC269_TYPE_ALC258; - } else { - alc_codec_rename(codec, "ALC269VB"); - spec->codec_variant = ALC269_TYPE_ALC269VB; - } - } else - alc_fix_pll_init(codec, 0x20, 0x04, 15); - - alc269_fill_coef(codec); + if (codec->vendor_id == 0x10ec0269) { + coef = alc_read_coef_idx(codec, 0); + if ((coef & 0x00f0) == 0x0010) { + if (codec->bus->pci->subsystem_vendor == 0x1025 && + spec->cdefine.platform_type == 1) { + alc_codec_rename(codec, "ALC271X"); + spec->codec_variant = ALC269_TYPE_ALC271X; + } else if ((coef & 0xf000) == 0x1000) { + spec->codec_variant = ALC269_TYPE_ALC270; + } else if ((coef & 0xf000) == 0x2000) { + alc_codec_rename(codec, "ALC259"); + spec->codec_variant = ALC269_TYPE_ALC259; + } else if ((coef & 0xf000) == 0x3000) { + alc_codec_rename(codec, "ALC258"); + spec->codec_variant = ALC269_TYPE_ALC258; + } else { + alc_codec_rename(codec, "ALC269VB"); + spec->codec_variant = ALC269_TYPE_ALC269VB; + } + } else + alc_fix_pll_init(codec, 0x20, 0x04, 15); + alc269_fill_coef(codec); + } board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, alc269_models, -- cgit v1.2.3 From 2d7ec12b902ae00920cee50d98757376b2fa9467 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Dec 2010 10:16:05 +0100 Subject: ALSA: hda - Fix conflict of d-mic capture volume controls When the d-mics are assigned to the same purpose of another analog mic pins, the driver doesn't compute the index properly, resulting in an error with "existing control". This patch fixes it. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index efa4225f5fd6..f03b2ff90496 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3481,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, label = hda_get_input_pin_label(codec, nid, 1); snd_hda_add_imux_item(dimux, label, index, &type_idx); + if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) + snd_hda_add_imux_item(imux, label, index, &type_idx); err = create_elem_capture_vol(codec, nid, label, type_idx, HDA_INPUT); @@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, if (err < 0) return err; } - - if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) - snd_hda_add_imux_item(imux, label, index, NULL); } return 0; -- cgit v1.2.3 From 1afe206ab6998ecd5f5485e02006b0578720a691 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Dec 2010 10:17:52 +0100 Subject: ALSA: hda - Try to find an empty control index when it's occupied When a mixer control element was already created with the given name, try to find another index for avoiding conflicts, instead of breaking with an error. This makes the driver more robust. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 57 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 644e3f14f8ca..98b6d02a36c9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, } EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); +static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name) +{ + int idx; + for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */ + if (!_snd_hda_find_mixer_ctl(codec, name, idx)) + return idx; + } + return -EBUSY; +} + /** * snd_hda_ctl_add - Add a control element and assign to the codec * @codec: HD-audio codec @@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = { { } /* end */ }; -#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */ - /** * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls * @codec: the HDA codec @@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) struct snd_kcontrol_new *dig_mix; int idx; - for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { - if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", - idx)) - break; - } - if (idx >= SPDIF_MAX_IDX) { + idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); + if (idx < 0) { printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); return -EBUSY; } @@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) struct snd_kcontrol_new *dig_mix; int idx; - for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { - if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", - idx)) - break; - } - if (idx >= SPDIF_MAX_IDX) { + idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch"); + if (idx < 0) { printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); return -EBUSY; } @@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) for (; knew->name; knew++) { struct snd_kcontrol *kctl; + int addr = 0, idx = 0; if (knew->iface == -1) /* skip this codec private value */ continue; - kctl = snd_ctl_new1(knew, codec); - if (!kctl) - return -ENOMEM; - err = snd_hda_ctl_add(codec, 0, kctl); - if (err < 0) { - if (!codec->addr) - return err; + for (;;) { kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; - kctl->id.device = codec->addr; + if (addr > 0) + kctl->id.device = addr; + if (idx > 0) + kctl->id.index = idx; err = snd_hda_ctl_add(codec, 0, kctl); - if (err < 0) + if (!err) + break; + /* try first with another device index corresponding to + * the codec addr; if it still fails (or it's the + * primary codec), then try another control index + */ + if (!addr && codec->addr) + addr = codec->addr; + else if (!idx && !knew->index) { + idx = find_empty_mixer_ctl_idx(codec, + knew->name); + if (idx <= 0) + return err; + } else return err; } } -- cgit v1.2.3 From 7039c74cb54652ba6d726ad4d2a42dbac95a97be Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 23 Dec 2010 16:35:34 +0100 Subject: ALSA: hda - Fix GPIO2-fixup for Sony laptops The fix-up entries by the commit 2785591a9760c677a7ee6f541e751c23086f5bfd ALSA: hda - Add fix-up for Sony VAIO with ALC275 codecs weren't applied in the right position. They had to be before the quirk entry matching to all Sony devices. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 69aa62eb9548..552a09e9211f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14847,10 +14847,10 @@ static const struct alc_fixup alc269_fixups[] = { }; static struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 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_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), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), -- cgit v1.2.3 From 1d3c16a818e992c199844954d95c17fd7ce6cbba Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Tue, 30 Nov 2010 17:43:26 -0600 Subject: PCI: make pci_restore_state return void pci_restore_state only ever returns 0, thus there is no benefit in having it return any value. Also, a large majority of the callers do not check the return code of pci_restore_state. Make the pci_restore_state a void return and avoid the overhead. Acked-by: Mauro Carvalho Chehab Signed-off-by: Jon Mason Signed-off-by: Jesse Barnes --- drivers/media/video/cafe_ccic.c | 4 +--- drivers/net/myri10ge/myri10ge.c | 4 +--- drivers/net/sfc/falcon.c | 25 +++++-------------------- drivers/net/skge.c | 4 +--- drivers/net/sky2.c | 5 +---- drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ++-- drivers/pci/pci-driver.c | 3 ++- drivers/pci/pci.c | 7 ++----- drivers/scsi/ipr.c | 8 +------- drivers/scsi/pmcraid.c | 7 +------ drivers/staging/sm7xx/smtcfb.c | 2 +- include/linux/pci.h | 8 +++----- sound/pci/cs5535audio/cs5535audio_pm.c | 7 +------ 13 files changed, 22 insertions(+), 66 deletions(-) (limited to 'sound/pci') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 0dfff50891e4..737bb877e962 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2186,9 +2186,7 @@ static int cafe_pci_resume(struct pci_dev *pdev) struct cafe_camera *cam = to_cam(v4l2_dev); int ret = 0; - ret = pci_restore_state(pdev); - if (ret) - return ret; + pci_restore_state(pdev); ret = pci_enable_device(pdev); if (ret) { diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 8524cc40ec57..d3c4a374a92e 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -3403,9 +3403,7 @@ static int myri10ge_resume(struct pci_dev *pdev) return -EIO; } - status = pci_restore_state(pdev); - if (status) - return status; + pci_restore_state(pdev); status = pci_enable_device(pdev); if (status) { diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 267019bb2b15..1763b9a7fd8e 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1066,22 +1066,9 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) /* Restore PCI configuration if needed */ if (method == RESET_TYPE_WORLD) { - if (efx_nic_is_dual_func(efx)) { - rc = pci_restore_state(nic_data->pci_dev2); - if (rc) { - netif_err(efx, drv, efx->net_dev, - "failed to restore PCI config for " - "the secondary function\n"); - goto fail3; - } - } - rc = pci_restore_state(efx->pci_dev); - if (rc) { - netif_err(efx, drv, efx->net_dev, - "failed to restore PCI config for the " - "primary function\n"); - goto fail4; - } + if (efx_nic_is_dual_func(efx)) + pci_restore_state(nic_data->pci_dev2); + pci_restore_state(efx->pci_dev); netif_dbg(efx, drv, efx->net_dev, "successfully restored PCI config\n"); } @@ -1092,7 +1079,7 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) rc = -ETIMEDOUT; netif_err(efx, hw, efx->net_dev, "timed out waiting for hardware reset\n"); - goto fail5; + goto fail3; } netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n"); @@ -1100,11 +1087,9 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) /* pci_save_state() and pci_restore_state() MUST be called in pairs */ fail2: -fail3: pci_restore_state(efx->pci_dev); fail1: -fail4: -fail5: +fail3: return rc; } diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 220e0398f1d5..61553af38e65 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -4087,9 +4087,7 @@ static int skge_resume(struct pci_dev *pdev) if (err) goto out; - err = pci_restore_state(pdev); - if (err) - goto out; + pci_restore_state(pdev); err = skge_reset(hw); if (err) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d6577084ce70..be3aee782760 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4969,10 +4969,7 @@ static int sky2_resume(struct pci_dev *pdev) if (err) goto out; - err = pci_restore_state(pdev); - if (err) - goto out; - + pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); /* Re-enable all clocks */ diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 2449d785cf8d..4fd4c33de6ae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -356,12 +356,12 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) struct rt2x00_dev *rt2x00dev = hw->priv; if (pci_set_power_state(pci_dev, PCI_D0) || - pci_enable_device(pci_dev) || - pci_restore_state(pci_dev)) { + pci_enable_device(pci_dev)) { ERROR(rt2x00dev, "Failed to resume device.\n"); return -EIO; } + pci_restore_state(pci_dev); return rt2x00lib_resume(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00pci_resume); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8a6f797de8e5..80e551ee640b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -449,7 +449,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) return error; } - return pci_restore_state(pci_dev); + pci_restore_state(pci_dev); + return 0; } static void pci_pm_default_resume_early(struct pci_dev *pci_dev) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 710c8a29be0d..6762dcae90ab 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -937,14 +937,13 @@ pci_save_state(struct pci_dev *dev) * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with */ -int -pci_restore_state(struct pci_dev *dev) +void pci_restore_state(struct pci_dev *dev) { int i; u32 val; if (!dev->state_saved) - return 0; + return; /* PCI Express register must be restored first */ pci_restore_pcie_state(dev); @@ -968,8 +967,6 @@ pci_restore_state(struct pci_dev *dev) pci_restore_iov_state(dev); dev->state_saved = false; - - return 0; } static int do_pci_enable_device(struct pci_dev *dev, int bars) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 5bbaee597e88..524d586c3147 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -7487,16 +7487,10 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; volatile u32 int_reg; - int rc; ENTER; ioa_cfg->pdev->state_saved = true; - rc = pci_restore_state(ioa_cfg->pdev); - - if (rc != PCIBIOS_SUCCESSFUL) { - ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); - return IPR_RC_JOB_CONTINUE; - } + pci_restore_state(ioa_cfg->pdev); if (ipr_set_pcix_cmd_reg(ioa_cfg)) { ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 300d59f389da..321cf3ae8630 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -2228,12 +2228,7 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd) /* Once either bist or pci reset is done, restore PCI config * space. If this fails, proceed with hard reset again */ - if (pci_restore_state(pinstance->pdev)) { - pmcraid_info("config-space error resetting again\n"); - pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; - pmcraid_reset_alert(cmd); - break; - } + pci_restore_state(pinstance->pdev); /* fail all pending commands */ pmcraid_fail_outstanding_cmds(pinstance); diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 24f47d6388f4..7162dee3b0d8 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -1071,7 +1071,7 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev) /* when resuming, restore pci data and fb cursor */ if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { retv = pci_set_power_state(pdev, PCI_D0); - retv = pci_restore_state(pdev); + pci_restore_state(pdev); if (pci_enable_device(pdev)) return -1; pci_set_master(pdev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 7454408c41b6..63cbadce337e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -806,7 +806,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); -int pci_restore_state(struct pci_dev *dev); +void pci_restore_state(struct pci_dev *dev); int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state); int pci_set_power_state(struct pci_dev *dev, pci_power_t state); pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); @@ -1168,10 +1168,8 @@ static inline int pci_save_state(struct pci_dev *dev) return 0; } -static inline int pci_restore_state(struct pci_dev *dev) -{ - return 0; -} +static inline void pci_restore_state(struct pci_dev *dev) +{ } static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index a3301cc4ab82..185b00088320 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c @@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci) int i; pci_set_power_state(pci, PCI_D0); - if (pci_restore_state(pci) < 0) { - printk(KERN_ERR "cs5535audio: pci_restore_state failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_restore_state(pci); if (pci_enable_device(pci) < 0) { printk(KERN_ERR "cs5535audio: pci_enable_device failed, " "disabling device\n"); -- cgit v1.2.3 From c521dde6a690721a1db17924ef5683864ff58fdb Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 27 Dec 2010 15:09:53 +0100 Subject: sound, ca0106: Fix assignment to 'channel'. The assignment to the local variable 'channel' in snd_ca0106_pcm_pointer_capture() is a little crazy. Order of assignment is undefined. This fixes it. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- sound/pci/ca0106/ca0106_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index d2d12c08f937..01b49388fafd 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1082,7 +1082,7 @@ snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ca0106_pcm *epcm = runtime->private_data; snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; - int channel = channel=epcm->channel_id; + int channel = epcm->channel_id; if (!epcm->running) return 0; -- cgit v1.2.3 From e03fa055bc126e536c7f65862e08a9b143138ea9 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Tue, 28 Dec 2010 17:20:02 -0500 Subject: ALSA: hda: Use LPIB quirk for Dell Inspiron m101z/1120 Sjoerd Simons reports that, without using position_fix=1, recording experiences overruns. Work around that by applying the LPIB quirk for his hardware. Reported-and-tested-by: Sjoerd Simons Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b030c8eba21f..a1c4008af891 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2300,6 +2300,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB), SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), -- 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 From 74dc8909c1ce38098e6689239ed6ae6b6bf9f92b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Jan 2011 14:14:41 +0100 Subject: ALSA: hda - Remove unused fixup entry for ALC262 ... and a minor cleanup. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 98c9cd8f6471..738d5d8962d0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12453,12 +12453,6 @@ static const struct alc_fixup alc262_fixups[] = { { } } }, - [PINFIX_PB_M5210] = { - .verbs = (const struct hda_verb[]) { - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, - {} - } - }, }; static struct snd_pci_quirk alc262_fixup_tbl[] = { @@ -14826,7 +14820,7 @@ static void alc269_fixup_hweq(struct hda_codec *codec, enum { ALC269_FIXUP_SONY_VAIO, - ALC275_FIX_SONY_VAIO_GPIO2, + ALC275_FIXUP_SONY_VAIO_GPIO2, ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, @@ -14841,7 +14835,7 @@ static const struct alc_fixup alc269_fixups[] = { {} } }, - [ALC275_FIX_SONY_VAIO_GPIO2] = { + [ALC275_FIXUP_SONY_VAIO_GPIO2] = { .verbs = (const struct hda_verb[]) { {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, @@ -14886,7 +14880,7 @@ static const struct alc_fixup alc269_fixups[] = { }; static struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), + SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_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), -- cgit v1.2.3 From 6fc398cb306b0441436c93d6ddead3109b99f884 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Jan 2011 14:36:37 +0100 Subject: ALSA: hda - Apply mario fixup only once The amp-override is necessary only once at initialization time. Also fixed a coding style issue. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 738d5d8962d0..f13920e53847 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19366,7 +19366,10 @@ static void alc662_auto_init(struct hda_codec *codec) } static void alc272_fixup_mario(struct hda_codec *codec, - const struct alc_fixup *fix, int pre_init) { + const struct alc_fixup *fix, int pre_init) +{ + if (!pre_init) + return; if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, (0x3b << AC_AMPCAP_OFFSET_SHIFT) | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | -- cgit v1.2.3 From 9fb1ef25f4d31f07cdaf7c6075b40bbcb00c1f92 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Jan 2011 14:40:43 +0100 Subject: ALSA: hda - Apply Sony VAIO hweq fixup only once This should be applied also only once as a part of the initialization. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f13920e53847..98b4b2e1b930 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14814,6 +14814,8 @@ static void alc269_fixup_hweq(struct hda_codec *codec, { int coef; + if (pre_init) + return; coef = alc_read_coef_idx(codec, 0x1e); alc_write_coef_idx(codec, 0x1e, coef | 0x80); } -- cgit v1.2.3 From b5bfbc670283d1ff21df4cd3f9f036cc47e34ce4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Jan 2011 14:22:32 +0100 Subject: ALSA: hda - Reorganize fixup structure for Realtek Instead of keeping various data types in a single record, put the type field and keep a single value in each entry, but allows chaining multiple fixup entries. This allows more flexible data management (see ALC275_FIXUP_SONY_HWEQ for example). Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 317 +++++++++++++++++++++++++----------------- 1 file changed, 193 insertions(+), 124 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 98b4b2e1b930..a06c9437cdeb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -303,6 +303,8 @@ struct alc_customize_define { unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ }; +struct alc_fixup; + struct alc_spec { /* codec parameterization */ struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ @@ -404,6 +406,11 @@ struct alc_spec { /* for PLL fix */ hda_nid_t pll_nid; unsigned int pll_coef_idx, pll_coef_bit; + + /* fix-up list */ + int fixup_id; + const struct alc_fixup *fixup_list; + const char *fixup_name; }; /* @@ -1683,88 +1690,130 @@ struct alc_model_fixup { }; 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); + int type; + union { + 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 action); + } v; + bool chained; + int chain_id; }; -static void __alc_pick_fixup(struct hda_codec *codec, - const struct alc_fixup *fix, - const char *modelname, - int pre_init) +enum { + ALC_FIXUP_INVALID, + ALC_FIXUP_SKU, + ALC_FIXUP_PINS, + ALC_FIXUP_VERBS, + ALC_FIXUP_FUNC, +}; + +enum { + ALC_FIXUP_ACT_PRE_PROBE, + ALC_FIXUP_ACT_PROBE, +}; + +static void alc_apply_fixup(struct hda_codec *codec, int action) { - const struct alc_pincfg *cfg; - struct alc_spec *spec; + struct alc_spec *spec = codec->spec; + int id = spec->fixup_id; + const char *modelname = spec->fixup_name; + int depth = 0; - 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, modelname); -#endif - spec = codec->spec; - spec->cdefine.sku_cfg = fix->sku; - spec->cdefine.fixup = 1; - } - if (pre_init && cfg) { -#ifdef CONFIG_SND_DEBUG_VERBOSE - snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", - codec->chip_name, modelname); -#endif - for (; cfg->nid; cfg++) - snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); - } - 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, 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, modelname); -#endif - fix->func(codec, fix, pre_init); + if (!spec->fixup_list) + return; + + while (id >= 0) { + const struct alc_fixup *fix = spec->fixup_list + id; + const struct alc_pincfg *cfg; + + switch (fix->type) { + case ALC_FIXUP_SKU: + if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) + break;; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply sku override for %s\n", + codec->chip_name, modelname); + spec->cdefine.sku_cfg = fix->v.sku; + spec->cdefine.fixup = 1; + break; + case ALC_FIXUP_PINS: + cfg = fix->v.pins; + if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg) + break; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply pincfg for %s\n", + codec->chip_name, modelname); + for (; cfg->nid; cfg++) + snd_hda_codec_set_pincfg(codec, cfg->nid, + cfg->val); + break; + case ALC_FIXUP_VERBS: + if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) + break; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply fix-verbs for %s\n", + codec->chip_name, modelname); + add_verb(codec->spec, fix->v.verbs); + break; + case ALC_FIXUP_FUNC: + if (!fix->v.func) + break; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply fix-func for %s\n", + codec->chip_name, modelname); + fix->v.func(codec, fix, action); + break; + default: + snd_printk(KERN_ERR "hda_codec: %s: " + "Invalid fixup type %d\n", + codec->chip_name, fix->type); + break; + } + if (!fix[id].chained) + break; + if (++depth > 10) + break; + id = fix[id].chain_id; } } static void alc_pick_fixup(struct hda_codec *codec, - const struct snd_pci_quirk *quirk, - const struct alc_fixup *fix, - int pre_init) + const struct alc_model_fixup *models, + const struct snd_pci_quirk *quirk, + const struct alc_fixup *fixlist) { - 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 - } -} + struct alc_spec *spec = codec->spec; + int id = -1; + const char *name = NULL; -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; + id = models->id; + name = models->name; break; } models++; } - __alc_pick_fixup(codec, fix, codec->modelname, pre_init); - } else { - alc_pick_fixup(codec, quirk, fix, pre_init); + } + if (id < 0) { + quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); + if (quirk) { + id = quirk->value; +#ifdef CONFIG_SND_DEBUG_VERBOSE + name = quirk->name; +#endif + } + } + + spec->fixup_id = id; + if (id >= 0) { + spec->fixup_list = fixlist; + spec->fixup_name = name; } } @@ -7090,7 +7139,8 @@ enum { static const struct alc_fixup alc260_fixups[] = { [PINFIX_HP_DC5750] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x11, 0x90130110 }, /* speaker */ { } } @@ -7301,8 +7351,10 @@ static int patch_alc260(struct hda_codec *codec) board_config = ALC260_AUTO; } - if (board_config == ALC260_AUTO) - alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); + if (board_config == ALC260_AUTO) { + alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC260_AUTO) { /* automatic parse from the BIOS config */ @@ -7350,8 +7402,7 @@ static int patch_alc260(struct hda_codec *codec) set_capture_mixer(codec); set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); - if (board_config == ALC260_AUTO) - alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x08; @@ -10678,7 +10729,8 @@ enum { static const struct alc_fixup alc882_fixups[] = { [PINFIX_ABIT_AW9D_MAX] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x15, 0x01080104 }, /* side */ { 0x16, 0x01011012 }, /* rear */ { 0x17, 0x01016011 }, /* clfe */ @@ -10686,13 +10738,15 @@ static const struct alc_fixup alc882_fixups[] = { } }, [PINFIX_PB_M5210] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, {} } }, [PINFIX_ACER_ASPIRE_7736] = { - .sku = ALC_FIXUP_SKU_IGNORE, + .type = ALC_FIXUP_SKU, + .v.sku = ALC_FIXUP_SKU_IGNORE, }, }; @@ -10978,8 +11032,10 @@ static int patch_alc882(struct hda_codec *codec) board_config = ALC882_AUTO; } - if (board_config == ALC882_AUTO) - alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); + if (board_config == ALC882_AUTO) { + alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } alc_auto_parse_customize_define(codec); @@ -11055,8 +11111,7 @@ static int patch_alc882(struct hda_codec *codec) if (has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); - if (board_config == ALC882_AUTO) - alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x0c; @@ -12446,7 +12501,8 @@ enum { static const struct alc_fixup alc262_fixups[] = { [PINFIX_FSC_H270] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x0221142f }, /* front HP */ { 0x1b, 0x0121141f }, /* rear HP */ @@ -12883,8 +12939,10 @@ static int patch_alc262(struct hda_codec *codec) board_config = ALC262_AUTO; } - if (board_config == ALC262_AUTO) - alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1); + if (board_config == ALC262_AUTO) { + alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC262_AUTO) { /* automatic parse from the BIOS config */ @@ -12954,8 +13012,7 @@ static int patch_alc262(struct hda_codec *codec) if (!spec->no_analog && has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); - if (board_config == ALC262_AUTO) - alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x0c; @@ -14810,11 +14867,11 @@ 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) + const struct alc_fixup *fix, int action) { int coef; - if (pre_init) + if (action != ALC_FIXUP_ACT_PROBE) return; coef = alc_read_coef_idx(codec, 0x1e); alc_write_coef_idx(codec, 0x1e, coef | 0x80); @@ -14832,22 +14889,26 @@ enum { static const struct alc_fixup alc269_fixups[] = { [ALC269_FIXUP_SONY_VAIO] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, {} } }, [ALC275_FIXUP_SONY_VAIO_GPIO2] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.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}, { } - } + }, + .chained = true, + .chain_id = ALC269_FIXUP_SONY_VAIO }, [ALC269_FIXUP_DELL_M101Z] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { /* Enables internal speaker */ {0x20, AC_VERB_SET_COEF_INDEX, 13}, {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, @@ -14855,29 +14916,28 @@ static const struct alc_fixup alc269_fixups[] = { } }, [ALC269_FIXUP_SKU_IGNORE] = { - .sku = ALC_FIXUP_SKU_IGNORE, + .type = ALC_FIXUP_SKU, + .v.sku = ALC_FIXUP_SKU_IGNORE, }, [ALC269_FIXUP_ASUS_G73JW] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x17, 0x99130111 }, /* subwoofer */ { } } }, [ALC269_FIXUP_LENOVO_EAPD] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, {} } }, [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}, - { } - } + .type = ALC_FIXUP_FUNC, + .v.func = alc269_fixup_hweq, + .chained = true, + .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 } }; @@ -15174,8 +15234,10 @@ static int patch_alc269(struct hda_codec *codec) board_config = ALC269_AUTO; } - if (board_config == ALC269_AUTO) - alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); + if (board_config == ALC269_AUTO) { + alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC269_AUTO) { /* automatic parse from the BIOS config */ @@ -15236,8 +15298,7 @@ static int patch_alc269(struct hda_codec *codec) if (has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); - if (board_config == ALC269_AUTO) - alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x02; @@ -16296,7 +16357,8 @@ enum { static const struct alc_fixup alc861_fixups[] = { [PINFIX_FSC_AMILO_PI1505] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x0b, 0x0221101f }, /* HP */ { 0x0f, 0x90170310 }, /* speaker */ { } @@ -16331,8 +16393,10 @@ static int patch_alc861(struct hda_codec *codec) board_config = ALC861_AUTO; } - if (board_config == ALC861_AUTO) - alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); + if (board_config == ALC861_AUTO) { + alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC861_AUTO) { /* automatic parse from the BIOS config */ @@ -16369,8 +16433,7 @@ static int patch_alc861(struct hda_codec *codec) spec->vmaster_nid = 0x03; - if (board_config == ALC861_AUTO) - alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; if (board_config == ALC861_AUTO) { @@ -17252,7 +17315,8 @@ enum { /* reset GPIO1 */ static const struct alc_fixup alc861vd_fixups[] = { [ALC660VD_FIX_ASUS_GPIO1] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, @@ -17287,8 +17351,10 @@ static int patch_alc861vd(struct hda_codec *codec) board_config = ALC861VD_AUTO; } - if (board_config == ALC861VD_AUTO) - alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); + if (board_config == ALC861VD_AUTO) { + alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC861VD_AUTO) { /* automatic parse from the BIOS config */ @@ -17336,8 +17402,7 @@ static int patch_alc861vd(struct hda_codec *codec) spec->vmaster_nid = 0x02; - if (board_config == ALC861VD_AUTO) - alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; @@ -19368,9 +19433,9 @@ static void alc662_auto_init(struct hda_codec *codec) } static void alc272_fixup_mario(struct hda_codec *codec, - const struct alc_fixup *fix, int pre_init) + const struct alc_fixup *fix, int action) { - if (!pre_init) + if (action != ALC_FIXUP_ACT_PROBE) return; if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, (0x3b << AC_AMPCAP_OFFSET_SHIFT) | @@ -19389,19 +19454,22 @@ enum { static const struct alc_fixup alc662_fixups[] = { [ALC662_FIXUP_ASPIRE] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x15, 0x99130112 }, /* subwoofer */ { } } }, [ALC662_FIXUP_IDEAPAD] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x17, 0x99130112 }, /* subwoofer */ { } } }, [ALC272_FIXUP_MARIO] = { - .func = alc272_fixup_mario, + .type = ALC_FIXUP_FUNC, + .v.func = alc272_fixup_mario, } }; @@ -19455,7 +19523,9 @@ static int patch_alc662(struct hda_codec *codec) } if (board_config == ALC662_AUTO) { - alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1); + alc_pick_fixup(codec, alc662_fixup_models, + alc662_fixup_tbl, alc662_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); /* automatic parse from the BIOS config */ err = alc662_parse_auto_config(codec); if (err < 0) { @@ -19513,12 +19583,11 @@ static int patch_alc662(struct hda_codec *codec) } spec->vmaster_nid = 0x02; + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + codec->patch_ops = alc_patch_ops; - if (board_config == ALC662_AUTO) { + if (board_config == ALC662_AUTO) spec->init_hook = alc662_auto_init; - alc_pick_fixup_model(codec, alc662_fixup_models, - alc662_fixup_tbl, alc662_fixups, 0); - } alc_init_jacks(codec); -- cgit v1.2.3 From 5870112021fb38e73b25dad3baec4ca0819c594a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Jan 2011 15:41:45 +0100 Subject: ALSA: hda - Add fixup-call in init callback In some cases, the fix-up is required in the init callback to be called both at the first initialization and at the resume. The new action type ALC_FIXUP_ACT_INIT is used for this case. So far, only ALC275_FIXUP_SONY_HWEQ uses this. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a06c9437cdeb..b445ae989421 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1714,6 +1714,7 @@ enum { enum { ALC_FIXUP_ACT_PRE_PROBE, ALC_FIXUP_ACT_PROBE, + ALC_FIXUP_ACT_INIT, }; static void alc_apply_fixup(struct hda_codec *codec, int action) @@ -3910,6 +3911,8 @@ static int alc_init(struct hda_codec *codec) if (spec->init_hook) spec->init_hook(codec); + alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); + hda_call_check_power_status(codec, 0x01); return 0; } @@ -14871,7 +14874,7 @@ static void alc269_fixup_hweq(struct hda_codec *codec, { int coef; - if (action != ALC_FIXUP_ACT_PROBE) + if (action != ALC_FIXUP_ACT_INIT) return; coef = alc_read_coef_idx(codec, 0x1e); alc_write_coef_idx(codec, 0x1e, coef | 0x80); -- cgit v1.2.3 From ad09fc9d2156f3d37537b34418a6b79309013d33 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 14 Jan 2011 09:42:27 +0100 Subject: ALSA: hda - Suppress the odd number of channels for HDMI It looks like that HDMI codecs don't support the odd number of channels although HD-audio spec doesn't have the restriction. Add the hw_constraint to limit to only the even number of channels. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index f29b97b5de8f..2d288793ceb3 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1238,6 +1238,9 @@ static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo, snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, hw_constraints_channels); + } else { + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, 2); } return snd_hda_multi_out_dig_open(codec, &spec->multiout); -- cgit v1.2.3 From f8fe80e4383bf5f542beb80bf2abe9fc1505c366 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 14 Jan 2011 08:07:50 +0100 Subject: ALSA: oxygen: Xonar DG: fix CS4245 register writes Accidentally exchanging register addresses and register values leads to many strange errors ... 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 e4de0b8d087a..e1fa602eba79 100644 --- a/sound/pci/oxygen/xonar_dg.c +++ b/sound/pci/oxygen/xonar_dg.c @@ -75,7 +75,7 @@ static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value) OXYGEN_SPI_CEN_LATCH_CLOCK_HI, CS4245_SPI_ADDRESS | CS4245_SPI_WRITE | - (value << 8) | reg); + (reg << 8) | value); data->cs4245_regs[reg] = value; } -- cgit v1.2.3 From 361fe6e90888af83d5bfdfc152d737018cbede43 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 14 Jan 2011 09:55:32 +0100 Subject: ALSA: hda - Rearrange fixup struct in patch_realtek.c Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b445ae989421..69554061c16e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1691,6 +1691,8 @@ struct alc_model_fixup { struct alc_fixup { int type; + bool chained; + int chain_id; union { unsigned int sku; const struct alc_pincfg *pins; @@ -1699,8 +1701,6 @@ struct alc_fixup { const struct alc_fixup *fix, int action); } v; - bool chained; - int chain_id; }; enum { -- cgit v1.2.3 From 639cef0eb6df05d5516520aa89b0c9fe62ee2d3b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 14 Jan 2011 10:30:46 +0100 Subject: ALSA: hda - Store PCM parameters properly in HDMI open callback In hdmi_pcm_open(), the evaluated PCM hw parameters are stored in hinfo, but these aren't properly set back to the current runtime record since these have been set beforehand in azx_pcm_open(). This patch fixes the behavior. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 2d288793ceb3..5980552f5970 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -817,6 +817,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, struct hdmi_spec *spec = codec->spec; struct hdmi_eld *eld; struct hda_pcm_stream *codec_pars; + struct snd_pcm_runtime *runtime = substream->runtime; unsigned int idx; for (idx = 0; idx < spec->num_cvts; idx++) @@ -844,6 +845,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, hinfo->formats = codec_pars->formats; hinfo->maxbps = codec_pars->maxbps; } + /* store the updated parameters */ + runtime->hw.channels_min = hinfo->channels_min; + runtime->hw.channels_max = hinfo->channels_max; + runtime->hw.formats = hinfo->formats; + runtime->hw.rates = hinfo->rates; return 0; } -- cgit v1.2.3 From 4fe2ca14678174d9df254ae3ba2b79bacc19e2ee Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 14 Jan 2011 10:33:26 +0100 Subject: ALSA: hda - More coverage for odd-number channels elimination for HDMI The commit ad09fc9d2156f3d37537b34418a6b79309013d33 didn't cover the case for Intel and Nvidia HDMIs, where hdmi_pcm_open() is called. Put the hw_constraint there, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 5980552f5970..2d5b83fa8d24 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -850,6 +850,9 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, runtime->hw.channels_max = hinfo->channels_max; runtime->hw.formats = hinfo->formats; runtime->hw.rates = hinfo->rates; + + snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, 2); return 0; } -- cgit v1.2.3 From 3e8b3b90fecedcf20d895c4e6ad01a379fe252bf Mon Sep 17 00:00:00 2001 From: Hanno Boeck Date: Fri, 14 Jan 2011 19:14:47 +0100 Subject: ALSA: constify functions in ac97 Signed-off-by: Hanno Boeck Signed-off-by: Takashi Iwai --- include/sound/ac97_codec.h | 2 +- sound/pci/ac97/ac97_codec.c | 2 +- sound/pci/ac97/ac97_patch.c | 62 ++++++++++++++++++++++----------------------- 3 files changed, 33 insertions(+), 33 deletions(-) (limited to 'sound/pci') diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index 49400459b477..b602f475cdbb 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h @@ -477,7 +477,7 @@ struct snd_ac97_template { struct snd_ac97 { /* -- lowlevel (hardware) driver specific -- */ - struct snd_ac97_build_ops * build_ops; + const struct snd_ac97_build_ops *build_ops; void *private_data; void (*private_free) (struct snd_ac97 *ac97); /* --- */ diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 0fc614ce16c1..cb62d178b3e0 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1961,7 +1961,7 @@ static int snd_ac97_dev_disconnect(struct snd_device *device) } /* build_ops to do nothing */ -static struct snd_ac97_build_ops null_build_ops; +static const struct snd_ac97_build_ops null_build_ops; #ifdef CONFIG_SND_AC97_POWER_SAVE static void do_update_power(struct work_struct *work) diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index e68c98ef4041..bf47574ca1f0 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -371,7 +371,7 @@ static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97) return 0; } -static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { +static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { .build_spdif = patch_yamaha_ymf743_build_spdif, .build_3d = patch_yamaha_ymf7x3_3d, }; @@ -455,7 +455,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { +static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { .build_3d = patch_yamaha_ymf7x3_3d, .build_post_spdif = patch_yamaha_ymf753_post_spdif }; @@ -502,7 +502,7 @@ static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { +static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { .build_specific = patch_wolfson_wm9703_specific, }; @@ -533,7 +533,7 @@ static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { +static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { .build_specific = patch_wolfson_wm9704_specific, }; @@ -677,7 +677,7 @@ static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { +static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { .build_specific = patch_wolfson_wm9711_specific, }; @@ -871,7 +871,7 @@ static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97) } #endif -static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { +static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { .build_specific = patch_wolfson_wm9713_specific, .build_3d = patch_wolfson_wm9713_3d, #ifdef CONFIG_PM @@ -976,7 +976,7 @@ static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { +static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { .build_3d = patch_sigmatel_stac9700_3d, .build_specific = patch_sigmatel_stac97xx_specific }; @@ -1023,7 +1023,7 @@ static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97) return patch_sigmatel_stac97xx_specific(ac97); } -static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { +static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { .build_3d = patch_sigmatel_stac9708_3d, .build_specific = patch_sigmatel_stac9708_specific }; @@ -1252,7 +1252,7 @@ static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97) return 0; } -static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { +static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { .build_3d = patch_sigmatel_stac9700_3d, .build_specific = patch_sigmatel_stac9758_specific }; @@ -1327,7 +1327,7 @@ static int patch_cirrus_build_spdif(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_cirrus_ops = { +static const struct snd_ac97_build_ops patch_cirrus_ops = { .build_spdif = patch_cirrus_build_spdif }; @@ -1384,7 +1384,7 @@ static int patch_conexant_build_spdif(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_conexant_ops = { +static const struct snd_ac97_build_ops patch_conexant_ops = { .build_spdif = patch_conexant_build_spdif }; @@ -1560,7 +1560,7 @@ static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int } } -static struct snd_ac97_build_ops patch_ad1881_build_ops = { +static const struct snd_ac97_build_ops patch_ad1881_build_ops = { #ifdef CONFIG_PM .resume = ad18xx_resume #endif @@ -1647,7 +1647,7 @@ static int patch_ad1885_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_ad1885_build_ops = { +static const struct snd_ac97_build_ops patch_ad1885_build_ops = { .build_specific = &patch_ad1885_specific, #ifdef CONFIG_PM .resume = ad18xx_resume @@ -1674,7 +1674,7 @@ static int patch_ad1886_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_ad1886_build_ops = { +static const struct snd_ac97_build_ops patch_ad1886_build_ops = { .build_specific = &patch_ad1886_specific, #ifdef CONFIG_PM .resume = ad18xx_resume @@ -1881,7 +1881,7 @@ static int patch_ad1981a_specific(struct snd_ac97 * ac97) ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); } -static struct snd_ac97_build_ops patch_ad1981a_build_ops = { +static const struct snd_ac97_build_ops patch_ad1981a_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1981a_specific, #ifdef CONFIG_PM @@ -1936,7 +1936,7 @@ static int patch_ad1981b_specific(struct snd_ac97 *ac97) ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); } -static struct snd_ac97_build_ops patch_ad1981b_build_ops = { +static const struct snd_ac97_build_ops patch_ad1981b_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1981b_specific, #ifdef CONFIG_PM @@ -2075,7 +2075,7 @@ static int patch_ad1888_specific(struct snd_ac97 *ac97) return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); } -static struct snd_ac97_build_ops patch_ad1888_build_ops = { +static const struct snd_ac97_build_ops patch_ad1888_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1888_specific, #ifdef CONFIG_PM @@ -2124,7 +2124,7 @@ static int patch_ad1980_specific(struct snd_ac97 *ac97) return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); } -static struct snd_ac97_build_ops patch_ad1980_build_ops = { +static const struct snd_ac97_build_ops patch_ad1980_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1980_specific, #ifdef CONFIG_PM @@ -2239,7 +2239,7 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97) ARRAY_SIZE(snd_ac97_ad1985_controls)); } -static struct snd_ac97_build_ops patch_ad1985_build_ops = { +static const struct snd_ac97_build_ops patch_ad1985_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1985_specific, #ifdef CONFIG_PM @@ -2531,7 +2531,7 @@ static int patch_ad1986_specific(struct snd_ac97 *ac97) ARRAY_SIZE(snd_ac97_ad1985_controls)); } -static struct snd_ac97_build_ops patch_ad1986_build_ops = { +static const struct snd_ac97_build_ops patch_ad1986_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1986_specific, #ifdef CONFIG_PM @@ -2636,7 +2636,7 @@ static int patch_alc650_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_alc650_ops = { +static const struct snd_ac97_build_ops patch_alc650_ops = { .build_specific = patch_alc650_specific, .update_jacks = alc650_update_jacks }; @@ -2788,7 +2788,7 @@ static int patch_alc655_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_alc655_ops = { +static const struct snd_ac97_build_ops patch_alc655_ops = { .build_specific = patch_alc655_specific, .update_jacks = alc655_update_jacks }; @@ -2900,7 +2900,7 @@ static int patch_alc850_specific(struct snd_ac97 *ac97) return 0; } -static struct snd_ac97_build_ops patch_alc850_ops = { +static const struct snd_ac97_build_ops patch_alc850_ops = { .build_specific = patch_alc850_specific, .update_jacks = alc850_update_jacks }; @@ -2962,7 +2962,7 @@ static int patch_cm9738_specific(struct snd_ac97 * ac97) return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls)); } -static struct snd_ac97_build_ops patch_cm9738_ops = { +static const struct snd_ac97_build_ops patch_cm9738_ops = { .build_specific = patch_cm9738_specific, .update_jacks = cm9738_update_jacks }; @@ -3053,7 +3053,7 @@ static int patch_cm9739_post_spdif(struct snd_ac97 * ac97) return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif)); } -static struct snd_ac97_build_ops patch_cm9739_ops = { +static const struct snd_ac97_build_ops patch_cm9739_ops = { .build_specific = patch_cm9739_specific, .build_post_spdif = patch_cm9739_post_spdif, .update_jacks = cm9739_update_jacks @@ -3227,7 +3227,7 @@ static int patch_cm9761_specific(struct snd_ac97 * ac97) return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls)); } -static struct snd_ac97_build_ops patch_cm9761_ops = { +static const struct snd_ac97_build_ops patch_cm9761_ops = { .build_specific = patch_cm9761_specific, .build_post_spdif = patch_cm9761_post_spdif, .update_jacks = cm9761_update_jacks @@ -3323,7 +3323,7 @@ static int patch_cm9780_specific(struct snd_ac97 *ac97) return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls)); } -static struct snd_ac97_build_ops patch_cm9780_ops = { +static const struct snd_ac97_build_ops patch_cm9780_ops = { .build_specific = patch_cm9780_specific, .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ }; @@ -3443,7 +3443,7 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_vt1616_ops = { +static const struct snd_ac97_build_ops patch_vt1616_ops = { .build_specific = patch_vt1616_specific }; @@ -3797,7 +3797,7 @@ static int patch_it2646_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_it2646_ops = { +static const struct snd_ac97_build_ops patch_it2646_ops = { .build_specific = patch_it2646_specific, .update_jacks = it2646_update_jacks }; @@ -3831,7 +3831,7 @@ static int patch_si3036_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_si3036_ops = { +static const struct snd_ac97_build_ops patch_si3036_ops = { .build_specific = patch_si3036_specific, }; @@ -3898,7 +3898,7 @@ static int patch_ucb1400_specific(struct snd_ac97 * ac97) return 0; } -static struct snd_ac97_build_ops patch_ucb1400_ops = { +static const struct snd_ac97_build_ops patch_ucb1400_ops = { .build_specific = patch_ucb1400_specific, }; -- cgit v1.2.3 From d9ab344336f74c012f6643ed3d1ad8ca0136de3b Mon Sep 17 00:00:00 2001 From: Raymond Yau Date: Sun, 16 Jan 2011 10:55:54 +0800 Subject: ALSA : au88x0 - Limit number of channels to fix Oops via OSS emu Fix playback/capture channels patch to change supported playback channels of au8830 to 1,2,4 and capture channels to 1,2. This prevent oops when oss emulation use SNDCTL_DSP_CHANNELS to set 3 Channels Signed-off-by: Raymond Yau Cc: Signed-off-by: Takashi Iwai --- sound/pci/au88x0/au88x0_pcm.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index b9d2f202cf9b..5439d662d104 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -42,11 +42,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = { .rate_min = 5000, .rate_max = 48000, .channels_min = 1, -#ifdef CHIP_AU8830 - .channels_max = 4, -#else .channels_max = 2, -#endif .buffer_bytes_max = 0x10000, .period_bytes_min = 0x1, .period_bytes_max = 0x1000, @@ -115,6 +111,17 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_wt = { .periods_max = 64, }; #endif +#ifdef CHIP_AU8830 +static unsigned int au8830_channels[3] = { + 1, 2, 4, +}; + +static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = { + .count = ARRAY_SIZE(au8830_channels), + .list = au8830_channels, + .mask = 0, +}; +#endif /* open callback */ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) { @@ -156,6 +163,15 @@ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S) runtime->hw = snd_vortex_playback_hw_adb; +#ifdef CHIP_AU8830 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && + VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) { + runtime->hw.channels_max = 4; + snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &hw_constraints_au8830_channels); + } +#endif substream->runtime->private_data = NULL; } #ifndef CHIP_AU8810 -- cgit v1.2.3 From c66ddf32dda0d5bcf9db7b4cc42ef5da7baadd3e Mon Sep 17 00:00:00 2001 From: Raymond Yau Date: Mon, 17 Jan 2011 11:19:03 +0100 Subject: ALSA: hda - Add add multi-streaming playback for AD1988 Attached a patch which add a new model to support multi-streaming playback for ad1988. playback another stereo stream through the front panel headphone on device 2 while playback through the speakers connected to rear panel on device 0 at the same time. Tested with ad1988a rev2 codec on asus P5B-V motherboard. Signed-off-by: Raymond Yau Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 182 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 178 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 46780670162b..34ee1169f2e0 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -46,6 +46,9 @@ struct ad198x_spec { unsigned int cur_eapd; unsigned int need_dac_fix; + hda_nid_t *alt_dac_nid; + struct hda_pcm_stream *stream_analog_alt_playback; + /* capture */ unsigned int num_adc_nids; hda_nid_t *adc_nids; @@ -156,6 +159,25 @@ static const char *ad_slave_sws[] = { NULL }; +static const char *ad1988_6stack_fp_slave_vols[] = { + "Front Playback Volume", + "Surround Playback Volume", + "Center Playback Volume", + "LFE Playback Volume", + "Side Playback Volume", + "IEC958 Playback Volume", + NULL +}; + +static const char *ad1988_6stack_fp_slave_sws[] = { + "Front Playback Switch", + "Surround Playback Switch", + "Center Playback Switch", + "LFE Playback Switch", + "Side Playback Switch", + "IEC958 Playback Switch", + NULL +}; static void ad198x_free_kctls(struct hda_codec *codec); #ifdef CONFIG_SND_HDA_INPUT_BEEP @@ -309,6 +331,38 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); } +static int ad198x_alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct ad198x_spec *spec = codec->spec; + snd_hda_codec_setup_stream(codec, spec->alt_dac_nid[0], stream_tag, + 0, format); + return 0; +} + +static int ad198x_alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct ad198x_spec *spec = codec->spec; + snd_hda_codec_cleanup_stream(codec, spec->alt_dac_nid[0]); + return 0; +} + +static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in ad198x_build_pcms */ + .ops = { + .prepare = ad198x_alt_playback_pcm_prepare, + .cleanup = ad198x_alt_playback_pcm_cleanup + }, +}; + /* * Digital out */ @@ -446,6 +500,17 @@ static int ad198x_build_pcms(struct hda_codec *codec) } } + if (spec->alt_dac_nid && spec->stream_analog_alt_playback) { + codec->num_pcms++; + info = spec->pcm_rec + 2; + info->name = "AD198x Headphone"; + info->pcm_type = HDA_PCM_TYPE_AUDIO; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = + *spec->stream_analog_alt_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = + spec->alt_dac_nid[0]; + } + return 0; } @@ -2015,6 +2080,7 @@ static int patch_ad1981(struct hda_codec *codec) enum { AD1988_6STACK, AD1988_6STACK_DIG, + AD1988_6STACK_DIG_FP, AD1988_3STACK, AD1988_3STACK_DIG, AD1988_LAPTOP, @@ -2047,6 +2113,10 @@ static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { 0x04, 0x05, 0x0a, 0x06 }; +static hda_nid_t ad1988_alt_dac_nid[1] = { + 0x03 +}; + static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 0x04, 0x0a, 0x06 }; @@ -2166,6 +2236,35 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { { } /* end */ }; +static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), + + HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT), + HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT), + HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), + HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), + + HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), + + 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 Volume", 0x39, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), + + { } /* end */ +}; + /* 3-stack mode */ static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), @@ -2445,6 +2544,68 @@ static struct hda_verb ad1988_6stack_init_verbs[] = { { } }; +static struct hda_verb ad1988_6stack_fp_init_verbs[] = { + /* Front, Surround, CLFE, side DAC; unmute as default */ + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + /* Headphone; unmute as default */ + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + /* Port-A front headphon path */ + {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + /* Port-D line-out path */ + {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + /* Port-F surround path */ + {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + /* Port-G CLFE path */ + {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + /* Port-H side path */ + {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + /* Mono out path */ + {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ + {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ + /* Port-B front mic-in path */ + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + /* Port-C line-in path */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, + /* Port-E mic-in path */ + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, + /* Analog CD Input */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + /* Analog Mix output amp */ + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ + + { } +}; + static struct hda_verb ad1988_capture_init_verbs[] = { /* mute analog mix */ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -3074,13 +3235,13 @@ static int ad1988_auto_init(struct hda_codec *codec) return 0; } - /* */ static const char *ad1988_models[AD1988_MODEL_LAST] = { [AD1988_6STACK] = "6stack", [AD1988_6STACK_DIG] = "6stack-dig", + [AD1988_6STACK_DIG_FP] = "6stack-dig-fp", [AD1988_3STACK] = "3stack", [AD1988_3STACK_DIG] = "3stack-dig", [AD1988_LAPTOP] = "laptop", @@ -3140,6 +3301,7 @@ static int patch_ad1988(struct hda_codec *codec) switch (board_config) { case AD1988_6STACK: case AD1988_6STACK_DIG: + case AD1988_6STACK_DIG_FP: spec->multiout.max_channels = 8; spec->multiout.num_dacs = 4; if (is_rev2(codec)) @@ -3152,10 +3314,22 @@ static int patch_ad1988(struct hda_codec *codec) spec->mixers[0] = ad1988_6stack_mixers1_rev2; else spec->mixers[0] = ad1988_6stack_mixers1; - spec->mixers[1] = ad1988_6stack_mixers2; + if (board_config == AD1988_6STACK_DIG_FP) { + spec->mixers[1] = ad1988_6stack_fp_mixers; + spec->slave_vols = ad1988_6stack_fp_slave_vols; + spec->slave_sws = ad1988_6stack_fp_slave_sws; + spec->alt_dac_nid = ad1988_alt_dac_nid; + spec->stream_analog_alt_playback = + &ad198x_pcm_analog_alt_playback; + } else + spec->mixers[1] = ad1988_6stack_mixers2; spec->num_init_verbs = 1; - spec->init_verbs[0] = ad1988_6stack_init_verbs; - if (board_config == AD1988_6STACK_DIG) { + if (board_config == AD1988_6STACK_DIG_FP) + spec->init_verbs[0] = ad1988_6stack_fp_init_verbs; + else + spec->init_verbs[0] = ad1988_6stack_init_verbs; + if ((board_config == AD1988_6STACK_DIG) || + (board_config == AD1988_6STACK_DIG_FP)) { spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; spec->dig_in_nid = AD1988_SPDIF_IN; } -- cgit v1.2.3 From ea73496324c1d990504e27f551e159388f891a4c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Jan 2011 11:29:34 +0100 Subject: ALSA: hda - consitify string arrays Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 10 +++++----- sound/pci/hda/hda_generic.c | 7 ++++--- sound/pci/hda/hda_local.h | 6 +++--- sound/pci/hda/hda_proc.c | 2 +- sound/pci/hda/patch_analog.c | 30 ++++++++++++++++-------------- sound/pci/hda/patch_cirrus.c | 4 ++-- sound/pci/hda/patch_cmedia.c | 2 +- sound/pci/hda/patch_conexant.c | 14 +++++++------- sound/pci/hda/patch_realtek.c | 34 ++++++++++++++++++---------------- sound/pci/hda/patch_sigmatel.c | 36 ++++++++++++++++++------------------ sound/pci/hda/patch_via.c | 28 ++++++++++++++++++++-------- 11 files changed, 95 insertions(+), 78 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 05e5ec88c2d9..ae5c5d5e4b7c 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2134,10 +2134,10 @@ int snd_hda_codec_reset(struct hda_codec *codec) * This function returns zero if successful or a negative error code. */ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, - unsigned int *tlv, const char **slaves) + unsigned int *tlv, const char * const *slaves) { struct snd_kcontrol *kctl; - const char **s; + const char * const *s; int err; for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) @@ -3689,7 +3689,7 @@ EXPORT_SYMBOL_HDA(snd_hda_build_pcms); * If no entries are matching, the function returns a negative value. */ int snd_hda_check_board_config(struct hda_codec *codec, - int num_configs, const char **models, + int num_configs, const char * const *models, const struct snd_pci_quirk *tbl) { if (codec->modelname && models) { @@ -3753,7 +3753,7 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config); * If no entries are matching, the function returns a negative value. */ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, - int num_configs, const char **models, + int num_configs, const char * const *models, const struct snd_pci_quirk *tbl) { const struct snd_pci_quirk *q; @@ -4690,7 +4690,7 @@ const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, int check_location) { unsigned int def_conf; - static const char *mic_names[] = { + static const char * const mic_names[] = { "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", }; int attr; diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index fb0582f8d725..a63c54d9d767 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -762,7 +762,8 @@ static int check_existing_control(struct hda_codec *codec, const char *type, con /* * build output mixer controls */ -static int create_output_mixers(struct hda_codec *codec, const char **names) +static int create_output_mixers(struct hda_codec *codec, + const char * const *names) { struct hda_gspec *spec = codec->spec; int i, err; @@ -780,8 +781,8 @@ static int create_output_mixers(struct hda_codec *codec, const char **names) static int build_output_controls(struct hda_codec *codec) { struct hda_gspec *spec = codec->spec; - static const char *types_speaker[] = { "Speaker", "Headphone" }; - static const char *types_line[] = { "Front", "Headphone" }; + static const char * const types_speaker[] = { "Speaker", "Headphone" }; + static const char * const types_line[] = { "Front", "Headphone" }; switch (spec->pcm_vol_nodes) { case 1: diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 46bbefe2e4a9..3ab5e7a303db 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -140,7 +140,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, const char *name); int snd_hda_add_vmaster(struct hda_codec *codec, char *name, - unsigned int *tlv, const char **slaves); + unsigned int *tlv, const char * const *slaves); int snd_hda_codec_reset(struct hda_codec *codec); /* amp value bits */ @@ -341,10 +341,10 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen); * Misc */ int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, - const char **modelnames, + const char * const *modelnames, const struct snd_pci_quirk *pci_list); int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, - int num_configs, const char **models, + int num_configs, const char * const *models, const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index f025200f2a62..bfe74c2fb079 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -418,7 +418,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer, static const char *get_pwr_state(u32 state) { - static const char *buf[4] = { + static const char * const buf[4] = { "D0", "D1", "D2", "D3" }; if (state < 4) diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 34ee1169f2e0..8dabab798689 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -84,8 +84,8 @@ struct ad198x_spec { #endif /* for virtual master */ hda_nid_t vmaster_nid; - const char **slave_vols; - const char **slave_sws; + const char * const *slave_vols; + const char * const *slave_sws; }; /* @@ -133,7 +133,7 @@ static int ad198x_init(struct hda_codec *codec) return 0; } -static const char *ad_slave_vols[] = { +static const char * const ad_slave_vols[] = { "Front Playback Volume", "Surround Playback Volume", "Center Playback Volume", @@ -146,7 +146,7 @@ static const char *ad_slave_vols[] = { NULL }; -static const char *ad_slave_sws[] = { +static const char * const ad_slave_sws[] = { "Front Playback Switch", "Surround Playback Switch", "Center Playback Switch", @@ -159,7 +159,7 @@ static const char *ad_slave_sws[] = { NULL }; -static const char *ad1988_6stack_fp_slave_vols[] = { +static const char * const ad1988_6stack_fp_slave_vols[] = { "Front Playback Volume", "Surround Playback Volume", "Center Playback Volume", @@ -169,7 +169,7 @@ static const char *ad1988_6stack_fp_slave_vols[] = { NULL }; -static const char *ad1988_6stack_fp_slave_sws[] = { +static const char * const ad1988_6stack_fp_slave_sws[] = { "Front Playback Switch", "Surround Playback Switch", "Center Playback Switch", @@ -1134,7 +1134,7 @@ enum { AD1986A_MODELS }; -static const char *ad1986a_models[AD1986A_MODELS] = { +static const char * const ad1986a_models[AD1986A_MODELS] = { [AD1986A_6STACK] = "6stack", [AD1986A_3STACK] = "3stack", [AD1986A_LAPTOP] = "laptop", @@ -1878,7 +1878,7 @@ enum { AD1981_MODELS }; -static const char *ad1981_models[AD1981_MODELS] = { +static const char * const ad1981_models[AD1981_MODELS] = { [AD1981_HP] = "hp", [AD1981_THINKPAD] = "thinkpad", [AD1981_BASIC] = "basic", @@ -2953,7 +2953,9 @@ static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + static const char * const chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; hda_nid_t nid; int i, err; @@ -3238,7 +3240,7 @@ static int ad1988_auto_init(struct hda_codec *codec) /* */ -static const char *ad1988_models[AD1988_MODEL_LAST] = { +static const char * const ad1988_models[AD1988_MODEL_LAST] = { [AD1988_6STACK] = "6stack", [AD1988_6STACK_DIG] = "6stack-dig", [AD1988_6STACK_DIG_FP] = "6stack-dig-fp", @@ -3573,7 +3575,7 @@ static struct hda_amp_list ad1884_loopbacks[] = { }; #endif -static const char *ad1884_slave_vols[] = { +static const char * const ad1884_slave_vols[] = { "PCM Playback Volume", "Mic Playback Volume", "Mono Playback Volume", @@ -3811,7 +3813,7 @@ enum { AD1984_MODELS }; -static const char *ad1984_models[AD1984_MODELS] = { +static const char * const ad1984_models[AD1984_MODELS] = { [AD1984_BASIC] = "basic", [AD1984_THINKPAD] = "thinkpad", [AD1984_DELL_DESKTOP] = "dell_desktop", @@ -4482,7 +4484,7 @@ enum { AD1884A_MODELS }; -static const char *ad1884a_models[AD1884A_MODELS] = { +static const char * const ad1884a_models[AD1884A_MODELS] = { [AD1884A_DESKTOP] = "desktop", [AD1884A_LAPTOP] = "laptop", [AD1884A_MOBILE] = "mobile", @@ -4870,7 +4872,7 @@ enum { AD1882_MODELS }; -static const char *ad1882_models[AD1986A_MODELS] = { +static const char * const ad1882_models[AD1986A_MODELS] = { [AD1882_3STACK] = "3stack", [AD1882_6STACK] = "6stack", }; diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 18af38ebf757..a07b031090d8 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -490,7 +490,7 @@ static int parse_digital_input(struct hda_codec *codec) * create mixer controls */ -static const char *dir_sfx[2] = { "Playback", "Capture" }; +static const char * const dir_sfx[2] = { "Playback", "Capture" }; static int add_mute(struct hda_codec *codec, const char *name, int index, unsigned int pval, int dir, struct snd_kcontrol **kctlp) @@ -1156,7 +1156,7 @@ static int cs_parse_auto_config(struct hda_codec *codec) return 0; } -static const char *cs420x_models[CS420X_MODELS] = { +static const char * const cs420x_models[CS420X_MODELS] = { [CS420X_MBP53] = "mbp53", [CS420X_MBP55] = "mbp55", [CS420X_IMAC27] = "imac27", diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index ff60908f4554..1f8bbcd0f802 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -608,7 +608,7 @@ static void cmi9880_free(struct hda_codec *codec) /* */ -static const char *cmi9880_models[CMI_MODELS] = { +static const char * const cmi9880_models[CMI_MODELS] = { [CMI_MINIMAL] = "minimal", [CMI_MIN_FP] = "min_fp", [CMI_FULL] = "full", diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e96581fcdbdb..9bb030a469cd 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -537,13 +537,13 @@ static struct snd_kcontrol_new cxt_beep_mixer[] = { }; #endif -static const char *slave_vols[] = { +static const char * const slave_vols[] = { "Headphone Playback Volume", "Speaker Playback Volume", NULL }; -static const char *slave_sws[] = { +static const char * const slave_sws[] = { "Headphone Playback Switch", "Speaker Playback Switch", NULL @@ -1134,7 +1134,7 @@ enum { CXT5045_MODELS }; -static const char *cxt5045_models[CXT5045_MODELS] = { +static const char * const cxt5045_models[CXT5045_MODELS] = { [CXT5045_LAPTOP_HPSENSE] = "laptop-hpsense", [CXT5045_LAPTOP_MICSENSE] = "laptop-micsense", [CXT5045_LAPTOP_HPMICSENSE] = "laptop-hpmicsense", @@ -1579,7 +1579,7 @@ enum { CXT5047_MODELS }; -static const char *cxt5047_models[CXT5047_MODELS] = { +static const char * const cxt5047_models[CXT5047_MODELS] = { [CXT5047_LAPTOP] = "laptop", [CXT5047_LAPTOP_HP] = "laptop-hp", [CXT5047_LAPTOP_EAPD] = "laptop-eapd", @@ -1995,7 +1995,7 @@ enum { CXT5051_MODELS }; -static const char *cxt5051_models[CXT5051_MODELS] = { +static const char *const cxt5051_models[CXT5051_MODELS] = { [CXT5051_LAPTOP] = "laptop", [CXT5051_HP] = "hp", [CXT5051_HP_DV6736] = "hp-dv6736", @@ -3084,7 +3084,7 @@ enum { CXT5066_MODELS }; -static const char *cxt5066_models[CXT5066_MODELS] = { +static const char * const cxt5066_models[CXT5066_MODELS] = { [CXT5066_LAPTOP] = "laptop", [CXT5066_DELL_LAPTOP] = "dell-laptop", [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", @@ -3746,7 +3746,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) struct conexant_spec *spec = codec->spec; int i, err; int num_line = 0, num_hp = 0, num_spk = 0; - static const char *texts[3] = { "Front", "Surround", "CLFE" }; + static const char * const texts[3] = { "Front", "Surround", "CLFE" }; if (spec->dac_info_filled == 1) return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 69554061c16e..4f006eedd7ef 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2916,7 +2916,7 @@ static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { /* * slave controls for virtual master */ -static const char *alc_slave_vols[] = { +static const char * const alc_slave_vols[] = { "Front Playback Volume", "Surround Playback Volume", "Center Playback Volume", @@ -2930,7 +2930,7 @@ static const char *alc_slave_vols[] = { NULL, }; -static const char *alc_slave_sws[] = { +static const char * const alc_slave_sws[] = { "Front Playback Switch", "Surround Playback Switch", "Center Playback Switch", @@ -4611,7 +4611,7 @@ static struct hda_verb alc880_test_init_verbs[] = { /* */ -static const char *alc880_models[ALC880_MODEL_LAST] = { +static const char * const alc880_models[ALC880_MODEL_LAST] = { [ALC880_3ST] = "3stack", [ALC880_TCL_S700] = "tcl", [ALC880_3ST_DIG] = "3stack-digout", @@ -5144,7 +5144,7 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { - static const char *chname[4] = { + static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; const char *pfx = alc_get_line_out_pfx(cfg, false); @@ -7158,7 +7158,7 @@ static struct snd_pci_quirk alc260_fixup_tbl[] = { /* * ALC260 configurations */ -static const char *alc260_models[ALC260_MODEL_LAST] = { +static const char * const alc260_models[ALC260_MODEL_LAST] = { [ALC260_BASIC] = "basic", [ALC260_HP] = "hp", [ALC260_HP_3013] = "hp-3013", @@ -9781,7 +9781,7 @@ static hda_nid_t alc1200_slave_dig_outs[] = { /* * configuration and preset */ -static const char *alc882_models[ALC882_MODEL_LAST] = { +static const char * const alc882_models[ALC882_MODEL_LAST] = { [ALC882_3ST_DIG] = "3stack-dig", [ALC882_6ST_DIG] = "6stack-dig", [ALC882_ARIMA] = "arima", @@ -12601,7 +12601,7 @@ static void alc262_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc262_models[ALC262_MODEL_LAST] = { +static const char * const alc262_models[ALC262_MODEL_LAST] = { [ALC262_BASIC] = "basic", [ALC262_HIPPO] = "hippo", [ALC262_HIPPO_1] = "hippo_1", @@ -13789,7 +13789,7 @@ static void alc268_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc268_models[ALC268_MODEL_LAST] = { +static const char * const alc268_models[ALC268_MODEL_LAST] = { [ALC267_QUANTA_IL1] = "quanta-il1", [ALC268_3ST] = "3stack", [ALC268_TOSHIBA] = "toshiba", @@ -14961,7 +14961,7 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = { /* * configuration and preset */ -static const char *alc269_models[ALC269_MODEL_LAST] = { +static const char * const alc269_models[ALC269_MODEL_LAST] = { [ALC269_BASIC] = "basic", [ALC269_QUANTA_FL1] = "quanta", [ALC269_AMIC] = "laptop-amic", @@ -16004,7 +16004,7 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct alc_spec *spec = codec->spec; - static const char *chname[4] = { + static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; const char *pfx = alc_get_line_out_pfx(cfg, true); @@ -16210,7 +16210,7 @@ static struct hda_amp_list alc861_loopbacks[] = { /* * configuration and preset */ -static const char *alc861_models[ALC861_MODEL_LAST] = { +static const char * const alc861_models[ALC861_MODEL_LAST] = { [ALC861_3ST] = "3stack", [ALC660_3ST] = "3stack-660", [ALC861_3ST_DIG] = "3stack-dig", @@ -16913,7 +16913,7 @@ static void alc861vd_dallas_setup(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { +static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC660VD_3ST] = "3stack-660", [ALC660VD_3ST_DIG] = "3stack-660-digout", [ALC660VD_ASUS_V1S] = "asus-v1s", @@ -17133,7 +17133,9 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 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"}; + static const char * const 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; @@ -18688,7 +18690,7 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = { /* * configuration and preset */ -static const char *alc662_models[ALC662_MODEL_LAST] = { +static const char * const alc662_models[ALC662_MODEL_LAST] = { [ALC662_3ST_2ch_DIG] = "3stack-dig", [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", [ALC662_3ST_6ch] = "3stack-6ch", @@ -19203,7 +19205,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct alc_spec *spec = codec->spec; - static const char *chname[4] = { + static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; const char *pfx = alc_get_line_out_pfx(cfg, true); @@ -19978,7 +19980,7 @@ static void alc680_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc680_models[ALC680_MODEL_LAST] = { +static const char * const alc680_models[ALC680_MODEL_LAST] = { [ALC680_BASE] = "base", [ALC680_AUTO] = "auto", }; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4ab019d0924e..056f52df68cd 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -266,7 +266,7 @@ struct sigmatel_spec { struct sigmatel_mic_route int_mic; struct sigmatel_mic_route dock_mic; - const char **spdif_labels; + const char * const *spdif_labels; hda_nid_t dig_in_nid; hda_nid_t mono_nid; @@ -524,7 +524,7 @@ static unsigned long stac927x_capsws[] = { HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), }; -static const char *stac927x_spdif_labels[5] = { +static const char * const stac927x_spdif_labels[5] = { "Digital Playback", "ADAT", "Analog Mux 1", "Analog Mux 2", "Analog Mux 3" }; @@ -1062,7 +1062,7 @@ static struct snd_kcontrol_new stac_smux_mixer = { .put = stac92xx_smux_enum_put, }; -static const char *slave_vols[] = { +static const char * const slave_vols[] = { "Front Playback Volume", "Surround Playback Volume", "Center Playback Volume", @@ -1073,7 +1073,7 @@ static const char *slave_vols[] = { NULL }; -static const char *slave_sws[] = { +static const char * const slave_sws[] = { "Front Playback Switch", "Surround Playback Switch", "Center Playback Switch", @@ -1354,7 +1354,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { [STAC_9200_PANASONIC] = ref9200_pin_configs, }; -static const char *stac9200_models[STAC_9200_MODELS] = { +static const char * const stac9200_models[STAC_9200_MODELS] = { [STAC_AUTO] = "auto", [STAC_REF] = "ref", [STAC_9200_OQO] = "oqo", @@ -1500,7 +1500,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { [STAC_M6] = stac925xM6_pin_configs, }; -static const char *stac925x_models[STAC_925x_MODELS] = { +static const char * const stac925x_models[STAC_925x_MODELS] = { [STAC_925x_AUTO] = "auto", [STAC_REF] = "ref", [STAC_M1] = "m1", @@ -1574,7 +1574,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, }; -static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { +static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_AUTO] = "auto", [STAC_92HD73XX_NO_JD] = "no-jd", [STAC_92HD73XX_REF] = "ref", @@ -1660,7 +1660,7 @@ static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, }; -static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { +static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_AUTO] = "auto", [STAC_92HD83XXX_REF] = "ref", [STAC_92HD83XXX_PWR_REF] = "mic-ref", @@ -1722,7 +1722,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { [STAC_HP_DV4_1222NR] = NULL, }; -static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { +static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { [STAC_92HD71BXX_AUTO] = "auto", [STAC_92HD71BXX_REF] = "ref", [STAC_DELL_M4_1] = "dell-m4-1", @@ -1915,7 +1915,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs, }; -static const char *stac922x_models[STAC_922X_MODELS] = { +static const char * const stac922x_models[STAC_922X_MODELS] = { [STAC_922X_AUTO] = "auto", [STAC_D945_REF] = "ref", [STAC_D945GTP5] = "5stack", @@ -2077,7 +2077,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [STAC_927X_VOLKNOB] = NULL, }; -static const char *stac927x_models[STAC_927X_MODELS] = { +static const char * const stac927x_models[STAC_927X_MODELS] = { [STAC_927X_AUTO] = "auto", [STAC_D965_REF_NO_JD] = "ref-no-jd", [STAC_D965_REF] = "ref", @@ -2180,7 +2180,7 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { [STAC_9205_EAPD] = NULL, }; -static const char *stac9205_models[STAC_9205_MODELS] = { +static const char * const stac9205_models[STAC_9205_MODELS] = { [STAC_9205_AUTO] = "auto", [STAC_9205_REF] = "ref", [STAC_9205_DELL_M42] = "dell-m42", @@ -3123,7 +3123,7 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, int type) { struct sigmatel_spec *spec = codec->spec; - static const char *chname[4] = { + static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; hda_nid_t nid; @@ -3256,7 +3256,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, } /* labels for mono mux outputs */ -static const char *stac92xx_mono_labels[4] = { +static const char * const stac92xx_mono_labels[4] = { "DAC0", "DAC1", "Mixer", "DAC2" }; @@ -3380,7 +3380,7 @@ static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) return 0; }; -static const char *stac92xx_spdif_labels[3] = { +static const char * const stac92xx_spdif_labels[3] = { "Digital Playback", "Analog Mux 1", "Analog Mux 2", }; @@ -3388,7 +3388,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; struct hda_input_mux *spdif_mux = &spec->private_smux; - const char **labels = spec->spdif_labels; + const char * const *labels = spec->spdif_labels; int i, num_cons; hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; @@ -3409,7 +3409,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) } /* labels for dmic mux inputs */ -static const char *stac92xx_dmic_labels[5] = { +static const char * const stac92xx_dmic_labels[5] = { "Analog Inputs", "Digital Mic 1", "Digital Mic 2", "Digital Mic 3", "Digital Mic 4" }; @@ -6270,7 +6270,7 @@ static unsigned int stac9872_vaio_pin_configs[9] = { 0x90a7013e }; -static const char *stac9872_models[STAC_9872_MODELS] = { +static const char * const stac9872_models[STAC_9872_MODELS] = { [STAC_9872_AUTO] = "auto", [STAC_9872_VAIO] = "vaio", }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index d1c3f8defc48..71f78456d682 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -2282,7 +2282,9 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; + static const char * const chname[4] = { + "Front", "Surround", "C/LFE", "Side" + }; hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b}; int i, err; @@ -2371,7 +2373,7 @@ static void create_hp_imux(struct via_spec *spec) { int i; struct hda_input_mux *imux = &spec->private_imux[1]; - static const char *texts[] = { "OFF", "ON", NULL}; + static const char * const texts[] = { "OFF", "ON", NULL}; /* for hp mode select */ for (i = 0; texts[i]; i++) @@ -2891,7 +2893,9 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; + static const char * const chname[4] = { + "Front", "Surround", "C/LFE", "Side" + }; hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29}; int i, err; @@ -3434,7 +3438,9 @@ static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; + static const char * const chname[4] = { + "Front", "Surround", "C/LFE", "Side" + }; hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27}; hda_nid_t nid, nid_vol = 0; int i, err; @@ -3862,7 +3868,9 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; + static const char * const chname[4] = { + "Front", "Surround", "C/LFE", "Side" + }; hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; hda_nid_t nid, nid_vol, nid_mute; @@ -4305,7 +4313,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) { int err, i; struct hda_input_mux *imux; - static const char *texts[] = { "ON", "OFF", NULL}; + static const char * const texts[] = { "ON", "OFF", NULL}; if (!pin) return 0; spec->multiout.hp_nid = 0x1D; @@ -4616,7 +4624,9 @@ static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; + static const char * const chname[4] = { + "Front", "Surround", "C/LFE", "Side" + }; hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb}; hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27}; hda_nid_t nid, nid_vol, nid_mute = 0; @@ -5065,7 +5075,9 @@ static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[3] = { "Front", "Surround", "C/LFE" }; + static const char * const chname[3] = { + "Front", "Surround", "C/LFE" + }; hda_nid_t nid_vols[] = {0x10, 0x11, 0x25}; hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27}; hda_nid_t nid, nid_vol, nid_mute; -- cgit v1.2.3 From 0f0714c5ed0a98fdeaa2287d3b159989bbe6d842 Mon Sep 17 00:00:00 2001 From: Bankim Bhavsar Date: Mon, 17 Jan 2011 15:23:21 +0100 Subject: ALSA: hda - Add support for VMware controller Add the new PCI ID 0x15ad and device ID 0x1977 for VMware HDAudio Controller. [changed to use AZX_DRIVER_GENERIC by tiwai] Signed-off-by: Bankim Bhavsar Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a1c4008af891..07c522fd2b10 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2806,6 +2806,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { #endif /* Vortex86MX */ { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, + /* VMware HDAudio */ + { PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC }, /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, -- cgit v1.2.3 From cbbf50b22f9693218f9f0d460432266b04fc960d Mon Sep 17 00:00:00 2001 From: Vitaliy Kulikov Date: Fri, 14 Jan 2011 17:21:13 -0600 Subject: ALSA: hda - Fix initialization for HP 2011 notebooks Fixes for HP 2011 notebooks: enable dock ports and disable BTL initialization in the driver. Signed-off-by: Vitaliy Kulikov Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 53 ++++++++---------------------------------- 1 file changed, 10 insertions(+), 43 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 056f52df68cd..9ea48b425d0b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5333,7 +5333,7 @@ again: return 0; } -static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec) +static int hp_bnb2011_with_dock(struct hda_codec *codec) { if (codec->vendor_id != 0x111d7605 && codec->vendor_id != 0x111d76d1) @@ -5348,10 +5348,6 @@ static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec) case 0x103c161d: case 0x103c161e: case 0x103c161f: - case 0x103c1620: - case 0x103c1621: - case 0x103c1622: - case 0x103c1623: case 0x103c162a: case 0x103c162b: @@ -5360,41 +5356,9 @@ static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec) case 0x103c1631: case 0x103c1633: - + case 0x103c1634: case 0x103c1635: - case 0x103c164f: - - case 0x103c1676: - case 0x103c1677: - case 0x103c1678: - case 0x103c1679: - case 0x103c167a: - case 0x103c167b: - case 0x103c167c: - case 0x103c167d: - case 0x103c167e: - case 0x103c167f: - case 0x103c1680: - case 0x103c1681: - case 0x103c1682: - case 0x103c1683: - case 0x103c1684: - case 0x103c1685: - case 0x103c1686: - case 0x103c1687: - case 0x103c1688: - case 0x103c1689: - case 0x103c168a: - case 0x103c168b: - case 0x103c168c: - case 0x103c168d: - case 0x103c168e: - case 0x103c168f: - case 0x103c1690: - case 0x103c1691: - case 0x103c1692: - case 0x103c3587: case 0x103c3588: case 0x103c3589: @@ -5402,9 +5366,9 @@ static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec) case 0x103c3667: case 0x103c3668: - /* set BTL amp level to 13.43dB for louder speaker output */ - return snd_hda_codec_write_cache(codec, codec->afg, 0, - 0x7F4, 0x14); + case 0x103c3669: + + return 1; } return 0; } @@ -5420,6 +5384,11 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; + if (hp_bnb2011_with_dock(codec)) { + snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f); + snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); + } + /* reset pin power-down; Windows may leave these bits after reboot */ snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0); snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); @@ -5546,8 +5515,6 @@ again: AC_VERB_SET_CONNECT_SEL, num_dacs); } - stac92hd83xxx_set_system_btl_amp(codec); - codec->proc_widget_hook = stac92hd_proc_hook; return 0; -- cgit v1.2.3 From b8b1a4cb6842fb33769be1ad636f062d31d588c3 Mon Sep 17 00:00:00 2001 From: Brian Bloniarz Date: Mon, 17 Jan 2011 23:20:03 -0800 Subject: ALSA: ice1712 delta - initialize SPI clock The driver was using an initial value for the clock on the SPI bus which was read from ICE1712 EEPROM, ice->eeprom.data[ICE_EEP1_GPIO_STATE] & ICE1712_DELTA_AP_CCLK (0x02) It appears some cards have it default high, some cards have it default low. On my Delta 66 rev. E: $ cat /proc/asound/M66/ice1712 | grep 'GPIO state' GPIO state : 0x70 /* ICE1712_DELTA_AP_CCLK bit is zero */ On my Audiophile 2496: $ cat /proc/asound/M2496/ice1712 | grep 'GPIO state' GPIO state : 0xfe /* ICE1712_DELTA_AP_CCLK bit is one */ It must be raised before the first SPI write happens, or the write will fail, leading to: [ 23.248721] invalid CS8427 signature 0x0: let me try again... I theorize that 4eb4550ab37d351ab0973ccec921a5a2d8560ec7 is no longer needed, it was a different way to workaround the problem. [fixed variable decleration by tiwai] Signed-off-by: Brian Bloniarz Signed-off-by: Takashi Iwai --- sound/pci/ice1712/delta.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 7b62de089fee..20c6b079d0df 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -580,6 +580,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) { int err; struct snd_akm4xxx *ak; + unsigned char tmp; if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 && ice->eeprom.gpiodir == 0x7b) @@ -622,6 +623,12 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) break; } + /* initialize the SPI clock to high */ + tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); + tmp |= ICE1712_DELTA_AP_CCLK; + snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); + udelay(5); + /* initialize spdif */ switch (ice->eeprom.subvendor) { case ICE1712_SUBDEVICE_AUDIOPHILE: -- cgit v1.2.3 From 569ed348ecef309fae5a71b86015951680ea3415 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 19 Jan 2011 10:14:46 +0100 Subject: Revert "ALSA: HDA: Create mixers on ALC887" This reverts commit 03b7a1ab557efe34e8f79b78660e514bd7374248. This commit was mistakenly re-introduced. While the change is harmless (as ALC887 uses patch_alc888() now), we should get rid of any wrong code. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 269dbff70b92..4f006eedd7ef 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10930,9 +10930,6 @@ 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) { @@ -10950,10 +10947,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); if (err < 0) return err; - 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); + 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], @@ -17134,7 +17128,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 and ALC887 have separate, +/* Based on ALC880 version. But ALC861VD has 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 5734a07cbb8d4600a74a374c839620ddc62b2cf2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 19 Jan 2011 17:07:12 +0100 Subject: ALSA: hda - Add quirk for HP Z-series workstation It seems working well with model=hp-bpc. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4f006eedd7ef..7874023db0f3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12629,6 +12629,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { ALC262_HP_BPC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", ALC262_HP_BPC), + SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", + ALC262_HP_BPC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), -- cgit v1.2.3 From aa1d0c5261f17d48636bf6d10bde0f38045511c0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 19 Jan 2011 17:27:58 +0100 Subject: ALSA: hda - Fix "unused variable" compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sound/pci/hda/patch_realtek.c: In function ‘alc_apply_fixup’: sound/pci/hda/patch_realtek.c:1724:14: warning: unused variable ‘modelname’ snd_printdd() is evaluated only when CONFIG_SND_DEBUG_VERBOSE=y. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7874023db0f3..2b055e2780bb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1721,7 +1721,9 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) { struct alc_spec *spec = codec->spec; int id = spec->fixup_id; +#ifdef CONFIG_SND_DEBUG_VERBOSE const char *modelname = spec->fixup_name; +#endif int depth = 0; if (!spec->fixup_list) -- cgit v1.2.3 From fb228af7060d02a81a7bcc2ce329ba3ab1af0c7f Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 19 Jan 2011 11:59:01 +0100 Subject: ALSA: HDA: Add SKU ignore for another Thinkpad Edge 14 BugLink: http://bugs.launchpad.net/bugs/705323 Thinkpad Edge 14 has one more SSID that suffers from disabled auto-mute. Signed-off-by: David Henningsson 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 2b055e2780bb..5ea60c6d24aa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14955,6 +14955,7 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = { 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), + SND_PCI_QUIRK(0x17aa, 0x21e9, "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 d2ebd4798744c401faf3fdc6493383912ccd0b80 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 20 Jan 2011 12:36:21 +0100 Subject: ALSA: hda - Fix EAPD to low on CZC P10T tablet computer with ALC662 Signed-off-by: Anisse Astier Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5ea60c6d24aa..be4df4c6fd56 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19460,6 +19460,7 @@ enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_IDEAPAD, ALC272_FIXUP_MARIO, + ALC662_FIXUP_CZC_P10T, }; static const struct alc_fixup alc662_fixups[] = { @@ -19480,7 +19481,14 @@ static const struct alc_fixup alc662_fixups[] = { [ALC272_FIXUP_MARIO] = { .type = ALC_FIXUP_FUNC, .v.func = alc272_fixup_mario, - } + }, + [ALC662_FIXUP_CZC_P10T] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, + {} + } + }, }; static struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -19488,6 +19496,7 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = { 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), + SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), {} }; -- cgit v1.2.3 From 233d84c46c2253d13e10b42d88c14748fbb67a98 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 20 Jan 2011 22:37:43 +0100 Subject: ALSA: Xonar, CS43xx: Don't overrun static array 'cs4398_regs' in 'struct xonar_cs43xx' is an array of 'u8' with a size of 8. So, this code in sound/pci/oxygen/xonar_cs43xx.c::dump_d1_registers() for (i = 2; i <= 8; ++i) snd_iprintf(buffer, " %02x", data->cs4398_regs[i]); will overrun the array when 'i == 8'. I guess that what's needed to fix it is the trivial patch below, but I must admit that I have no idea about this code, so I may very well be wrong. Additionally, I have no way to actually test this, so all I know is that the below compiles. Someone who actually knows this code should take a look before anything is comitted - consider the below (not much more than) a bug report. Signed-off-by: Jesper Juhl Acked-by: Clemens Ladisch --- sound/pci/oxygen/xonar_cs43xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 9f72d424969c..252719101c42 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -392,7 +392,7 @@ static void dump_d1_registers(struct oxygen *chip, unsigned int i; snd_iprintf(buffer, "\nCS4398: 7?"); - for (i = 2; i <= 8; ++i) + for (i = 2; i < 8; ++i) snd_iprintf(buffer, " %02x", data->cs4398_regs[i]); snd_iprintf(buffer, "\n"); dump_cs4362a_registers(data, buffer); -- cgit v1.2.3 From c9ba374d24882c04e7cc000d8cf3b0fe56511b84 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Tue, 25 Jan 2011 06:46:31 +0100 Subject: ALSA: azt3328 - fix broken AZF_FMT_XLATE macro Cleanly revert to non-macro implementation of snd_azf3328_codec_setfmt(), to fix last-minute functionality breakage induced by following checkpatch.pl recommendations without giving them their due full share of thought ("revolting computer, ensuing PEBKAC"). I would like to thank Jiri Slaby for his very timely (in -rc1 even) and unexpected (uncommon hardware) "recognition of the dangerous situation" due to his very commendable static parser use. :) Reported-by: Jiri Slaby Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 6117595fc075..573594bf3225 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -979,31 +979,25 @@ snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec, snd_azf3328_dbgcallenter(); switch (bitrate) { -#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) + case AZF_FREQ_4000: freq = SOUNDFORMAT_FREQ_SUSPECTED_4000; break; + case AZF_FREQ_4800: freq = SOUNDFORMAT_FREQ_SUSPECTED_4800; break; + case AZF_FREQ_5512: + /* the AZF3328 names it "5510" for some strange reason */ + freq = SOUNDFORMAT_FREQ_5510; break; + case AZF_FREQ_6620: freq = SOUNDFORMAT_FREQ_6620; break; + case AZF_FREQ_8000: freq = SOUNDFORMAT_FREQ_8000; break; + case AZF_FREQ_9600: freq = SOUNDFORMAT_FREQ_9600; break; + case AZF_FREQ_11025: freq = SOUNDFORMAT_FREQ_11025; break; + case AZF_FREQ_13240: freq = SOUNDFORMAT_FREQ_SUSPECTED_13240; break; + case AZF_FREQ_16000: freq = SOUNDFORMAT_FREQ_16000; break; + case AZF_FREQ_22050: freq = SOUNDFORMAT_FREQ_22050; break; + case AZF_FREQ_32000: freq = SOUNDFORMAT_FREQ_32000; break; default: snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); /* fall-through */ - AZF_FMT_XLATE(44100, 44100) - AZF_FMT_XLATE(48000, 48000) - AZF_FMT_XLATE(66200, SUSPECTED_66200) -#undef AZF_FMT_XLATE + case AZF_FREQ_44100: freq = SOUNDFORMAT_FREQ_44100; break; + case AZF_FREQ_48000: freq = SOUNDFORMAT_FREQ_48000; break; + case AZF_FREQ_66200: freq = SOUNDFORMAT_FREQ_SUSPECTED_66200; break; } /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ -- cgit v1.2.3 From d757534ed15387202e322854cd72dc58bbb975de Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 25 Jan 2011 19:44:26 +0100 Subject: ALSA: HDA: Fix dmesg output of HDMI supported bits This typo caused the dmesg output of the supported bits of HDMI to be cut off early. Cc: stable@kernel.org Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 4a663471dadc..74b0560289c0 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -381,7 +381,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a) snd_print_pcm_rates(a->rates, buf, sizeof(buf)); if (a->format == AUDIO_CODING_TYPE_LPCM) - snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8)); + snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); else if (a->max_bitrate) snprintf(buf2, sizeof(buf2), ", max bitrate = %d", a->max_bitrate); -- cgit v1.2.3 From ded9f5238bb719737f82b0b5b957937cb0203804 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 26 Jan 2011 11:46:12 +0100 Subject: ALSA: HDA: Fix automute on Thinkpad L412/L512 BugLink: http://bugs.launchpad.net/bugs/707902 More Thinkpad machines with invalid SKU found, that disables automute between speakers and headphones on these machines. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index be4df4c6fd56..2fa9ed99c32f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14954,9 +14954,11 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = { 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), - SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", 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