diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_controller.c | 19 | ||||
-rw-r--r-- | sound/pci/hda/hda_controller.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 23 | ||||
-rw-r--r-- | sound/pci/ice1712/delta.c | 31 | ||||
-rw-r--r-- | sound/pci/ice1712/ice1712.c | 47 |
6 files changed, 103 insertions, 23 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 97993e17f46a..248b90abb882 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -187,13 +187,14 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) struct azx_dev *azx_dev = &chip->azx_dev[dev]; dsp_lock(azx_dev); if (!azx_dev->opened && !dsp_is_locked(azx_dev)) { - res = azx_dev; - if (res->assigned_key == key) { - res->opened = 1; - res->assigned_key = key; + if (azx_dev->assigned_key == key) { + azx_dev->opened = 1; + azx_dev->assigned_key = key; dsp_unlock(azx_dev); return azx_dev; } + if (!res) + res = azx_dev; } dsp_unlock(azx_dev); } @@ -1604,7 +1605,7 @@ static void azx_exit_link_reset(struct azx *chip) } /* reset codec link */ -static int azx_reset(struct azx *chip, int full_reset) +static int azx_reset(struct azx *chip, bool full_reset) { if (!full_reset) goto __skip; @@ -1701,7 +1702,7 @@ static void azx_int_clear(struct azx *chip) /* * reset and start the controller registers */ -void azx_init_chip(struct azx *chip, int full_reset) +void azx_init_chip(struct azx *chip, bool full_reset) { if (chip->initialized) return; @@ -1758,7 +1759,7 @@ irqreturn_t azx_interrupt(int irq, void *dev_id) #ifdef CONFIG_PM_RUNTIME if (chip->driver_caps & AZX_DCAPS_PM_RUNTIME) - if (chip->card->dev->power.runtime_status != RPM_ACTIVE) + if (!pm_runtime_active(chip->card->dev)) return IRQ_NONE; #endif @@ -1841,7 +1842,7 @@ static void azx_bus_reset(struct hda_bus *bus) bus->in_reset = 1; azx_stop_chip(chip); - azx_init_chip(chip, 1); + azx_init_chip(chip, true); #ifdef CONFIG_PM if (chip->initialized) { struct azx_pcm *p; @@ -1948,7 +1949,7 @@ int azx_codec_create(struct azx *chip, const char *model, * get back to the sanity state. */ azx_stop_chip(chip); - azx_init_chip(chip, 1); + azx_init_chip(chip, true); } } } diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 1d2e3be2bae6..baf0e77330af 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -37,7 +37,7 @@ int azx_alloc_stream_pages(struct azx *chip); void azx_free_stream_pages(struct azx *chip); /* Low level azx interface */ -void azx_init_chip(struct azx *chip, int full_reset); +void azx_init_chip(struct azx *chip, bool full_reset); void azx_stop_chip(struct azx *chip); void azx_enter_link_reset(struct azx *chip); irqreturn_t azx_interrupt(int irq, void *dev_id); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 77ca894f8284..d6bca62ef387 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -636,7 +636,7 @@ static int azx_resume(struct device *dev) return -EIO; azx_init_pci(chip); - azx_init_chip(chip, 1); + azx_init_chip(chip, true); snd_hda_resume(chip->bus); snd_power_change_state(card, SNDRV_CTL_POWER_D0); @@ -689,7 +689,7 @@ static int azx_runtime_resume(struct device *dev) status = azx_readw(chip, STATESTS); azx_init_pci(chip); - azx_init_chip(chip, 1); + azx_init_chip(chip, true); bus = chip->bus; if (status && bus) { diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ea2351d119f0..14ae979a92ea 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3026,6 +3026,11 @@ static void alc283_init(struct hda_codec *codec) bool hp_pin_sense; int val; + if (!spec->gen.autocfg.hp_outs) { + if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) + hp_pin = spec->gen.autocfg.line_out_pins[0]; + } + alc283_restore_default_value(codec); if (!hp_pin) @@ -3062,6 +3067,11 @@ static void alc283_shutup(struct hda_codec *codec) bool hp_pin_sense; int val; + if (!spec->gen.autocfg.hp_outs) { + if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) + hp_pin = spec->gen.autocfg.line_out_pins[0]; + } + if (!hp_pin) { alc269_shutup(codec); return; @@ -3085,6 +3095,7 @@ static void alc283_shutup(struct hda_codec *codec) if (hp_pin_sense) msleep(100); + alc_auto_setup_eapd(codec, false); snd_hda_shutup_pins(codec); alc_write_coef_idx(codec, 0x43, 0x9614); } @@ -3361,8 +3372,9 @@ static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) if (spec->mute_led_polarity) enabled = !enabled; - pinval = AC_PINCTL_IN_EN | - (enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80); + pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); + pinval &= ~AC_PINCTL_VREFEN; + pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; if (spec->mute_led_nid) snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); } @@ -3994,6 +4006,10 @@ static void alc283_fixup_chromebook(struct hda_codec *codec, spec->gen.mixer_nid = 0; break; case HDA_FIXUP_ACT_INIT: + /* MIC2-VREF control */ + /* Set to manual mode */ + val = alc_read_coef_idx(codec, 0x06); + alc_write_coef_idx(codec, 0x06, val & ~0x000c); /* Enable Line1 input control by verb */ val = alc_read_coef_idx(codec, 0x1a); alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); @@ -4602,6 +4618,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), @@ -4768,7 +4785,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, - {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-chrome"}, + {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, {} }; diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index ed2144eee38a..496dbd0ad5db 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -579,12 +579,37 @@ static struct snd_ak4xxx_private akm_vx442_priv = { #ifdef CONFIG_PM_SLEEP static int snd_ice1712_delta_resume(struct snd_ice1712 *ice) { - unsigned char akm_backup[AK4XXX_IMAGE_SIZE]; + unsigned char akm_img_bak[AK4XXX_IMAGE_SIZE]; + unsigned char akm_vol_bak[AK4XXX_IMAGE_SIZE]; + + /* init spdif */ + switch (ice->eeprom.subvendor) { + case ICE1712_SUBDEVICE_AUDIOPHILE: + case ICE1712_SUBDEVICE_DELTA410: + case ICE1712_SUBDEVICE_DELTA1010E: + case ICE1712_SUBDEVICE_DELTA1010LT: + case ICE1712_SUBDEVICE_VX442: + case ICE1712_SUBDEVICE_DELTA66E: + snd_cs8427_init(ice->i2c, ice->cs8427); + break; + case ICE1712_SUBDEVICE_DELTA1010: + case ICE1712_SUBDEVICE_MEDIASTATION: + /* nothing */ + break; + case ICE1712_SUBDEVICE_DELTADIO2496: + case ICE1712_SUBDEVICE_DELTA66: + /* Set spdif defaults */ + snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits); + break; + } + /* init codec and restore registers */ if (ice->akm_codecs) { - memcpy(akm_backup, ice->akm->images, sizeof(akm_backup)); + memcpy(akm_img_bak, ice->akm->images, sizeof(akm_img_bak)); + memcpy(akm_vol_bak, ice->akm->volumes, sizeof(akm_vol_bak)); snd_akm4xxx_init(ice->akm); - memcpy(ice->akm->images, akm_backup, sizeof(akm_backup)); + memcpy(ice->akm->images, akm_img_bak, sizeof(akm_img_bak)); + memcpy(ice->akm->volumes, akm_vol_bak, sizeof(akm_vol_bak)); snd_akm4xxx_reset(ice->akm, 0); } diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 291672fc4a99..d9b9e4595f17 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -685,9 +685,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream * if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1)) return 0; ptr = runtime->buffer_size - inw(ice->ddma_port + 4); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream) @@ -704,9 +705,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substrea addr = ICE1712_DSC_ADDR0; ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) - ice->playback_con_virt_addr[substream->number]; + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream) @@ -717,9 +719,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1)) return 0; ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr; + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static const struct snd_pcm_hardware snd_ice1712_playback = { @@ -1048,6 +1051,8 @@ __out: old = inb(ICEMT(ice, RATE)); if (!force && old == val) goto __out; + + ice->cur_rate = rate; outb(val, ICEMT(ice, RATE)); spin_unlock_irqrestore(&ice->reg_lock, flags); @@ -1114,9 +1119,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substre if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START)) return 0; ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream) @@ -1127,9 +1133,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW)) return 0; ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static const struct snd_pcm_hardware snd_ice1712_playback_pro = { @@ -2832,6 +2839,12 @@ static int snd_ice1712_suspend(struct device *dev) snd_pcm_suspend_all(ice->pcm_ds); snd_ac97_suspend(ice->ac97); + spin_lock_irq(&ice->reg_lock); + ice->pm_saved_is_spdif_master = is_spdif_master(ice); + ice->pm_saved_spdif_ctrl = inw(ICEMT(ice, ROUTE_SPDOUT)); + ice->pm_saved_route = inw(ICEMT(ice, ROUTE_PSDOUT03)); + spin_unlock_irq(&ice->reg_lock); + if (ice->pm_suspend) ice->pm_suspend(ice); @@ -2846,6 +2859,7 @@ static int snd_ice1712_resume(struct device *dev) struct pci_dev *pci = to_pci_dev(dev); struct snd_card *card = dev_get_drvdata(dev); struct snd_ice1712 *ice = card->private_data; + int rate; if (!ice->pm_suspend_enabled) return 0; @@ -2860,14 +2874,37 @@ static int snd_ice1712_resume(struct device *dev) pci_set_master(pci); + if (ice->cur_rate) + rate = ice->cur_rate; + else + rate = PRO_RATE_DEFAULT; + if (snd_ice1712_chip_init(ice) < 0) { snd_card_disconnect(card); return -EIO; } + ice->cur_rate = rate; + if (ice->pm_resume) ice->pm_resume(ice); + if (ice->pm_saved_is_spdif_master) { + /* switching to external clock via SPDIF */ + spin_lock_irq(&ice->reg_lock); + outb(inb(ICEMT(ice, RATE)) | ICE1712_SPDIF_MASTER, + ICEMT(ice, RATE)); + spin_unlock_irq(&ice->reg_lock); + snd_ice1712_set_input_clock_source(ice, 1); + } else { + /* internal on-card clock */ + snd_ice1712_set_pro_rate(ice, rate, 1); + snd_ice1712_set_input_clock_source(ice, 0); + } + + outw(ice->pm_saved_spdif_ctrl, ICEMT(ice, ROUTE_SPDOUT)); + outw(ice->pm_saved_route, ICEMT(ice, ROUTE_PSDOUT03)); + if (ice->ac97) snd_ac97_resume(ice->ac97); |