summaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/ctxfi/ctatc.c15
-rw-r--r--sound/pci/ctxfi/ctvmem.c38
-rw-r--r--sound/pci/ctxfi/ctvmem.h8
-rw-r--r--sound/pci/hda/hda_intel.c25
-rw-r--r--sound/pci/hda/patch_realtek.c131
-rw-r--r--sound/pci/hda/patch_sigmatel.c61
-rw-r--r--sound/pci/ice1712/aureon.c12
7 files changed, 204 insertions, 86 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index cb65bd0dd35b..459c1f62783b 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -166,18 +166,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index)
{
- struct ct_vm *vm;
- void *kvirt_addr;
- unsigned long phys_addr;
-
- vm = atc->vm;
- kvirt_addr = vm->get_ptp_virt(vm, index);
- if (kvirt_addr == NULL)
- phys_addr = (~0UL);
- else
- phys_addr = virt_to_phys(kvirt_addr);
-
- return phys_addr;
+ return atc->vm->get_ptp_phys(atc->vm, index);
}
static unsigned int convert_format(snd_pcm_format_t snd_format)
@@ -1669,7 +1658,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
}
/* Set up device virtual memory management object */
- err = ct_vm_create(&atc->vm);
+ err = ct_vm_create(&atc->vm, pci);
if (err < 0)
goto error1;
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index 6b78752e9503..65da6e466f80 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -138,7 +138,7 @@ ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size)
return NULL;
}
- ptp = vm->ptp[0];
+ ptp = (unsigned long *)vm->ptp[0].area;
pte_start = (block->addr >> CT_PAGE_SHIFT);
pages = block->size >> CT_PAGE_SHIFT;
for (i = 0; i < pages; i++) {
@@ -158,25 +158,25 @@ static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block)
}
/* *
- * return the host (kmalloced) addr of the @index-th device
- * page talbe page on success, or NULL on failure.
- * The first returned NULL indicates the termination.
+ * return the host physical addr of the @index-th device
+ * page table page on success, or ~0UL on failure.
+ * The first returned ~0UL indicates the termination.
* */
-static void *
-ct_get_ptp_virt(struct ct_vm *vm, int index)
+static dma_addr_t
+ct_get_ptp_phys(struct ct_vm *vm, int index)
{
- void *addr;
+ dma_addr_t addr;
- addr = (index >= CT_PTP_NUM) ? NULL : vm->ptp[index];
+ addr = (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr;
return addr;
}
-int ct_vm_create(struct ct_vm **rvm)
+int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci)
{
struct ct_vm *vm;
struct ct_vm_block *block;
- int i;
+ int i, err = 0;
*rvm = NULL;
@@ -188,23 +188,21 @@ int ct_vm_create(struct ct_vm **rvm)
/* Allocate page table pages */
for (i = 0; i < CT_PTP_NUM; i++) {
- vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!vm->ptp[i])
+ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(pci),
+ PAGE_SIZE, &vm->ptp[i]);
+ if (err < 0)
break;
}
- if (!i) {
+ if (err < 0) {
/* no page table pages are allocated */
- kfree(vm);
+ ct_vm_destroy(vm);
return -ENOMEM;
}
vm->size = CT_ADDRS_PER_PAGE * i;
- /* Initialise remaining ptps */
- for (; i < CT_PTP_NUM; i++)
- vm->ptp[i] = NULL;
-
vm->map = ct_vm_map;
vm->unmap = ct_vm_unmap;
- vm->get_ptp_virt = ct_get_ptp_virt;
+ vm->get_ptp_phys = ct_get_ptp_phys;
INIT_LIST_HEAD(&vm->unused);
INIT_LIST_HEAD(&vm->used);
block = kzalloc(sizeof(*block), GFP_KERNEL);
@@ -242,7 +240,7 @@ void ct_vm_destroy(struct ct_vm *vm)
/* free allocated page table pages */
for (i = 0; i < CT_PTP_NUM; i++)
- kfree(vm->ptp[i]);
+ snd_dma_free_pages(&vm->ptp[i]);
vm->size = 0;
diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h
index 01e4fd0386a3..b23adfca4de6 100644
--- a/sound/pci/ctxfi/ctvmem.h
+++ b/sound/pci/ctxfi/ctvmem.h
@@ -22,6 +22,8 @@
#include <linux/mutex.h>
#include <linux/list.h>
+#include <linux/pci.h>
+#include <sound/memalloc.h>
/* The chip can handle the page table of 4k pages
* (emu20k1 can handle even 8k pages, but we don't use it right now)
@@ -41,7 +43,7 @@ struct snd_pcm_substream;
/* Virtual memory management object for card device */
struct ct_vm {
- void *ptp[CT_PTP_NUM]; /* Device page table pages */
+ struct snd_dma_buffer ptp[CT_PTP_NUM]; /* Device page table pages */
unsigned int size; /* Available addr space in bytes */
struct list_head unused; /* List of unused blocks */
struct list_head used; /* List of used blocks */
@@ -52,10 +54,10 @@ struct ct_vm {
int size);
/* Unmap device logical addr area. */
void (*unmap)(struct ct_vm *, struct ct_vm_block *block);
- void *(*get_ptp_virt)(struct ct_vm *vm, int index);
+ dma_addr_t (*get_ptp_phys)(struct ct_vm *vm, int index);
};
-int ct_vm_create(struct ct_vm **rvm);
+int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci);
void ct_vm_destroy(struct ct_vm *vm);
#endif /* CTVMEM_H */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ec9c348336cc..ff6da6f386d1 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -426,6 +426,7 @@ struct azx {
/* flags */
int position_fix;
+ int poll_count;
unsigned int running :1;
unsigned int initialized :1;
unsigned int single_cmd :1;
@@ -506,7 +507,7 @@ static char *driver_short_names[] __devinitdata = {
#define get_azx_dev(substream) (substream->runtime->private_data)
static int azx_acquire_irq(struct azx *chip, int do_disconnect);
-
+static int azx_send_cmd(struct hda_bus *bus, unsigned int val);
/*
* Interface for HD codec
*/
@@ -664,11 +665,12 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
{
struct azx *chip = bus->private_data;
unsigned long timeout;
+ int do_poll = 0;
again:
timeout = jiffies + msecs_to_jiffies(1000);
for (;;) {
- if (chip->polling_mode) {
+ if (chip->polling_mode || do_poll) {
spin_lock_irq(&chip->reg_lock);
azx_update_rirb(chip);
spin_unlock_irq(&chip->reg_lock);
@@ -676,6 +678,9 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
if (!chip->rirb.cmds[addr]) {
smp_rmb();
bus->rirb_error = 0;
+
+ if (!do_poll)
+ chip->poll_count = 0;
return chip->rirb.res[addr]; /* the last value */
}
if (time_after(jiffies, timeout))
@@ -688,6 +693,16 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
}
}
+ if (!chip->polling_mode && chip->poll_count < 2) {
+ snd_printdd(SFX "azx_get_response timeout, "
+ "polling the codec once: last cmd=0x%08x\n",
+ chip->last_cmd[addr]);
+ do_poll = 1;
+ chip->poll_count++;
+ goto again;
+ }
+
+
if (!chip->polling_mode) {
snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
"switching to polling mode: last cmd=0x%08x\n",
@@ -1878,6 +1893,9 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
if (!bdl_pos_adj[chip->dev_index])
return 1; /* no delayed ack */
+ if (WARN_ONCE(!azx_dev->period_bytes,
+ "hda-intel: zero azx_dev->period_bytes"))
+ return 0; /* this shouldn't happen! */
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 */
@@ -2043,7 +2061,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
{
if (request_irq(chip->pci->irq, azx_interrupt,
chip->msi ? 0 : IRQF_SHARED,
- "HDA Intel", chip)) {
+ "hda_intel", chip)) {
printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
"disabling device\n", chip->pci->irq);
if (do_disconnect)
@@ -2332,6 +2350,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
*/
static struct snd_pci_quirk msi_black_list[] __devinitdata = {
SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
+ SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
{}
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e3caa78ccd54..da34095c707f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1093,6 +1093,16 @@ static void alc889_coef_init(struct hda_codec *codec)
snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
}
+/* turn on/off EAPD control (only if available) */
+static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
+{
+ if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
+ return;
+ if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
+ on ? 2 : 0);
+}
+
static void alc_auto_init_amp(struct hda_codec *codec, int type)
{
unsigned int tmp;
@@ -1110,25 +1120,22 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
case ALC_INIT_DEFAULT:
switch (codec->vendor_id) {
case 0x10ec0260:
- snd_hda_codec_write(codec, 0x0f, 0,
- AC_VERB_SET_EAPD_BTLENABLE, 2);
- snd_hda_codec_write(codec, 0x10, 0,
- AC_VERB_SET_EAPD_BTLENABLE, 2);
+ set_eapd(codec, 0x0f, 1);
+ set_eapd(codec, 0x10, 1);
break;
case 0x10ec0262:
case 0x10ec0267:
case 0x10ec0268:
case 0x10ec0269:
+ case 0x10ec0270:
case 0x10ec0272:
case 0x10ec0660:
case 0x10ec0662:
case 0x10ec0663:
case 0x10ec0862:
case 0x10ec0889:
- snd_hda_codec_write(codec, 0x14, 0,
- AC_VERB_SET_EAPD_BTLENABLE, 2);
- snd_hda_codec_write(codec, 0x15, 0,
- AC_VERB_SET_EAPD_BTLENABLE, 2);
+ set_eapd(codec, 0x14, 1);
+ set_eapd(codec, 0x15, 1);
break;
}
switch (codec->vendor_id) {
@@ -1230,6 +1237,8 @@ static void alc_init_auto_mic(struct hda_codec *codec)
return; /* invalid entry */
}
}
+ if (!ext || !fixed)
+ return;
if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
return; /* no unsol support */
snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
@@ -1834,10 +1843,8 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
#ifdef CONFIG_SND_HDA_POWER_SAVE
static void alc889_power_eapd(struct hda_codec *codec, int power)
{
- snd_hda_codec_write(codec, 0x14, 0,
- AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
- snd_hda_codec_write(codec, 0x15, 0,
- AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
+ set_eapd(codec, 0x14, power);
+ set_eapd(codec, 0x15, power);
}
#endif
@@ -4812,6 +4819,49 @@ static void fixup_automic_adc(struct hda_codec *codec)
spec->auto_mic = 0; /* disable auto-mic to be sure */
}
+/* choose the ADC/MUX containing the input pin and initialize the setup */
+static void fixup_single_adc(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t pin;
+ int i;
+
+ /* search for the input pin; there must be only one */
+ for (i = 0; i < AUTO_PIN_LAST; i++) {
+ if (spec->autocfg.input_pins[i]) {
+ pin = spec->autocfg.input_pins[i];
+ break;
+ }
+ }
+ if (!pin)
+ return;
+
+ /* set the default connection to that pin */
+ for (i = 0; i < spec->num_adc_nids; i++) {
+ hda_nid_t cap = spec->capsrc_nids ?
+ spec->capsrc_nids[i] : spec->adc_nids[i];
+ int idx;
+
+ idx = get_connection_index(codec, cap, pin);
+ if (idx < 0)
+ continue;
+ /* use only this ADC */
+ if (spec->capsrc_nids)
+ spec->capsrc_nids += i;
+ spec->adc_nids += i;
+ spec->num_adc_nids = 1;
+ /* select or unmute this route */
+ if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
+ snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
+ HDA_AMP_MUTE, 0);
+ } else {
+ snd_hda_codec_write_cache(codec, cap, 0,
+ AC_VERB_SET_CONNECT_SEL, idx);
+ }
+ return;
+ }
+}
+
static void set_capture_mixer(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -4824,14 +4874,15 @@ static void set_capture_mixer(struct hda_codec *codec)
alc_capture_mixer3 },
};
if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
- int mux;
- if (spec->auto_mic) {
- mux = 0;
+ int mux = 0;
+ if (spec->auto_mic)
fixup_automic_adc(codec);
- } else if (spec->input_mux && spec->input_mux->num_items > 1)
- mux = 1;
- else
- mux = 0;
+ else if (spec->input_mux) {
+ if (spec->input_mux->num_items > 1)
+ mux = 1;
+ else if (spec->input_mux->num_items == 1)
+ fixup_single_adc(codec);
+ }
spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
}
}
@@ -7094,8 +7145,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
- HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
+ HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, 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, 0x01, HDA_INPUT),
@@ -7496,6 +7547,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
/* Front Mic pin: input vref at 80% */
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
@@ -7680,6 +7732,27 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
spec->autocfg.speaker_pins[0] = 0x14;
}
+static void alc885_mb5_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+
+ present = snd_hda_codec_read(codec, 0x14, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+
+}
+
+static void alc885_mb5_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ /* Headphone insertion or removal. */
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc885_mb5_automute(codec);
+}
+
static void alc885_imac91_automute(struct hda_codec *codec)
{
unsigned int present;
@@ -9126,6 +9199,8 @@ static struct alc_config_preset alc882_presets[] = {
.input_mux = &mb5_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID,
+ .unsol_event = alc885_mb5_unsol_event,
+ .init_hook = alc885_mb5_automute,
},
[ALC885_MACPRO] = {
.mixers = { alc882_macpro_mixer },
@@ -9403,6 +9478,7 @@ static struct alc_config_preset alc882_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
.channel_mode = alc883_3ST_6ch_modes,
.need_dac_fix = 1,
+ .const_channel_count = 6,
.num_mux_defs =
ARRAY_SIZE(alc888_2_capture_sources),
.input_mux = alc888_2_capture_sources,
@@ -10307,7 +10383,7 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x15;
- spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
+ spec->autocfg.speaker_pins[0] = 0x14;
}
static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
@@ -11179,7 +11255,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
}
#define alc262_auto_create_input_ctls \
- alc880_auto_create_input_ctls
+ alc882_auto_create_input_ctls
/*
* generic initialization of ADC, input mixers and output mixers
@@ -11718,9 +11794,9 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
- .unsol_event = alc_automute_amp_unsol_event,
+ .unsol_event = alc_sku_unsol_event,
.setup = alc262_hp_t5735_setup,
- .init_hook = alc_automute_amp,
+ .init_hook = alc_inithook,
},
[ALC262_HP_RP5700] = {
.mixers = { alc262_hp_rp5700_mixer },
@@ -12471,6 +12547,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
dac = 0x02;
break;
case 0x15:
+ case 0x21:
dac = 0x03;
break;
default:
@@ -14855,6 +14932,8 @@ static int patch_alc861(struct hda_codec *codec)
spec->stream_digital_playback = &alc861_pcm_digital_playback;
spec->stream_digital_capture = &alc861_pcm_digital_capture;
+ if (!spec->cap_mixer)
+ set_capture_mixer(codec);
set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
spec->vmaster_nid = 0x03;
@@ -17251,7 +17330,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
ALC662_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
+ SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
ALC662_3ST_6ch_DIG),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 2291a8396817..799ba2570902 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4730,6 +4730,26 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
}
}
+static int hp_blike_system(u32 subsystem_id);
+
+static void set_hp_led_gpio(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ switch (codec->vendor_id) {
+ case 0x111d7608:
+ /* GPIO 0 */
+ spec->gpio_led = 0x01;
+ break;
+ case 0x111d7600:
+ case 0x111d7601:
+ case 0x111d7602:
+ case 0x111d7603:
+ /* GPIO 3 */
+ spec->gpio_led = 0x08;
+ break;
+ }
+}
+
/*
* This method searches for the mute LED GPIO configuration
* provided as OEM string in SMBIOS. The format of that string
@@ -4741,6 +4761,14 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
*
* So, HP B-series like systems may have HP_Mute_LED_0 (current models)
* or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
+ *
+ *
+ * The dv-series laptops don't seem to have the HP_Mute_LED* strings in
+ * SMBIOS - at least the ones I have seen do not have them - which include
+ * my own system (HP Pavilion dv6-1110ax) and my cousin's
+ * HP Pavilion dv9500t CTO.
+ * Need more information on whether it is true across the entire series.
+ * -- kunal
*/
static int find_mute_led_gpio(struct hda_codec *codec)
{
@@ -4751,28 +4779,27 @@ static int find_mute_led_gpio(struct hda_codec *codec)
while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
NULL, dev))) {
if (sscanf(dev->name, "HP_Mute_LED_%d_%d",
- &spec->gpio_led_polarity,
- &spec->gpio_led) == 2) {
+ &spec->gpio_led_polarity,
+ &spec->gpio_led) == 2) {
spec->gpio_led = 1 << spec->gpio_led;
return 1;
}
if (sscanf(dev->name, "HP_Mute_LED_%d",
- &spec->gpio_led_polarity) == 1) {
- switch (codec->vendor_id) {
- case 0x111d7608:
- /* GPIO 0 */
- spec->gpio_led = 0x01;
- return 1;
- case 0x111d7600:
- case 0x111d7601:
- case 0x111d7602:
- case 0x111d7603:
- /* GPIO 3 */
- spec->gpio_led = 0x08;
- return 1;
- }
+ &spec->gpio_led_polarity) == 1) {
+ set_hp_led_gpio(codec);
+ return 1;
}
}
+
+ /*
+ * Fallback case - if we don't find the DMI strings,
+ * we statically set the GPIO - if not a B-series system.
+ */
+ if (!hp_blike_system(codec->subsystem_id)) {
+ set_hp_led_gpio(codec);
+ spec->gpio_led_polarity = 1;
+ return 1;
+ }
}
return 0;
}
@@ -5548,6 +5575,8 @@ again:
spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
+ snd_printdd("Found board config: %d\n", spec->board_config);
+
switch (spec->board_config) {
case STAC_HP_M4:
/* enable internal microphone */
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 765d7bd4c3d4..9e66f6d306f8 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -703,11 +703,13 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
{
unsigned char nvol;
- if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
+ if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) {
nvol = 0;
- else
+ } else {
nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
WM_VOL_MAX;
+ nvol += 0x1b;
+ }
wm_put(ice, index, nvol);
wm_put_nocache(ice, index, 0x180 | nvol);
@@ -778,7 +780,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
for (ch = 0; ch < 2; ch++) {
unsigned int vol = ucontrol->value.integer.value[ch];
if (vol > WM_VOL_MAX)
- continue;
+ vol = WM_VOL_MAX;
vol |= spec->master[ch] & WM_VOL_MUTE;
if (vol != spec->master[ch]) {
int dac;
@@ -834,8 +836,8 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
for (i = 0; i < voices; i++) {
unsigned int vol = ucontrol->value.integer.value[i];
if (vol > WM_VOL_MAX)
- continue;
- vol |= spec->vol[ofs+i];
+ vol = WM_VOL_MAX;
+ vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
if (vol != spec->vol[ofs+i]) {
spec->vol[ofs+i] = vol;
idx = WM_DAC_ATTEN + ofs + i;
OpenPOWER on IntegriCloud