From 9ad593f6d326e7a4664e3856520f6c042f82a37f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 16 May 2008 12:34:47 +0200 Subject: [ALSA] hda - Fix DMA position inaccuracy Many HD-audio controllers seem inaccurate about the IRQ timing of PCM period updates. This has caused problems on audio quality; e.g. JACK doesn't work with two periods. This patch fixes the problem by checking the current DMA position at IRQ handler and delays the period-update via a workq if it's inaccurate. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 124 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 106 insertions(+), 18 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b3a618eb42c..6ba7ac01d9f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -285,6 +285,7 @@ struct azx_dev { u32 *posbuf; /* position buffer pointer */ unsigned int bufsize; /* size of the play buffer in bytes */ + unsigned int period_bytes; /* size of the period in bytes */ unsigned int frags; /* number for period in the play buffer */ unsigned int fifo_size; /* FIFO size */ @@ -301,11 +302,10 @@ struct azx_dev { */ unsigned char stream_tag; /* assigned stream */ unsigned char index; /* stream index */ - /* for sanity check of position buffer */ - unsigned int period_intr; unsigned int opened :1; unsigned int running :1; + unsigned int irq_pending: 1; }; /* CORB/RIRB */ @@ -369,6 +369,9 @@ struct azx { /* for debugging */ unsigned int last_cmd; /* last issued command (to sync) */ + + /* for pending irqs */ + struct work_struct irq_pending_work; }; /* driver types */ @@ -908,6 +911,8 @@ static void azx_init_pci(struct azx *chip) } +static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); + /* * interrupt handler */ @@ -930,11 +935,18 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) azx_dev = &chip->azx_dev[i]; if (status & azx_dev->sd_int_sta_mask) { azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); - if (azx_dev->substream && azx_dev->running) { - azx_dev->period_intr++; + if (!azx_dev->substream || !azx_dev->running) + continue; + /* check whether this IRQ is really acceptable */ + if (azx_position_ok(chip, azx_dev)) { + azx_dev->irq_pending = 0; spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(azx_dev->substream); spin_lock(&chip->reg_lock); + } else { + /* bogus IRQ, process it later */ + azx_dev->irq_pending = 1; + schedule_work(&chip->irq_pending_work); } } } @@ -973,6 +985,7 @@ static int azx_setup_periods(struct snd_pcm_substream *substream, azx_sd_writel(azx_dev, SD_BDLPU, 0); period_bytes = snd_pcm_lib_period_bytes(substream); + azx_dev->period_bytes = period_bytes; periods = azx_dev->bufsize / period_bytes; /* program the initial BDL entries */ @@ -1421,27 +1434,16 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return 0; } -static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) +static unsigned int azx_get_position(struct azx *chip, + struct azx_dev *azx_dev) { - struct azx_pcm *apcm = snd_pcm_substream_chip(substream); - struct azx *chip = apcm->chip; - struct azx_dev *azx_dev = get_azx_dev(substream); unsigned int pos; if (chip->position_fix == POS_FIX_POSBUF || chip->position_fix == POS_FIX_AUTO) { /* use the position buffer */ pos = le32_to_cpu(*azx_dev->posbuf); - if (chip->position_fix == POS_FIX_AUTO && - azx_dev->period_intr == 1 && !pos) { - printk(KERN_WARNING - "hda-intel: Invalid position buffer, " - "using LPIB read method instead.\n"); - chip->position_fix = POS_FIX_NONE; - goto read_lpib; - } } else { - read_lpib: /* read LPIB */ pos = azx_sd_readl(azx_dev, SD_LPIB); if (chip->position_fix == POS_FIX_FIFO) @@ -1449,7 +1451,90 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) } if (pos >= azx_dev->bufsize) pos = 0; - return bytes_to_frames(substream->runtime, pos); + return pos; +} + +static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct azx_pcm *apcm = snd_pcm_substream_chip(substream); + struct azx *chip = apcm->chip; + struct azx_dev *azx_dev = get_azx_dev(substream); + return bytes_to_frames(substream->runtime, + azx_get_position(chip, azx_dev)); +} + +/* + * Check whether the current DMA position is acceptable for updating + * periods. Returns non-zero if it's OK. + * + * Many HD-audio controllers appear pretty inaccurate about + * the update-IRQ timing. The IRQ is issued before actually the + * data is processed. So, we need to process it afterwords in a + * workqueue. + */ +static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) +{ + unsigned int pos; + + pos = azx_get_position(chip, azx_dev); + if (chip->position_fix == POS_FIX_AUTO) { + if (!pos) { + printk(KERN_WARNING + "hda-intel: Invalid position buffer, " + "using LPIB read method instead.\n"); + chip->position_fix = POS_FIX_NONE; + pos = azx_get_position(chip, azx_dev); + } else + chip->position_fix = POS_FIX_POSBUF; + } + + if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) + return 0; /* NG - it's below the period boundary */ + return 1; /* OK, it's fine */ +} + +/* + * The work for pending PCM period updates. + */ +static void azx_irq_pending_work(struct work_struct *work) +{ + struct azx *chip = container_of(work, struct azx, irq_pending_work); + int i, pending; + + for (;;) { + pending = 0; + spin_lock_irq(&chip->reg_lock); + for (i = 0; i < chip->num_streams; i++) { + struct azx_dev *azx_dev = &chip->azx_dev[i]; + if (!azx_dev->irq_pending || + !azx_dev->substream || + !azx_dev->running) + continue; + if (azx_position_ok(chip, azx_dev)) { + azx_dev->irq_pending = 0; + spin_unlock(&chip->reg_lock); + snd_pcm_period_elapsed(azx_dev->substream); + spin_lock(&chip->reg_lock); + } else + pending++; + } + spin_unlock_irq(&chip->reg_lock); + if (!pending) + return; + cond_resched(); + } +} + +/* clear irq_pending flags and assure no on-going workq */ +static void azx_clear_irq_pending(struct azx *chip) +{ + int i; + + spin_lock_irq(&chip->reg_lock); + for (i = 0; i < chip->num_streams; i++) + chip->azx_dev[i].irq_pending = 0; + spin_unlock_irq(&chip->reg_lock); + flush_scheduled_work(); } static struct snd_pcm_ops azx_pcm_ops = { @@ -1676,6 +1761,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + azx_clear_irq_pending(chip); for (i = 0; i < AZX_MAX_PCMS; i++) snd_pcm_suspend_all(chip->pcm[i]); if (chip->initialized) @@ -1732,6 +1818,7 @@ static int azx_free(struct azx *chip) int i; if (chip->initialized) { + azx_clear_irq_pending(chip); for (i = 0; i < chip->num_streams; i++) azx_stream_stop(chip, &chip->azx_dev[i]); azx_stop_chip(chip); @@ -1857,6 +1944,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->irq = -1; chip->driver_type = driver_type; chip->msi = enable_msi; + INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); chip->position_fix = check_position_fix(chip, position_fix[dev]); check_probe_mask(chip, dev); -- cgit v1.2.3 From 62cf872a8eec1f11aacbec0ac3fe3698bfa9b403 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 20 May 2008 12:15:15 +0200 Subject: [ALSA] Replace CONFIG_SND_DEBUG_DETECT with CONFIG_SND_DEBUG_VERBOSE Replace CONFIG_SND_DEBUG_DETECT with CONFIG_SND_DEBUG_VERBOSE to represent its meaning more better. This config isn't provided only for the detection but for more verbose debug prints in general. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 +- sound/pci/hda/hda_hwdep.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a6be6e3e871..d2e1093f8e9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2335,7 +2335,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, if (!tbl) return -1; if (tbl->value >= 0 && tbl->value < num_configs) { -#ifdef CONFIG_SND_DEBUG_DETECT +#ifdef CONFIG_SND_DEBUG_VERBOSE char tmp[10]; const char *model = NULL; if (models) diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 2177d9af533..6e18a422d99 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -88,7 +88,7 @@ static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file, static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file) { -#ifndef CONFIG_SND_DEBUG_DETECT +#ifndef CONFIG_SND_DEBUG_VERBOSE if (!capable(CAP_SYS_RAWIO)) return -EACCES; #endif -- cgit v1.2.3 From f269002e61446ed3410d8ca5f06ebca1e2760cb5 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 11:44:55 +0200 Subject: [ALSA] hda - Add support of Teradici controller Add the new PCI ID 0x6549 0x1200 Teradici controller. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 6ba7ac01d9f..7f62196989a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -197,6 +197,10 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define ATIHDMI_NUM_CAPTURE 0 #define ATIHDMI_NUM_PLAYBACK 1 +/* TERA has 4 playback and 3 capture */ +#define TERA_NUM_CAPTURE 3 +#define TERA_NUM_PLAYBACK 4 + /* this number is statically defined for simplicity */ #define MAX_AZX_DEV 16 @@ -384,6 +388,7 @@ enum { AZX_DRIVER_SIS, AZX_DRIVER_ULI, AZX_DRIVER_NVIDIA, + AZX_DRIVER_TERA, }; static char *driver_short_names[] __devinitdata = { @@ -395,6 +400,7 @@ static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_SIS] = "HDA SIS966", [AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_NVIDIA] = "HDA NVidia", + [AZX_DRIVER_TERA] = "HDA Teradici", }; /* @@ -1106,6 +1112,7 @@ static unsigned int azx_max_codecs[] __devinitdata = { [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */ [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */ [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ + [AZX_DRIVER_TERA] = 1, }; static int __devinit azx_codec_create(struct azx *chip, const char *model, @@ -2229,6 +2236,8 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x0bd5), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0bd6), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, + /* Teradici */ + { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); -- cgit v1.2.3 From abbc9d1b25637b1948a4718fa8f7b257233136bc Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 11:48:01 +0200 Subject: [ALSA] hda - Add ICH9 controller support (8086:2911) Added the missing PCI ID for ICH9 controller (8086:2911) Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7f62196989a..6e2dc4f5ca7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2184,6 +2184,7 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x269a), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x284b), .driver_data = AZX_DRIVER_ICH }, + { PCI_DEVICE(0x8086, 0x2911), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x293e), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH }, -- cgit v1.2.3 From 6dda9f4a95905f2b38e79e3737da5e25397e6acb Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:05:31 +0200 Subject: [ALSA] hda - Add ALC663 support Added the support of ALC663 codec, including specific models for ASUS M51VA, ASUS G71V, ASUS H13 and ASUS G50V. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 289 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 286 insertions(+), 3 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b0a2a262ece..c659588e26d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -163,6 +163,10 @@ enum { ALC662_LENOVO_101E, ALC662_ASUS_EEEPC_P701, ALC662_ASUS_EEEPC_EP20, + ALC663_ASUS_M51VA, + ALC663_ASUS_G71V, + ALC663_ASUS_H13, + ALC663_ASUS_G50V, ALC662_AUTO, ALC662_MODEL_LAST, }; @@ -13251,6 +13255,23 @@ static struct hda_input_mux alc662_eeepc_capture_source = { }, }; +static struct hda_input_mux alc663_capture_source = { + .num_items = 3, + .items = { + { "Mic", 0x0 }, + { "Front Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; + +static struct hda_input_mux alc663_m51va_capture_source = { + .num_items = 2, + .items = { + { "Ext-Mic", 0x0 }, + { "D-Mic", 0x9 }, + }, +}; + #define alc662_mux_enum_info alc_mux_enum_info #define alc662_mux_enum_get alc_mux_enum_get #define alc662_mux_enum_put alc882_mux_enum_put @@ -13431,6 +13452,44 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc663_m51va_mixer[] = { + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc663_g71v_mixer[] = { + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc663_g50v_mixer[] = { + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + 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("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc662_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -13501,6 +13560,11 @@ static struct hda_verb alc662_init_verbs[] = { {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + /* always trun on EAPD */ + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } }; @@ -13571,6 +13635,43 @@ static struct hda_verb alc662_auto_init_verbs[] = { { } }; +static struct hda_verb alc663_m51va_init_verbs[] = { + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ + + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, + + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_g71v_init_verbs[] = { + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ + /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ + + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ + + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_g50v_init_verbs[] = { + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ + + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + /* capture mixer elements */ static struct snd_kcontrol_new alc662_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), @@ -13692,6 +13793,125 @@ static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) alc662_eeepc_ep20_automute(codec); } +static void alc663_m51va_speaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); +} + +static void alc663_m51va_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); + snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); +} + +static void alc663_m51va_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_m51va_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc663_m51va_mic_automute(codec); + break; + } +} + +static void alc663_m51va_inithook(struct hda_codec *codec) +{ + alc663_m51va_speaker_automute(codec); + alc663_m51va_mic_automute(codec); +} + +static void alc663_g71v_hp_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); +} + +static void alc663_g71v_front_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, bits); +} + +static void alc663_g71v_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_g71v_hp_automute(codec); + break; + case ALC880_FRONT_EVENT: + alc663_g71v_front_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_g71v_inithook(struct hda_codec *codec) +{ + alc663_g71v_front_automute(codec); + alc663_g71v_hp_automute(codec); + alc662_eeepc_mic_automute(codec); +} + +static void alc663_g50v_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_m51va_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_g50v_inithook(struct hda_codec *codec) +{ + alc663_m51va_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} + #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc662_loopbacks alc880_loopbacks #endif @@ -13714,14 +13934,24 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { [ALC662_LENOVO_101E] = "lenovo-101e", [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", + [ALC663_ASUS_M51VA] = "m51va", + [ALC663_ASUS_G71V] = "g71v", + [ALC663_ASUS_H13] = "h13", + [ALC663_ASUS_G50V] = "g50v", [ALC662_AUTO] = "auto", }; static struct snd_pci_quirk alc662_cfg_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V), + SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), + SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V), SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), + SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), + SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), + SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), {} }; @@ -13809,7 +14039,53 @@ static struct alc_config_preset alc662_presets[] = { .unsol_event = alc662_eeepc_ep20_unsol_event, .init_hook = alc662_eeepc_ep20_inithook, }, - + [ALC663_ASUS_M51VA] = { + .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc663_m51va_capture_source, + .unsol_event = alc663_m51va_unsol_event, + .init_hook = alc663_m51va_inithook, + }, + [ALC663_ASUS_G71V] = { + .mixers = { alc663_g71v_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc663_g71v_unsol_event, + .init_hook = alc663_g71v_inithook, + }, + [ALC663_ASUS_H13] = { + .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc663_m51va_capture_source, + .unsol_event = alc663_m51va_unsol_event, + .init_hook = alc663_m51va_inithook, + }, + [ALC663_ASUS_G50V] = { + .mixers = { alc663_g50v_mixer, alc662_capture_mixer}, + .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .input_mux = &alc663_capture_source, + .unsol_event = alc663_g50v_unsol_event, + .init_hook = alc663_g50v_inithook, + }, }; @@ -14108,11 +14384,17 @@ static int patch_alc662(struct hda_codec *codec) if (board_config != ALC662_AUTO) setup_preset(spec, &alc662_presets[board_config]); - spec->stream_name_analog = "ALC662 Analog"; + if (codec->vendor_id == 0x10ec0663) { + spec->stream_name_analog = "ALC663 Analog"; + spec->stream_name_digital = "ALC663 Digital"; + } else { + spec->stream_name_analog = "ALC662 Analog"; + spec->stream_name_digital = "ALC662 Digital"; + } + spec->stream_analog_playback = &alc662_pcm_analog_playback; spec->stream_analog_capture = &alc662_pcm_analog_capture; - spec->stream_name_digital = "ALC662 Digital"; spec->stream_digital_playback = &alc662_pcm_digital_playback; spec->stream_digital_capture = &alc662_pcm_digital_capture; @@ -14151,6 +14433,7 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc883 }, { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", .patch = patch_alc662 }, + { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, -- cgit v1.2.3 From 531240ff520406c793a110e1c0f187d931f47d66 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:10:25 +0200 Subject: [ALSA] hda - Fix vref pincap check in alc882 auto-detection Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c659588e26d..8174050da15 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6357,7 +6357,9 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) continue; vref = PIN_IN; if (1 /*i <= AUTO_PIN_FRONT_MIC*/) { - if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) & + unsigned int pincap; + pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); + if ((pincap >> AC_PINCAP_VREF_SHIFT) & AC_PINCAP_VREF_80) vref = PIN_VREF80; } -- cgit v1.2.3 From 2f8932863d243a744ccd3dc005490ad9d2eae478 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:14:47 +0200 Subject: [ALSA] hda - show correct codec chip in PCM stream names Show more exact codec chip name in the PCM stream name strings. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 47 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8174050da15..5770b9c3efa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6491,14 +6491,20 @@ static int patch_alc882(struct hda_codec *codec) if (board_config != ALC882_AUTO) setup_preset(spec, &alc882_presets[board_config]); - spec->stream_name_analog = "ALC882 Analog"; + if (codec->vendor_id == 0x10ec0885) { + spec->stream_name_analog = "ALC885 Analog"; + spec->stream_name_digital = "ALC885 Digital"; + } else { + spec->stream_name_analog = "ALC882 Analog"; + spec->stream_name_digital = "ALC882 Digital"; + } + spec->stream_analog_playback = &alc882_pcm_analog_playback; spec->stream_analog_capture = &alc882_pcm_analog_capture; /* FIXME: setup DAC5 */ /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; - spec->stream_name_digital = "ALC882 Digital"; spec->stream_digital_playback = &alc882_pcm_digital_playback; spec->stream_digital_capture = &alc882_pcm_digital_capture; @@ -8177,12 +8183,25 @@ static int patch_alc883(struct hda_codec *codec) if (board_config != ALC883_AUTO) setup_preset(spec, &alc883_presets[board_config]); - spec->stream_name_analog = "ALC883 Analog"; + switch (codec->vendor_id) { + case 0x10ec0888: + spec->stream_name_analog = "ALC888 Analog"; + spec->stream_name_digital = "ALC888 Digital"; + break; + case 0x10ec0889: + spec->stream_name_analog = "ALC889 Analog"; + spec->stream_name_digital = "ALC889 Digital"; + break; + default: + spec->stream_name_analog = "ALC883 Analog"; + spec->stream_name_digital = "ALC883 Digital"; + break; + } + spec->stream_analog_playback = &alc883_pcm_analog_playback; spec->stream_analog_capture = &alc883_pcm_analog_capture; spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture; - spec->stream_name_digital = "ALC883 Digital"; spec->stream_digital_playback = &alc883_pcm_digital_playback; spec->stream_digital_capture = &alc883_pcm_digital_capture; @@ -10680,12 +10699,18 @@ static int patch_alc268(struct hda_codec *codec) if (board_config != ALC268_AUTO) setup_preset(spec, &alc268_presets[board_config]); - spec->stream_name_analog = "ALC268 Analog"; + if (codec->vendor_id == 0x10ec0267) { + spec->stream_name_analog = "ALC267 Analog"; + spec->stream_name_digital = "ALC267 Digital"; + } else { + spec->stream_name_analog = "ALC268 Analog"; + spec->stream_name_digital = "ALC268 Digital"; + } + spec->stream_analog_playback = &alc268_pcm_analog_playback; spec->stream_analog_capture = &alc268_pcm_analog_capture; spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; - spec->stream_name_digital = "ALC268 Digital"; spec->stream_digital_playback = &alc268_pcm_digital_playback; if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) @@ -13174,11 +13199,17 @@ static int patch_alc861vd(struct hda_codec *codec) if (board_config != ALC861VD_AUTO) setup_preset(spec, &alc861vd_presets[board_config]); - spec->stream_name_analog = "ALC861VD Analog"; + if (codec->vendor_id == 0x10ec0660) { + spec->stream_name_analog = "ALC660-VD Analog"; + spec->stream_name_digital = "ALC660-VD Digital"; + } else { + spec->stream_name_analog = "ALC861VD Analog"; + spec->stream_name_digital = "ALC861VD Digital"; + } + spec->stream_analog_playback = &alc861vd_pcm_analog_playback; spec->stream_analog_capture = &alc861vd_pcm_analog_capture; - spec->stream_name_digital = "ALC861VD Digital"; spec->stream_digital_playback = &alc861vd_pcm_digital_playback; spec->stream_digital_capture = &alc861vd_pcm_digital_capture; -- cgit v1.2.3 From f9423e7a94eb2dfef3503dde76d17eaf342ab962 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 27 May 2008 12:32:25 +0200 Subject: [ALSA] hda - Fix EAPD and COEF setups for realtek codecs Fixed EAPD and COEF setups for Realtek ALC662/663, 660-VD and 888 codecs. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5770b9c3efa..cb3e0283f0c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -780,6 +780,24 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) alc_sku_automute(codec); } +/* additional initialization for ALC888 variants */ +static void alc888_coef_init(struct hda_codec *codec) +{ + unsigned int tmp; + + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); + tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); + if ((tmp & 0xf0) == 2) + /* alc888S-VC */ + snd_hda_codec_read(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, 0x830); + else + /* alc888-VB */ + snd_hda_codec_read(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, 0x3030); +} + /* 32-bit subsystem ID for BIOS loading in HD Audio codec. * 31 ~ 16 : Manufacture ID * 15 ~ 8 : SKU ID @@ -855,8 +873,10 @@ do_sku: case 0x10ec0267: case 0x10ec0268: case 0x10ec0269: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0663: case 0x10ec0862: - case 0x10ec0662: case 0x10ec0889: snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_EAPD_BTLENABLE, 2); @@ -881,7 +901,6 @@ do_sku: case 0x10ec0882: case 0x10ec0883: case 0x10ec0885: - case 0x10ec0888: case 0x10ec0889: snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); @@ -893,6 +912,9 @@ do_sku: AC_VERB_SET_PROC_COEF, tmp | 0x2010); break; + case 0x10ec0888: + alc888_coef_init(codec); + break; case 0x10ec0267: case 0x10ec0268: snd_hda_codec_write(codec, 0x20, 0, @@ -8214,6 +8236,9 @@ static int patch_alc883(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC883_AUTO) spec->init_hook = alc883_auto_init; + else if (codec->vendor_id == 0x10ec0888) + spec->init_hook = alc888_coef_init; + #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc883_loopbacks; @@ -12662,6 +12687,12 @@ static struct hda_verb alc861vd_eapd_verbs[] = { { } }; +static struct hda_verb alc660vd_eapd_verbs[] = { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -13202,6 +13233,8 @@ static int patch_alc861vd(struct hda_codec *codec) if (codec->vendor_id == 0x10ec0660) { spec->stream_name_analog = "ALC660-VD Analog"; spec->stream_name_digital = "ALC660-VD Digital"; + /* always turn on EAPD */ + spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs; } else { spec->stream_name_analog = "ALC861VD Analog"; spec->stream_name_digital = "ALC861VD Digital"; -- cgit v1.2.3 From 17bba1b72d190742c99a140154f0abac9c1996c3 Mon Sep 17 00:00:00 2001 From: Jiang zhe Date: Wed, 4 Jun 2008 12:11:07 +0200 Subject: [ALSA] hda - support intel DG33 motherboards These two motherboards's pin configuration are not covered by driver. I wrote a new model to support them. Signed-off-by: Jiang zhe Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 107 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cb3e0283f0c..048cb84721f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -209,6 +209,7 @@ enum { ALC883_MITAC, ALC883_CLEVO_M720, ALC883_FUJITSU_PI2515, + ALC883_3ST_6ch_INTEL, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -6603,6 +6604,16 @@ static struct hda_input_mux alc883_capture_source = { }, }; +static struct hda_input_mux alc883_3stack_6ch_intel = { + .num_items = 4, + .items = { + { "Mic", 0x1 }, + { "Front Mic", 0x0 }, + { "Line", 0x2 }, + { "CD", 0x4 }, + }, +}; + static struct hda_input_mux alc883_lenovo_101e_capture_source = { .num_items = 2, .items = { @@ -6683,6 +6694,48 @@ static struct hda_channel_mode alc883_3ST_6ch_modes[3] = { { 6, alc883_3ST_ch6_init }, }; +/* + * 2ch mode + */ +static struct hda_verb alc883_3ST_ch2_intel_init[] = { + { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { } /* end */ +}; + +/* + * 4ch mode + */ +static struct hda_verb alc883_3ST_ch4_intel_init[] = { + { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc883_3ST_ch6_intel_init[] = { + { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { } /* end */ +}; + +static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { + { 2, alc883_3ST_ch2_intel_init }, + { 4, alc883_3ST_ch4_intel_init }, + { 6, alc883_3ST_ch6_intel_init }, +}; + /* * 6ch mode */ @@ -6915,6 +6968,45 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, + HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone 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("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_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_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 2, + .info = alc883_mux_enum_info, + .get = alc883_mux_enum_get, + .put = alc883_mux_enum_put, + }, + { } /* end */ +}; + static struct snd_kcontrol_new alc883_fivestack_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -7763,6 +7855,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_MITAC] = "mitac", [ALC883_CLEVO_M720] = "clevo-m720", [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", + [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", [ALC883_AUTO] = "auto", }; @@ -7820,6 +7913,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), + SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), + SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), {} }; @@ -7858,6 +7953,18 @@ static struct alc_config_preset alc883_presets[] = { .need_dac_fix = 1, .input_mux = &alc883_capture_source, }, + [ALC883_3ST_6ch_INTEL] = { + .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, + .init_verbs = { alc883_init_verbs }, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .dig_in_nid = ALC883_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), + .channel_mode = alc883_3ST_6ch_intel_modes, + .need_dac_fix = 1, + .input_mux = &alc883_3stack_6ch_intel, + }, [ALC883_6ST_DIG] = { .mixers = { alc883_base_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, -- cgit v1.2.3 From 2c3bf9abb11dd8050cd2d153917d1746c8d5af05 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Jun 2008 12:39:38 +0200 Subject: [ALSA] hda - Fix PLL gating control on Realtek codecs On some Realtek codecs, the analog PLL gating control bit must be set off while the default value is 1. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 048cb84721f..7997e13b59a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -285,6 +285,10 @@ struct alc_spec { #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; #endif + + /* for PLL fix */ + hda_nid_t pll_nid; + unsigned int pll_coef_idx, pll_coef_bit; }; /* @@ -752,6 +756,38 @@ static struct hda_verb alc_gpio3_init_verbs[] = { { } }; +/* + * Fix hardware PLL issue + * On some codecs, the analog PLL gating control must be off while + * the default value is 1. + */ +static void alc_fix_pll(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + unsigned int val; + + if (!spec->pll_nid) + return; + snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, + spec->pll_coef_idx); + val = snd_hda_codec_read(codec, spec->pll_nid, 0, + AC_VERB_GET_PROC_COEF, 0); + snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, + spec->pll_coef_idx); + snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, + val & ~(1 << spec->pll_coef_bit)); +} + +static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, + unsigned int coef_idx, unsigned int coef_bit) +{ + struct alc_spec *spec = codec->spec; + spec->pll_nid = nid; + spec->pll_coef_idx = coef_idx; + spec->pll_coef_bit = coef_bit; + alc_fix_pll(codec); +} + static void alc_sku_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -2400,6 +2436,8 @@ static int alc_init(struct hda_codec *codec) struct alc_spec *spec = codec->spec; unsigned int i; + alc_fix_pll(codec); + for (i = 0; i < spec->num_init_verbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); @@ -8286,6 +8324,8 @@ static int patch_alc883(struct hda_codec *codec) codec->spec = spec; + alc_fix_pll_init(codec, 0x20, 0x0a, 10); + board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, alc883_models, alc883_cfg_tbl); @@ -9886,6 +9926,8 @@ static int patch_alc262(struct hda_codec *codec) } #endif + alc_fix_pll_init(codec, 0x20, 0x0a, 10); + board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, alc262_models, alc262_cfg_tbl); @@ -11196,6 +11238,8 @@ static int patch_alc269(struct hda_codec *codec) codec->spec = spec; + alc_fix_pll_init(codec, 0x20, 0x04, 15); + board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, alc269_models, alc269_cfg_tbl); @@ -14531,6 +14575,8 @@ static int patch_alc662(struct hda_codec *codec) codec->spec = spec; + alc_fix_pll_init(codec, 0x20, 0x04, 15); + board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, alc662_models, alc662_cfg_tbl); -- cgit v1.2.3 From 607d982bbea2a14b5b77cc7689f509d588e1e6da Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 4 Jun 2008 12:41:21 +0200 Subject: [ALSA] hda - increase max_codecs of ICH to 4 It turned out that some ICH9-based boards use SD3 for the audio codec where the current driver code doesn't probe. Since we have a better codec slot check now, it must be safe to increase this to 4. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 6e2dc4f5ca7..dc68709e756 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1104,7 +1104,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) */ static unsigned int azx_max_codecs[] __devinitdata = { - [AZX_DRIVER_ICH] = 3, + [AZX_DRIVER_ICH] = 4, /* Some ICH9 boards use SD3 */ [AZX_DRIVER_SCH] = 3, [AZX_DRIVER_ATI] = 4, [AZX_DRIVER_ATIHDMI] = 4, -- cgit v1.2.3 From 36ca6e133ae3a57318a3ad8a41b2f005e3934c29 Mon Sep 17 00:00:00 2001 From: Akio Idehara Date: Mon, 9 Jun 2008 22:57:40 +0900 Subject: [ALSA] hda - Add Toshiba dynabook SS RX1 support I have Toshiba dynabook SS RX1 and this patch adds that support. Signed-off-by: Akio Idehara Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7997e13b59a..61f8c13b2bb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9719,6 +9719,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), + SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", + ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), -- cgit v1.2.3 From 675f25d4d3ff6501cbce608bcc2333a56ec4c105 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jun 2008 17:53:20 +0200 Subject: ALSA: hda - Add bdl_pos_adj option Added a new option, bdl_pos_adj, to adjust the delay of IRQ-wakeup timing. Most HD-audio hardwares have a problem that a BDL IRQ is issued before actually the data and the DMA pointer are updated. We have already a mechanism to force to delay snd_pcm_period_elapsed() calls via workq, but this costs much CPU, and typically the delay is within one sample. Thus, it's more clever to adjust the BDL entries instead. The new option adds the size of the delay in frames. As default, it's set to 1 -- that is, one sample delay. Even the hardware is really correct, one sample delay is relatively harmless in comparison with reporting wrong positions. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 117 +++++++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 32 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index dc68709e756..1ec3fd4c894 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -58,6 +58,7 @@ static int position_fix[SNDRV_CARDS]; static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int single_cmd; static int enable_msi; +static int bdl_pos_adj = 1; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); @@ -77,6 +78,8 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " "(for debugging only)."); module_param(enable_msi, int, 0444); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); +module_param(bdl_pos_adj, int, 0644); +MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset"); #ifdef CONFIG_SND_HDA_POWER_SAVE /* power_save option is defined in hda_codec.c */ @@ -309,7 +312,8 @@ struct azx_dev { unsigned int opened :1; unsigned int running :1; - unsigned int irq_pending: 1; + unsigned int irq_pending :1; + unsigned int irq_ignore :1; }; /* CORB/RIRB */ @@ -943,6 +947,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); if (!azx_dev->substream || !azx_dev->running) continue; + /* ignore the first dummy IRQ (due to pos_adj) */ + if (azx_dev->irq_ignore) { + azx_dev->irq_ignore = 0; + continue; + } /* check whether this IRQ is really acceptable */ if (azx_position_ok(chip, azx_dev)) { azx_dev->irq_pending = 0; @@ -976,15 +985,54 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) } +/* + * set up a BDL entry + */ +static int setup_bdle(struct snd_pcm_substream *substream, + struct azx_dev *azx_dev, u32 **bdlp, + int ofs, int size, int with_ioc) +{ + struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); + u32 *bdl = *bdlp; + + while (size > 0) { + dma_addr_t addr; + int chunk; + + if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) + return -EINVAL; + + addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); + /* program the address field of the BDL entry */ + bdl[0] = cpu_to_le32((u32)addr); + bdl[1] = cpu_to_le32(upper_32bit(addr)); + /* program the size field of the BDL entry */ + chunk = PAGE_SIZE - (ofs % PAGE_SIZE); + if (size < chunk) + chunk = size; + bdl[2] = cpu_to_le32(chunk); + /* program the IOC to enable interrupt + * only when the whole fragment is processed + */ + size -= chunk; + bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01); + bdl += 4; + azx_dev->frags++; + ofs += chunk; + } + *bdlp = bdl; + return ofs; +} + /* * set up BDL entries */ static int azx_setup_periods(struct snd_pcm_substream *substream, struct azx_dev *azx_dev) { - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); u32 *bdl; int i, ofs, periods, period_bytes; + int pos_adj = 0; /* reset BDL address */ azx_sd_writel(azx_dev, SD_BDLPL, 0); @@ -998,39 +1046,44 @@ static int azx_setup_periods(struct snd_pcm_substream *substream, bdl = (u32 *)azx_dev->bdl.area; ofs = 0; azx_dev->frags = 0; - for (i = 0; i < periods; i++) { - int size, rest; - if (i >= AZX_MAX_BDL_ENTRIES) { - snd_printk(KERN_ERR "Too many BDL entries: " - "buffer=%d, period=%d\n", - azx_dev->bufsize, period_bytes); - /* reset */ - azx_sd_writel(azx_dev, SD_BDLPL, 0); - azx_sd_writel(azx_dev, SD_BDLPU, 0); - return -EINVAL; + azx_dev->irq_ignore = 0; + if (bdl_pos_adj > 0) { + struct snd_pcm_runtime *runtime = substream->runtime; + pos_adj = (bdl_pos_adj * runtime->rate + 47999) / 48000; + if (!pos_adj) + pos_adj = 1; + pos_adj = frames_to_bytes(runtime, pos_adj); + if (pos_adj >= period_bytes) { + snd_printk(KERN_WARNING "Too big adjustment %d\n", + bdl_pos_adj); + pos_adj = 0; + } else { + ofs = setup_bdle(substream, azx_dev, + &bdl, ofs, pos_adj, 1); + if (ofs < 0) + goto error; + azx_dev->irq_ignore = 1; } - rest = period_bytes; - do { - dma_addr_t addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); - /* program the address field of the BDL entry */ - bdl[0] = cpu_to_le32((u32)addr); - bdl[1] = cpu_to_le32(upper_32bit(addr)); - /* program the size field of the BDL entry */ - size = PAGE_SIZE - (ofs % PAGE_SIZE); - if (rest < size) - size = rest; - bdl[2] = cpu_to_le32(size); - /* program the IOC to enable interrupt - * only when the whole fragment is processed - */ - rest -= size; - bdl[3] = rest ? 0 : cpu_to_le32(0x01); - bdl += 4; - azx_dev->frags++; - ofs += size; - } while (rest > 0); + } + for (i = 0; i < periods; i++) { + if (i == periods - 1 && pos_adj) + ofs = setup_bdle(substream, azx_dev, &bdl, ofs, + period_bytes - pos_adj, 0); + else + ofs = setup_bdle(substream, azx_dev, &bdl, ofs, + period_bytes, 1); + if (ofs < 0) + goto error; } return 0; + + error: + snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n", + azx_dev->bufsize, period_bytes); + /* reset */ + azx_sd_writel(azx_dev, SD_BDLPL, 0); + azx_sd_writel(azx_dev, SD_BDLPU, 0); + return -EINVAL; } /* -- cgit v1.2.3 From d2e1c97331d37a477ef7e9a272b4de4e53b893be Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jun 2008 17:53:34 +0200 Subject: ALSA: hda - remove position_fix=3 position_fix=3 is the option to correct the DMA position with the FIFO size. But, it never worked correctly, and we have now more other workarounds for the DMA position fixes. Thus better to remove it. Also, change POS_FIX_NONE to POS_FIX_LPIB to represent its real role better. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1ec3fd4c894..0ff8b9b9629 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -70,7 +70,7 @@ module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param_array(position_fix, int, NULL, 0444); MODULE_PARM_DESC(position_fix, "Fix DMA pointer " - "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); + "(0 = auto, 1 = none, 2 = POSBUF)."); module_param_array(probe_mask, int, NULL, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); module_param(single_cmd, bool, 0444); @@ -266,9 +266,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; /* position fix mode */ enum { POS_FIX_AUTO, - POS_FIX_NONE, + POS_FIX_LPIB, POS_FIX_POSBUF, - POS_FIX_FIFO, }; /* Defines for ATI HD Audio support in SB450 south bridge */ @@ -1506,8 +1505,6 @@ static unsigned int azx_get_position(struct azx *chip, } else { /* read LPIB */ pos = azx_sd_readl(azx_dev, SD_LPIB); - if (chip->position_fix == POS_FIX_FIFO) - pos += azx_dev->fifo_size; } if (pos >= azx_dev->bufsize) pos = 0; @@ -1542,7 +1539,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) printk(KERN_WARNING "hda-intel: Invalid position buffer, " "using LPIB read method instead.\n"); - chip->position_fix = POS_FIX_NONE; + chip->position_fix = POS_FIX_LPIB; pos = azx_get_position(chip, azx_dev); } else chip->position_fix = POS_FIX_POSBUF; @@ -1917,9 +1914,9 @@ static int azx_dev_free(struct snd_device *device) * white/black-listing for position_fix */ static struct snd_pci_quirk position_fix_list[] __devinitdata = { - SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), - SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_NONE), - SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_NONE), + SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), {} }; -- cgit v1.2.3 From 555e219ffaeecbd08d1603e1551188483e7e3b64 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jun 2008 17:53:34 +0200 Subject: ALSA: hda - bdl_pos_adj option to each instance The option bdl_pos_adj should be provided for each card instance instead of a global one because the value depends rather on each controller-chip. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 0ff8b9b9629..ddae3c479a8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -55,10 +55,10 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static char *model[SNDRV_CARDS]; static int position_fix[SNDRV_CARDS]; +static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int single_cmd; static int enable_msi; -static int bdl_pos_adj = 1; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); @@ -71,6 +71,8 @@ MODULE_PARM_DESC(model, "Use the given board model."); module_param_array(position_fix, int, NULL, 0444); MODULE_PARM_DESC(position_fix, "Fix DMA pointer " "(0 = auto, 1 = none, 2 = POSBUF)."); +module_param_array(bdl_pos_adj, int, NULL, 0644); +MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); module_param_array(probe_mask, int, NULL, 0444); MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); module_param(single_cmd, bool, 0444); @@ -78,8 +80,6 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " "(for debugging only)."); module_param(enable_msi, int, 0444); MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); -module_param(bdl_pos_adj, int, 0644); -MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset"); #ifdef CONFIG_SND_HDA_POWER_SAVE /* power_save option is defined in hda_codec.c */ @@ -330,6 +330,7 @@ struct azx_rb { struct azx { struct snd_card *card; struct pci_dev *pci; + int dev_index; /* chip type specific */ int driver_type; @@ -1026,12 +1027,13 @@ static int setup_bdle(struct snd_pcm_substream *substream, /* * set up BDL entries */ -static int azx_setup_periods(struct snd_pcm_substream *substream, +static int azx_setup_periods(struct azx *chip, + struct snd_pcm_substream *substream, struct azx_dev *azx_dev) { u32 *bdl; int i, ofs, periods, period_bytes; - int pos_adj = 0; + int pos_adj; /* reset BDL address */ azx_sd_writel(azx_dev, SD_BDLPL, 0); @@ -1046,15 +1048,16 @@ static int azx_setup_periods(struct snd_pcm_substream *substream, ofs = 0; azx_dev->frags = 0; azx_dev->irq_ignore = 0; - if (bdl_pos_adj > 0) { + pos_adj = bdl_pos_adj[chip->dev_index]; + if (pos_adj > 0) { struct snd_pcm_runtime *runtime = substream->runtime; - pos_adj = (bdl_pos_adj * runtime->rate + 47999) / 48000; + pos_adj = (pos_adj * runtime->rate + 47999) / 48000; if (!pos_adj) pos_adj = 1; pos_adj = frames_to_bytes(runtime, pos_adj); if (pos_adj >= period_bytes) { snd_printk(KERN_WARNING "Too big adjustment %d\n", - bdl_pos_adj); + bdl_pos_adj[chip->dev_index]); pos_adj = 0; } else { ofs = setup_bdle(substream, azx_dev, @@ -1063,7 +1066,8 @@ static int azx_setup_periods(struct snd_pcm_substream *substream, goto error; azx_dev->irq_ignore = 1; } - } + } else + pos_adj = 0; for (i = 0; i < periods; i++) { if (i == periods - 1 && pos_adj) ofs = setup_bdle(substream, azx_dev, &bdl, ofs, @@ -1388,7 +1392,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", azx_dev->bufsize, azx_dev->format_val); - if (azx_setup_periods(substream, azx_dev) < 0) + if (azx_setup_periods(chip, substream, azx_dev) < 0) return -EINVAL; azx_setup_controller(chip, azx_dev); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -2001,6 +2005,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->irq = -1; chip->driver_type = driver_type; chip->msi = enable_msi; + chip->dev_index = dev; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); chip->position_fix = check_position_fix(chip, position_fix[dev]); -- cgit v1.2.3 From 5c0d7bc103dd1ae85967fbcf70be8d1ae3aa3d79 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jun 2008 17:53:35 +0200 Subject: ALSA: hda - Fix bdl_pos_adj value for ATI SB chipsets ATI SB controllers seem to report the DMA ahead in the amount of FIFO. Thus bdl_pos_adj should be 32 for them as default. Also, the default value is set to -1, which means to make the driver to choose the appropriate value. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ddae3c479a8..9b2dc0669b9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -55,7 +55,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static char *model[SNDRV_CARDS]; static int position_fix[SNDRV_CARDS]; -static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; +static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int single_cmd; static int enable_msi; @@ -2013,6 +2013,18 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->single_cmd = single_cmd; + if (bdl_pos_adj[dev] < 0) { + switch (chip->driver_type) { + case AZX_DRIVER_ATI: + case AZX_DRIVER_ATIHDMI: + bdl_pos_adj[dev] = 32; + break; + default: + bdl_pos_adj[dev] = 1; + break; + } + } + #if BITS_PER_LONG != 64 /* Fix up base address on ULI M5461 */ if (chip->driver_type == AZX_DRIVER_ULI) { -- cgit v1.2.3 From a6a950a8a8e1431e8527809339e089ac926a7d34 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Jun 2008 17:53:35 +0200 Subject: ALSA: hda - Add a warning if pending IRQ is found The pending IRQ handling is a very hackish workaround and should be avoided as much as possible via a larger bdl_pos_adj option value. Put a warning message if this situation occurs so that the user may have a chance to notice that something is wrong. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9b2dc0669b9..ec4ae2d9400 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -374,6 +374,7 @@ struct azx { unsigned int single_cmd :1; unsigned int polling_mode :1; unsigned int msi :1; + unsigned int irq_pending_warned :1; /* for debugging */ unsigned int last_cmd; /* last issued command (to sync) */ @@ -1562,6 +1563,14 @@ static void azx_irq_pending_work(struct work_struct *work) struct azx *chip = container_of(work, struct azx, irq_pending_work); int i, pending; + if (!chip->irq_pending_warned) { + printk(KERN_WARNING + "hda-intel: IRQ timing workaround is activated " + "for card #%d. Suggest a bigger bdl_pos_adj.\n", + chip->card->number); + chip->irq_pending_warned = 1; + } + for (;;) { pending = 0; spin_lock_irq(&chip->reg_lock); -- cgit v1.2.3 From 4549915cdf468019d2fd86485dd8d2ab426b8d85 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Jun 2008 16:27:24 +0200 Subject: ALSA: hda - Fix stac9205_cfg_tbl Sort stac9205_cfg_table in the order of id numbers, and removed the duplicated (obsoleted) entries for 0x01fc and 0x01fd. This doesn't change the driver behavior since the old entries are all secondary. The duplication occured due to commit dfe495d0, and the old entries were introduced by commit ae0a8ed8. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a4f44a00bae..1ef3dd6e8a6 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1754,12 +1754,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { "unknown Dell", STAC_9205_DELL_M42), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, "Dell Precision", STAC_9205_DELL_M43), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c, - "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, "Dell Precision", STAC_9205_DELL_M43), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, - "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, @@ -1770,18 +1766,14 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, "Dell Precision M4300", STAC_9205_DELL_M43), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, - "Dell Precision", STAC_9205_DELL_M43), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, - "Dell Inspiron", STAC_9205_DELL_M44), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, - "Dell Inspiron", STAC_9205_DELL_M44), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, - "Dell Inspiron", STAC_9205_DELL_M44), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd, - "Dell Inspiron", STAC_9205_DELL_M44), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204, "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c, + "Dell Precision", STAC_9205_DELL_M43), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, "Dell Inspiron", STAC_9205_DELL_M44), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, -- cgit v1.2.3 From 149b154452b18dedd4559cdd65b965ae9011e425 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Jun 2008 17:43:36 +0200 Subject: ALSA: hda - Remove unused mutex Removed unused mutex from patch_*.c. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 5 ----- sound/pci/hda/patch_conexant.c | 4 ---- 2 files changed, 9 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index a99e86d7427..55ce897ef0b 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "hda_codec.h" @@ -64,7 +63,6 @@ struct ad198x_spec { /* PCM information */ struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ - struct mutex amp_mutex; /* PCM volume/mute control mutex */ unsigned int spdif_route; /* dynamic controls, init_verbs and input_mux */ @@ -3177,7 +3175,6 @@ static int patch_ad1884(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -3847,7 +3844,6 @@ static int patch_ad1884a(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -4152,7 +4148,6 @@ static int patch_ad1882(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 6; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 36fd8526003..e3df8ac3707 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -82,7 +82,6 @@ struct conexant_spec { /* PCM information */ struct hda_pcm pcm_rec[2]; /* used in build_pcms() */ - struct mutex amp_mutex; /* PCM volume/mute control mutex */ unsigned int spdif_route; /* dynamic controls, init_verbs and input_mux */ @@ -928,7 +927,6 @@ static int patch_cxt5045(struct hda_codec *codec) spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -1477,7 +1475,6 @@ static int patch_cxt5047(struct hda_codec *codec) spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; spec->multiout.max_channels = 2; @@ -1736,7 +1733,6 @@ static int patch_cxt5051(struct hda_codec *codec) spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; - mutex_init(&spec->amp_mutex); codec->spec = spec; codec->patch_ops = conexant_patch_ops; -- cgit v1.2.3 From aafc4412be31306e5c38bd4e4581066507503adc Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 13 Jun 2008 18:04:33 +0200 Subject: ALSA: hda: Add support for 92HD73xxx codecs Added support for new family of IDT codecs. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 47 +++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 1ef3dd6e8a6..c4f3489376c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -636,21 +636,28 @@ static struct hda_verb stac92hd71bxx_core_init[] = { { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, }; +#define HD_DISABLE_PORTF 3 static struct hda_verb stac92hd71bxx_analog_core_init[] = { + /* start of config #1 */ + + /* connect port 0f to audio mixer */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ + /* unmute right and left channels for node 0x0f */ + { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + /* start of config #2 */ + /* set master volume and direct control */ { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* connect headphone jack to dac1 */ { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, - /* connect ports 0d and 0f to audio mixer */ + /* connect port 0d to audio mixer */ { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2}, - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ /* unmute dac0 input in audio mixer */ { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, - /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ + /* unmute right and left channels for nodes 0x0a, 0xd */ { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {} }; @@ -1317,13 +1324,13 @@ static unsigned int ref92hd71bxx_pin_configs[10] = { 0x90a000f0, 0x01452050, }; -static unsigned int dell_m4_1_pin_configs[13] = { +static unsigned int dell_m4_1_pin_configs[10] = { 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, 0x40f000f0, 0x4f0000f0, }; -static unsigned int dell_m4_2_pin_configs[13] = { +static unsigned int dell_m4_2_pin_configs[10] = { 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x044413b0, @@ -3095,13 +3102,16 @@ static int stac92xx_init(struct hda_codec *codec) 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], 0, AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = get_defcfg_connect(def_conf); /* outputs are only ports capable of power management * any attempts on powering down a input port cause the * referenced VREF to act quirky. */ if (pinctl & AC_PINCTL_IN_EN) continue; - if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) + /* skip any ports that don't have jacks since presence + * detection is useless */ + if (def_conf && def_conf != AC_JACK_PORT_FIXED) continue; enable_pin_detect(codec, spec->pwr_nids[i], event | i); codec->patch_ops.unsol_event(codec, (event | i) << 26); @@ -3606,6 +3616,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); + spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); spec->pin_nids = stac92hd71bxx_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_92HD71BXX_MODELS, @@ -3634,6 +3645,19 @@ again: spec->mixer = stac92hd71bxx_mixer; spec->init = stac92hd71bxx_core_init; break; + case 0x111d7608: /* 5 Port with Analog Mixer */ + /* no output amps */ + spec->num_pwrs = 0; + spec->mixer = stac92hd71bxx_analog_mixer; + + /* disable VSW */ + spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; + stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); + break; + case 0x111d7603: /* 6 Port with Analog Mixer */ + /* no output amps */ + spec->num_pwrs = 0; + /* fallthru */ default: spec->mixer = stac92hd71bxx_analog_mixer; spec->init = stac92hd71bxx_analog_core_init; @@ -3652,15 +3676,13 @@ again: spec->adc_nids = stac92hd71bxx_adc_nids; spec->dmic_nids = stac92hd71bxx_dmic_nids; spec->dmux_nids = stac92hd71bxx_dmux_nids; + spec->pwr_nids = stac92hd71bxx_pwr_nids; spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); spec->num_dmics = STAC92HD71BXX_NUM_DMICS; spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); - spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); - spec->pwr_nids = stac92hd71bxx_pwr_nids; - spec->multiout.num_dacs = 1; spec->multiout.hp_nid = 0x11; spec->multiout.dac_nids = stac92hd71bxx_dac_nids; @@ -4298,10 +4320,11 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, + { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, + { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, - { .id = 0x111d7608, .name = "92HD71BXX", .patch = patch_stac92hd71bxx }, { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, -- cgit v1.2.3 From 0c6341ace5efb14a0da08482e299b3c158e0d5fb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Jun 2008 20:50:27 +0200 Subject: ALSA: hda - bdl_pos_adj=32 as default Use bdl_pos_adj=32 as default except for Intel hardwares confirmed to work with bdl_pos_adj=1. Looks like ATI and NVidia require this higher value. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ec4ae2d9400..539d20102c3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2024,12 +2024,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, if (bdl_pos_adj[dev] < 0) { switch (chip->driver_type) { - case AZX_DRIVER_ATI: - case AZX_DRIVER_ATIHDMI: - bdl_pos_adj[dev] = 32; + case AZX_DRIVER_ICH: + bdl_pos_adj[dev] = 1; break; default: - bdl_pos_adj[dev] = 1; + bdl_pos_adj[dev] = 32; break; } } -- cgit v1.2.3 From 766979e09d302315f314bfd96fdd83f8f9896d9c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Jun 2008 20:53:56 +0200 Subject: ALSA: hda - use upper_32_bits() Use the standard upper_32_bits() instead of own macro. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 539d20102c3..16715a68ba5 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -440,11 +440,6 @@ static char *driver_short_names[] __devinitdata = { /* for pcm support */ #define get_azx_dev(substream) (substream->runtime->private_data) -/* Get the upper 32bit of the given dma_addr_t - * Compiler should optimize and eliminate the code if dma_addr_t is 32bit - */ -#define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0) - static int azx_acquire_irq(struct azx *chip, int do_disconnect); /* @@ -475,7 +470,7 @@ static void azx_init_cmd_io(struct azx *chip) chip->corb.addr = chip->rb.addr; chip->corb.buf = (u32 *)chip->rb.area; azx_writel(chip, CORBLBASE, (u32)chip->corb.addr); - azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr)); + azx_writel(chip, CORBUBASE, upper_32_bits(chip->corb.addr)); /* set the corb size to 256 entries (ULI requires explicitly) */ azx_writeb(chip, CORBSIZE, 0x02); @@ -490,7 +485,7 @@ static void azx_init_cmd_io(struct azx *chip) chip->rirb.addr = chip->rb.addr + 2048; chip->rirb.buf = (u32 *)(chip->rb.area + 2048); azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); - azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr)); + azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr)); /* set the rirb size to 256 entries (ULI requires explicitly) */ azx_writeb(chip, RIRBSIZE, 0x02); @@ -861,7 +856,7 @@ static void azx_init_chip(struct azx *chip) /* program the position buffer */ azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); - azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); + azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr)); chip->initialized = 1; } @@ -1006,7 +1001,7 @@ static int setup_bdle(struct snd_pcm_substream *substream, addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); /* program the address field of the BDL entry */ bdl[0] = cpu_to_le32((u32)addr); - bdl[1] = cpu_to_le32(upper_32bit(addr)); + bdl[1] = cpu_to_le32(upper_32_bits(addr)); /* program the size field of the BDL entry */ chunk = PAGE_SIZE - (ofs % PAGE_SIZE); if (size < chunk) @@ -1138,7 +1133,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) /* lower BDL address */ azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr); /* upper BDL address */ - azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl.addr)); + azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr)); /* enable the position buffer */ if (chip->position_fix == POS_FIX_POSBUF || -- cgit v1.2.3 From 43785eaeb1cfb8aed3cf8027f298b242f88fdc45 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Jun 2008 15:47:26 +0200 Subject: ALSA: hda - Fix wrong volumes in AD1988 auto-probe mode Don't create mixer volume elements for Headphone and Speaker if they use the same DAC as normal line-outs on AD1988. Otherwise the amp value gets screwed up, e.g. https://bugzilla.novell.com/show_bug.cgi?id=398255 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 55ce897ef0b..05ca027fcc0 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -2621,7 +2621,7 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, { struct ad198x_spec *spec = codec->spec; hda_nid_t nid; - int idx, err; + int i, idx, err; char name[32]; if (! pin) @@ -2629,16 +2629,26 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, idx = ad1988_pin_idx(pin); nid = ad1988_idx_to_dac(codec, idx); - /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) - spec->multiout.hp_nid = nid; - else - spec->multiout.extra_out_nid[0] = nid; - /* control HP volume/switch on the output mixer amp */ - sprintf(name, "%s Playback Volume", pfx); - if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) - return err; + /* check whether the corresponding DAC was already taken */ + for (i = 0; i < spec->autocfg.line_outs; i++) { + hda_nid_t pin = spec->autocfg.line_out_pins[i]; + hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin)); + if (dac == nid) + break; + } + if (i >= spec->autocfg.line_outs) { + /* specify the DAC as the extra output */ + if (!spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + else + spec->multiout.extra_out_nid[0] = nid; + /* control HP volume/switch on the output mixer amp */ + sprintf(name, "%s Playback Volume", pfx); + err = add_control(spec, AD_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } nid = ad1988_mixer_nids[idx]; sprintf(name, "%s Playback Switch", pfx); if ((err = add_control(spec, AD_CTL_BIND_MUTE, name, -- cgit v1.2.3 From a1855d802fb62718192eb7e180161b08adff4e73 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 19 Jun 2008 15:41:37 +0200 Subject: ALSA: hda - Fix digital converter proc output AC_VERB_GET_DIGI_CONVERT_2 isn't actually implemented but reserved. The whole SIC bits are returned from DIGI_CONVERT_1. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.h | 2 +- sound/pci/hda/hda_proc.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index dcd390b2bba..efc682888b3 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -78,7 +78,7 @@ enum { #define AC_VERB_GET_BEEP_CONTROL 0x0f0a #define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c #define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d -#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e +#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */ #define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f /* f10-f1a: GPIO */ #define AC_VERB_GET_GPIO_DATA 0x0f15 diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 5633f77f8f3..1e5aff5c48d 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -366,8 +366,6 @@ static void print_digital_conv(struct snd_info_buffer *buffer, { unsigned int digi1 = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0); - unsigned int digi2 = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_DIGI_CONVERT_2, 0); snd_iprintf(buffer, " Digital:"); if (digi1 & AC_DIG1_ENABLE) snd_iprintf(buffer, " Enabled"); @@ -386,7 +384,8 @@ static void print_digital_conv(struct snd_info_buffer *buffer, if (digi1 & AC_DIG1_LEVEL) snd_iprintf(buffer, " GenLevel"); snd_iprintf(buffer, "\n"); - snd_iprintf(buffer, " Digital category: 0x%x\n", digi2 & AC_DIG2_CC); + snd_iprintf(buffer, " Digital category: 0x%x\n", + (digi1 >> 8) & AC_DIG2_CC); } static const char *get_pwr_state(u32 state) -- cgit v1.2.3 From 3e0e469fa216ec70c93b1593821b759d19ee2e6b Mon Sep 17 00:00:00 2001 From: Travis Place Date: Fri, 20 Jun 2008 16:51:45 +0200 Subject: ALSA: hda - Added model selection for iMac 24" Added the SSID of a known iMac 24" to automatically use ALC885_IMAC24 quirk. Signed-off-by: Travis Place Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 61f8c13b2bb..d96a8762b28 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6192,6 +6192,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), + SND_PCI_QUIRK(0x106b, 0x00a0, "Apple iMac 24''", ALC885_IMAC24), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), -- cgit v1.2.3 From 1d11604eebfc91204e3182b48d3d920f51b09d40 Mon Sep 17 00:00:00 2001 From: Travis Place Date: Mon, 23 Jun 2008 11:42:30 +0200 Subject: ALSA: hda - Added SSID for 'Fujitsu Siemens Amilo M1451G' laptop Add the SSID for the "Fujitsu Siemens Amilo M1451G" laptop to patch_realtek.c , so that it uses ALC880_FUJITSU by default. Signed-off-by: Travis Place Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d96a8762b28..4edde6094cd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3074,6 +3074,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), + SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), -- cgit v1.2.3 From c7e0757a461db87157bbf92c4f5afda87cbe05f6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 26 Jun 2008 14:42:51 +0200 Subject: ALSA: hda - Add MacBook 3.1 support MacBook 3.1 is compatible with model=mbp3. Added the codec SSID 10b6:3600. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4edde6094cd..c7d4bbb0179 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6519,8 +6519,9 @@ static int patch_alc882(struct hda_codec *codec) case 0x106b1000: /* iMac 24 */ board_config = ALC885_IMAC24; break; - case 0x106b00a1: /* Macbook */ + case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ case 0x106b2c00: /* Macbook Pro rev3 */ + case 0x106b3600: /* Macbook 3.1 */ board_config = ALC885_MBP3; break; default: -- cgit v1.2.3 From 031005f78c8d0aebc17ddf7a34af9ffd48034d7d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 26 Jun 2008 14:49:58 +0200 Subject: ALSA: hda - disable amp override on non-HP machines Some machines with Cx5045 seem to have no problem with the volume over 0dB on NID 0x17. Disable amp overrides for other devices but HP. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e3df8ac3707..64df8100593 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1005,15 +1005,19 @@ static int patch_cxt5045(struct hda_codec *codec) #endif } - /* - * Fix max PCM level to 0 dB - * (originall it has 0x2b steps with 0dB offset 0x14) - */ - snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, - (0x14 << AC_AMPCAP_OFFSET_SHIFT) | - (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) | - (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | - (1 << AC_AMPCAP_MUTE_SHIFT)); + switch (codec->subsystem_id >> 16) { + case 0x103c: + /* HP laptop has a really bad sound over 0dB on NID 0x17. + * Fix max PCM level to 0 dB + * (originall it has 0x2b steps with 0dB offset 0x14) + */ + snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, + (0x14 << AC_AMPCAP_OFFSET_SHIFT) | + (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (1 << AC_AMPCAP_MUTE_SHIFT)); + break; + } return 0; } -- cgit v1.2.3 From 0701e0640f4a1de2b509cfee508216275f81d812 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Jun 2008 16:30:57 +0200 Subject: ALSA: ALSA: hda - Fix ALC883 medion model ALC883 medion model doesn't unmute the proper amps so no output can be heard. Replaced the mute switches to behave just like other models. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c7d4bbb0179..081d1a55706 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7050,13 +7050,13 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { static struct snd_kcontrol_new alc883_fivestack_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), -- cgit v1.2.3 From 470eaf6be78424fc499a5039e5d5fe58bace2bc3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jun 2008 16:40:10 +0200 Subject: ALSA: hda - Add missing Thinkpad Z60m support Added the missing SSID of Thinkpad Z60m for model=thinkpad with AD1981HD. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 05ca027fcc0..e8003d99f0b 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1616,6 +1616,7 @@ static const char *ad1981_models[AD1981_MODELS] = { static struct snd_pci_quirk ad1981_cfg_tbl[] = { SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), + SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), /* All HP models */ SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP), SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), -- cgit v1.2.3 From 6a9dccd61253f361760802d8d19c28fa83ea83f5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 1 Jul 2008 14:52:05 +0200 Subject: ALSA: ALSA: hda - Fix speaker output on Toshiba P105 Toshiba Satellite P105 with cx5045 has no HP pin but only a speaker pin and does the speaker-muting on hardware. Thus the matching model is laptop-micsense. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 64df8100593..95e3367d887 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -906,6 +906,7 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV9533EG", CXT5045_LAPTOP_HPSENSE), SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP_HPSENSE), + SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE), SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE), -- cgit v1.2.3 From be321a890c25272965129ffe4b3b59a519fcf583 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 7 Jul 2008 16:04:04 +0200 Subject: ALSA: hda - Add support for Lenovo 3000 N200 Added the model entry (model=lenovo) for Lenovo N3000 N200 laptop with ALC861-VD. Reference below: https://bugzilla.novell.com/show_bug.cgi?id=406425 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 081d1a55706..92a709be3c4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -13004,6 +13004,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), {} }; -- cgit v1.2.3 From 7e2574050e6af203f0c94915c98c53ce1fc48044 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 8 Jul 2008 11:50:09 +0200 Subject: ALSA: hda - removed redundant gpio_mask An gpio_mask value was defined twice needlessly. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c4f3489376c..a6d138831e2 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3669,7 +3669,6 @@ again: /* GPIO0 High = EAPD */ spec->gpio_mask = 0x01; spec->gpio_dir = 0x01; - spec->gpio_mask = 0x01; spec->gpio_data = 0x01; spec->mux_nids = stac92hd71bxx_mux_nids; -- cgit v1.2.3 From 34ec8a0ae138c2787a550b930d29a9cce4900cee Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 10 Jul 2008 14:49:19 +0200 Subject: ALSA: HDA - HP dc7600 with pci sub IDs 0x103c/0x3011 belongs to hp-3013 model As reported and tested by an RedHat customer, HP dc7600 with pci sub IDs 0x103c/0x3011 works with the hp-3013 model and not with the hp only model. Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 92a709be3c4..2807bc840d2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5167,7 +5167,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), - SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), + SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), -- cgit v1.2.3 From f7c5dda23a9f4b7f8977612154daef44cc0f423b Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Thu, 10 Jul 2008 17:49:11 +0200 Subject: ALSA: hda: 92hd71bxx PC Beep Added volume controls for the analog PC Beep on 92hd71bxx codecs. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a6d138831e2..08cb77f5188 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -825,6 +825,9 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), { } /* end */ -- cgit v1.2.3 From 4090dffb1438e03a434e3747b14321440561d956 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 12 Jul 2008 12:02:45 +0200 Subject: ALSA: hda - Fix internal mic vref pin setup Set the vref80 to the internal mic pin 0x12 for Cx5045. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 95e3367d887..71c4072c926 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -686,7 +686,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { static struct hda_verb cxt5045_init_verbs[] = { /* Line in, Mic */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + {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 }, /* HP, Amp */ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -- cgit v1.2.3 From 86376df6ad0f1a7a1118cd53b0cfd679524f5436 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 12 Jul 2008 12:04:05 +0200 Subject: ALSA: hda - Fix missing init for unsol events on micsense model Fixed the missing initialization for unsolicited events on Cx5045 micsense model. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 71c4072c926..8295994665e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -962,6 +962,7 @@ static int patch_cxt5045(struct hda_codec *codec) codec->patch_ops.init = cxt5045_init; break; case CXT5045_LAPTOP_MICSENSE: + codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; spec->input_mux = &cxt5045_capture_source; spec->num_init_verbs = 2; spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; -- cgit v1.2.3 From 9e4641541e9681a568483133813332cfafa34d86 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 12 Jul 2008 12:05:25 +0200 Subject: ALSA: hda - Fix FSC V5505 model model=laptop-hpmicsense matches better to FSC V5505 laptop. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_conexant.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/pci/hda') diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 8295994665e..7c1eb23f0ce 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -910,7 +910,8 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE), - SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", CXT5045_LAPTOP_HPSENSE), + SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505", + CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE), -- cgit v1.2.3