diff options
Diffstat (limited to 'sound/pci')
38 files changed, 177 insertions, 135 deletions
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 9f569379b77e..e781ccca1793 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1882,10 +1882,8 @@ static int ali_suspend(struct device *dev) return 0; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < chip->num_of_codecs; i++) { - snd_pcm_suspend_all(chip->pcm[i]); + for (i = 0; i < chip->num_of_codecs; i++) snd_ac97_suspend(chip->ac97[i]); - } spin_lock_irq(&chip->reg_lock); diff --git a/sound/pci/als300.c b/sound/pci/als300.c index eaa2d853d922..516b3d9cbfdf 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c @@ -731,7 +731,6 @@ static int snd_als300_suspend(struct device *dev) struct snd_als300 *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); return 0; } diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 26b097edec8c..45fa38382e79 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -994,7 +994,6 @@ static int snd_als4000_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); snd_sbmixer_suspend(chip); return 0; } diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 1a41f8c80243..7715d26916ac 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -733,6 +733,10 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: + if (dma->running && dma->suspended && + cmd == SNDRV_PCM_TRIGGER_RESUME) + writel(dma->saved_curptr, chip->remap_addr + + dma->ops->dt_cur); dma->ops->enable_transfer(chip, 1); dma->running = 1; dma->suspended = 0; @@ -740,9 +744,12 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: + dma->suspended = cmd == SNDRV_PCM_TRIGGER_SUSPEND; + if (dma->running && dma->suspended) + dma->saved_curptr = readl(chip->remap_addr + + dma->ops->dt_cur); dma->ops->enable_transfer(chip, 0); dma->running = 0; - dma->suspended = cmd == SNDRV_PCM_TRIGGER_SUSPEND; break; default: err = -EINVAL; @@ -1479,14 +1486,6 @@ static int snd_atiixp_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < NUM_ATI_PCMDEVS; i++) - if (chip->pcmdevs[i]) { - struct atiixp_dma *dma = &chip->dmas[i]; - if (dma->substream && dma->running) - dma->saved_curptr = readl(chip->remap_addr + - dma->ops->dt_cur); - snd_pcm_suspend_all(chip->pcmdevs[i]); - } for (i = 0; i < NUM_ATI_CODECS; i++) snd_ac97_suspend(chip->ac97[i]); snd_atiixp_aclink_down(chip); @@ -1514,8 +1513,6 @@ static int snd_atiixp_resume(struct device *dev) dma->substream->ops->prepare(dma->substream); writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN, chip->remap_addr + dma->ops->llp_offset); - writel(dma->saved_curptr, chip->remap_addr + - dma->ops->dt_cur); } } diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index dc1de860cedf..a357a8e2e73d 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -1125,8 +1125,6 @@ static int snd_atiixp_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < NUM_ATI_PCMDEVS; i++) - snd_pcm_suspend_all(chip->pcmdevs[i]); for (i = 0; i < NUM_ATI_CODECS; i++) snd_ac97_suspend(chip->ac97[i]); snd_atiixp_aclink_down(chip); diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index fc18c29a8173..90348817f096 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -2699,10 +2699,6 @@ snd_azf3328_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - /* same pcm object for playback/capture */ - snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]); - snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]); - snd_azf3328_suspend_ac97(chip); snd_azf3328_suspend_regs(chip, chip->ctrl_io, diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index cd27b5536654..3d1b0bbff33b 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1910,11 +1910,8 @@ static int snd_ca0106_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct snd_ca0106 *chip = card->private_data; - int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < 4; i++) - snd_pcm_suspend_all(chip->pcm[i]); if (chip->details->ac97) snd_ac97_suspend(chip->ac97); snd_ca0106_mixer_suspend(chip); diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 452cc79b44af..5bbf31c1695c 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -3351,10 +3351,6 @@ static int snd_cmipci_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(cm->pcm); - snd_pcm_suspend_all(cm->pcm2); - snd_pcm_suspend_all(cm->pcm_spdif); - /* save registers */ for (i = 0; i < ARRAY_SIZE(saved_regs); i++) cm->saved_regs[i] = snd_cmipci_read(cm, saved_regs[i]); diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index ec4247638fa1..a9fb819cad1d 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -2002,8 +2002,6 @@ static int cs4281_suspend(struct device *dev) unsigned int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); - snd_ac97_suspend(chip->ac97); snd_ac97_suspend(chip->ac97_secondary); diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 750eec437a79..a77d4cc44028 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -3781,12 +3781,6 @@ static int snd_cs46xx_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->in_suspend = 1; - snd_pcm_suspend_all(chip->pcm); -#ifdef CONFIG_SND_CS46XX_NEW_DSP - snd_pcm_suspend_all(chip->pcm_rear); - snd_pcm_suspend_all(chip->pcm_center_lfe); - snd_pcm_suspend_all(chip->pcm_iec958); -#endif // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index 82bd10b68a77..446ef1f1b45a 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c @@ -62,7 +62,6 @@ static int __maybe_unused snd_cs5535audio_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(cs5535au->pcm); snd_ac97_suspend(cs5535au->ac97); for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) { struct cs5535audio_dma *dma = &cs5535au->dmas[i]; diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 2ada8444abd9..e622613ea947 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -1548,18 +1548,10 @@ static void atc_connect_resources(struct ct_atc *atc) #ifdef CONFIG_PM_SLEEP static int atc_suspend(struct ct_atc *atc) { - int i; struct hw *hw = atc->hw; snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot); - for (i = FRONT; i < NUM_PCMS; i++) { - if (!atc->pcms[i]) - continue; - - snd_pcm_suspend_all(atc->pcms[i]); - } - atc_release_resources(atc); hw->suspend(hw); diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 907cf1a46712..18d30d479b6b 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -2165,9 +2165,6 @@ static int snd_echo_suspend(struct device *dev) { struct echoaudio *chip = dev_get_drvdata(dev); - snd_pcm_suspend_all(chip->analog_pcm); - snd_pcm_suspend_all(chip->digital_pcm); - #ifdef ECHOCARD_HAS_MIDI /* This call can sleep */ if (chip->midi_out) diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index d3203df50a1a..3c41a0edcfb0 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c @@ -224,12 +224,6 @@ static int snd_emu10k1_suspend(struct device *dev) cancel_delayed_work_sync(&emu->emu1010.firmware_work); - snd_pcm_suspend_all(emu->pcm); - snd_pcm_suspend_all(emu->pcm_mic); - snd_pcm_suspend_all(emu->pcm_efx); - snd_pcm_suspend_all(emu->pcm_multi); - snd_pcm_suspend_all(emu->pcm_p16v); - snd_ac97_suspend(emu->ac97); snd_emu10k1_efx_suspend(emu); diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 727eb3da1fda..1f2960ecc57e 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -2037,9 +2037,6 @@ static int snd_ensoniq_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(ensoniq->pcm1); - snd_pcm_suspend_all(ensoniq->pcm2); - #ifdef CHIP1371 snd_ac97_suspend(ensoniq->u.es1371.ac97); #else diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 9d248eb2e26c..84d07bce581c 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1475,7 +1475,6 @@ static int es1938_suspend(struct device *dev) unsigned char *s, *d; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); /* save mixer-related registers */ for (s = saved_regs, d = chip->saved_regs; *s; s++, d++) diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 0b1845ca6005..9dcb698fc8c7 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -2392,7 +2392,6 @@ static int es1968_suspend(struct device *dev) chip->in_suspend = 1; cancel_work_sync(&chip->hwvol_work); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); snd_es1968_bob_stop(chip); return 0; diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index e3fb9c61017c..1317f3183eb1 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -1408,7 +1408,6 @@ static int snd_fm801_suspend(struct device *dev) if (chip->tea575x_tuner & TUNER_ONLY) { /* FIXME: tea575x suspend */ } else { - snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); snd_ac97_suspend(chip->ac97_sec); } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 9f8d59e7e89f..e4704f5729d3 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2923,12 +2923,9 @@ static void hda_call_codec_resume(struct hda_codec *codec) static int hda_codec_runtime_suspend(struct device *dev) { struct hda_codec *codec = dev_to_hda_codec(dev); - struct hda_pcm *pcm; unsigned int state; cancel_delayed_work_sync(&codec->jackpoll_work); - list_for_each_entry(pcm, &codec->pcm_list_head, list) - snd_pcm_suspend_all(pcm->pcm); state = hda_call_codec_suspend(codec); if (codec->link_down_at_suspend || (codec_has_clkstop(codec) && codec_has_epss(codec) && diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index 97a176d817a0..c8d18dc4da2a 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -32,6 +32,7 @@ #include <linux/slab.h> #include <linux/time.h> #include <linux/string.h> +#include <linux/pm_runtime.h> #include <sound/core.h> #include <sound/initval.h> @@ -232,40 +233,72 @@ static void hda_tegra_disable_clocks(struct hda_tegra *data) static int hda_tegra_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); - struct azx *chip = card->private_data; - struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); - struct hdac_bus *bus = azx_bus(chip); + int rc; + rc = pm_runtime_force_suspend(dev); + if (rc < 0) + return rc; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - azx_stop_chip(chip); - synchronize_irq(bus->irq); - azx_enter_link_reset(chip); - hda_tegra_disable_clocks(hda); - return 0; } static int hda_tegra_resume(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); + int rc; + + rc = pm_runtime_force_resume(dev); + if (rc < 0) + return rc; + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +#ifdef CONFIG_PM +static int hda_tegra_runtime_suspend(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); + struct hdac_bus *bus = azx_bus(chip); - hda_tegra_enable_clocks(hda); + if (chip && chip->running) { + azx_stop_chip(chip); + synchronize_irq(bus->irq); + azx_enter_link_reset(chip); + } + hda_tegra_disable_clocks(hda); - hda_tegra_init(hda); + return 0; +} - azx_init_chip(chip, 1); +static int hda_tegra_runtime_resume(struct device *dev) +{ + struct snd_card *card = dev_get_drvdata(dev); + struct azx *chip = card->private_data; + struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); + int rc; - snd_power_change_state(card, SNDRV_CTL_POWER_D0); + rc = hda_tegra_enable_clocks(hda); + if (rc != 0) + return rc; + if (chip && chip->running) { + hda_tegra_init(hda); + azx_init_chip(chip, 1); + } return 0; } -#endif /* CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM */ static const struct dev_pm_ops hda_tegra_pm = { SET_SYSTEM_SLEEP_PM_OPS(hda_tegra_suspend, hda_tegra_resume) + SET_RUNTIME_PM_OPS(hda_tegra_runtime_suspend, + hda_tegra_runtime_resume, + NULL) }; static int hda_tegra_dev_disconnect(struct snd_device *device) @@ -303,7 +336,23 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev) struct hdac_bus *bus = azx_bus(chip); struct device *dev = hda->dev; struct resource *res; - int err; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hda->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(hda->regs)) + return PTR_ERR(hda->regs); + + bus->remap_addr = hda->regs + HDA_BAR0; + bus->addr = res->start + HDA_BAR0; + + hda_tegra_init(hda); + + return 0; +} + +static int hda_tegra_init_clk(struct hda_tegra *hda) +{ + struct device *dev = hda->dev; hda->hda_clk = devm_clk_get(dev, "hda"); if (IS_ERR(hda->hda_clk)) { @@ -321,22 +370,6 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev) return PTR_ERR(hda->hda2hdmi_clk); } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hda->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(hda->regs)) - return PTR_ERR(hda->regs); - - bus->remap_addr = hda->regs + HDA_BAR0; - bus->addr = res->start + HDA_BAR0; - - err = hda_tegra_enable_clocks(hda); - if (err) { - dev_err(dev, "failed to get enable clocks\n"); - return err; - } - - hda_tegra_init(hda); - return 0; } @@ -487,7 +520,8 @@ MODULE_DEVICE_TABLE(of, hda_tegra_match); static int hda_tegra_probe(struct platform_device *pdev) { - const unsigned int driver_flags = AZX_DCAPS_CORBRP_SELF_CLEAR; + const unsigned int driver_flags = AZX_DCAPS_CORBRP_SELF_CLEAR | + AZX_DCAPS_PM_RUNTIME; struct snd_card *card; struct azx *chip; struct hda_tegra *hda; @@ -506,12 +540,21 @@ static int hda_tegra_probe(struct platform_device *pdev) return err; } + err = hda_tegra_init_clk(hda); + if (err < 0) + goto out_free; + err = hda_tegra_create(card, driver_flags, hda); if (err < 0) goto out_free; card->private_data = chip; dev_set_drvdata(&pdev->dev, card); + + pm_runtime_enable(hda->dev); + if (!azx_has_pm_runtime(chip)) + pm_runtime_forbid(hda->dev); + schedule_work(&hda->probe_work); return 0; @@ -528,6 +571,7 @@ static void hda_tegra_probe_work(struct work_struct *work) struct platform_device *pdev = to_platform_device(hda->dev); int err; + pm_runtime_get_sync(hda->dev); err = hda_tegra_first_init(chip, pdev); if (err < 0) goto out_free; @@ -549,12 +593,18 @@ static void hda_tegra_probe_work(struct work_struct *work) snd_hda_set_power_save(&chip->bus, power_save * 1000); out_free: + pm_runtime_put(hda->dev); return; /* no error return from async probe */ } static int hda_tegra_remove(struct platform_device *pdev) { - return snd_card_free(dev_get_drvdata(&pdev->dev)); + int ret; + + ret = snd_card_free(dev_get_drvdata(&pdev->dev)); + pm_runtime_disable(&pdev->dev); + + return ret; } static void hda_tegra_shutdown(struct platform_device *pdev) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 46f88dc7b7e8..73d7042ff884 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1865,7 +1865,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, hda_nid_t pin_nid; struct snd_pcm_runtime *runtime = substream->runtime; bool non_pcm; - int pinctl; + int pinctl, stripe; int err = 0; mutex_lock(&spec->pcm_lock); @@ -1909,6 +1909,14 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, per_pin->channels = substream->runtime->channels; per_pin->setup = true; + if (get_wcaps(codec, cvt_nid) & AC_WCAP_STRIPE) { + stripe = snd_hdac_get_stream_stripe_ctl(&codec->bus->core, + substream); + snd_hda_codec_write(codec, cvt_nid, 0, + AC_VERB_SET_STRIPE_CONTROL, + stripe); + } + hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); mutex_unlock(&per_pin->lock); if (spec->dyn_pin_out) { diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index b8af747ecb43..7646c93e8268 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -826,7 +826,12 @@ static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg snd_i2c_lock(ice->i2c); byte = reg; - snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1); + if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1)) { + snd_i2c_unlock(ice->i2c); + dev_err(ice->card->dev, "cannot send pca\n"); + return -EIO; + } + byte = 0; if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) { snd_i2c_unlock(ice->i2c); diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index f1fe497c2f9d..dda9b26192cb 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -2792,9 +2792,6 @@ static int snd_ice1712_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(ice->pcm); - snd_pcm_suspend_all(ice->pcm_pro); - snd_pcm_suspend_all(ice->pcm_ds); snd_ac97_suspend(ice->ac97); spin_lock_irq(&ice->reg_lock); diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 057c2f394ea7..42994cf36156 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -2804,9 +2804,6 @@ static int snd_vt1724_suspend(struct device *dev) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(ice->pcm); - snd_pcm_suspend_all(ice->pcm_pro); - snd_pcm_suspend_all(ice->pcm_ds); snd_ac97_suspend(ice->ac97); spin_lock_irq(&ice->reg_lock); diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index ffddcdfe0c66..885e1d488ed6 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2614,8 +2614,6 @@ static int intel8x0_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < chip->pcm_devs; i++) - snd_pcm_suspend_all(chip->pcm[i]); for (i = 0; i < chip->ncodecs; i++) snd_ac97_suspend(chip->ac97[i]); if (chip->device_type == DEVICE_INTEL_ICH4) diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index c84629190cba..44eb9e28a1eb 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -1025,11 +1025,8 @@ static int intel8x0m_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct intel8x0m *chip = card->private_data; - int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < chip->pcm_devs; i++) - snd_pcm_suspend_all(chip->pcm[i]); snd_ac97_suspend(chip->ac97); if (chip->irq >= 0) { free_irq(chip->irq, chip); diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 62962178a9d7..1a9468c14aaf 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2422,7 +2422,6 @@ static int m3_suspend(struct device *dev) chip->in_suspend = 1; cancel_work_sync(&chip->hwvol_work); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); msleep(10); /* give the assp a chance to idle.. */ diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index b97f4ea6b56c..85e46ff44ac3 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -1413,7 +1413,6 @@ static int nm256_suspend(struct device *dev) struct nm256 *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); chip->coeffs_current = 0; return 0; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index b4ef5804212d..d4cfff7e49e1 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -373,7 +373,7 @@ static void oxygen_init(struct oxygen *chip) for (i = 0; i < 8; ++i) chip->dac_volume[i] = chip->model.dac_volume_min; chip->dac_mute = 1; - chip->spdif_playback_enable = 1; + chip->spdif_playback_enable = 0; chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL | (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT); chip->spdif_pcm_bits = chip->spdif_bits; @@ -744,13 +744,10 @@ static int oxygen_pci_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct oxygen *chip = card->private_data; - unsigned int i, saved_interrupt_mask; + unsigned int saved_interrupt_mask; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < PCM_COUNT; ++i) - snd_pcm_suspend(chip->streams[i]); - if (chip->model.suspend) chip->model.suspend(chip); diff --git a/sound/pci/oxygen/pcm1796.h b/sound/pci/oxygen/pcm1796.h index 34d07dd2d22e..d5dcb09e44cd 100644 --- a/sound/pci/oxygen/pcm1796.h +++ b/sound/pci/oxygen/pcm1796.h @@ -10,7 +10,6 @@ #define PCM1796_MUTE 0x01 #define PCM1796_DME 0x02 #define PCM1796_DMF_MASK 0x0c -#define PCM1796_DMF_DISABLED 0x00 #define PCM1796_DMF_48 0x04 #define PCM1796_DMF_441 0x08 #define PCM1796_DMF_32 0x0c diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 24109d37ca09..a1c6b98b191e 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -331,7 +331,7 @@ static void pcm1796_init(struct oxygen *chip) struct xonar_pcm179x *data = chip->model_data; data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = - PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; + PCM1796_FMT_24_I2S | PCM1796_ATLD; if (!data->broken_i2c) data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE; data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = @@ -621,6 +621,23 @@ static void update_pcm1796_oversampling(struct oxygen *chip) pcm1796_write_cached(chip, i, 20, reg); } +static void update_pcm1796_deemph(struct oxygen *chip) +{ + struct xonar_pcm179x *data = chip->model_data; + unsigned int i; + u8 reg; + + reg = data->pcm1796_regs[0][18 - PCM1796_REG_BASE] & ~PCM1796_DMF_MASK; + if (data->current_rate == 48000) + reg |= PCM1796_DMF_48; + else if (data->current_rate == 44100) + reg |= PCM1796_DMF_441; + else if (data->current_rate == 32000) + reg |= PCM1796_DMF_32; + for (i = 0; i < data->dacs; ++i) + pcm1796_write_cached(chip, i, 18, reg); +} + static void set_pcm1796_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -629,6 +646,7 @@ static void set_pcm1796_params(struct oxygen *chip, msleep(1); data->current_rate = params_rate(params); update_pcm1796_oversampling(chip); + update_pcm1796_deemph(chip); } static void update_pcm1796_volume(struct oxygen *chip) @@ -653,9 +671,11 @@ static void update_pcm1796_mute(struct oxygen *chip) unsigned int i; u8 value; - value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD; + value = data->pcm1796_regs[0][18 - PCM1796_REG_BASE]; if (chip->dac_mute) value |= PCM1796_MUTE; + else + value &= ~PCM1796_MUTE; for (i = 0; i < data->dacs; ++i) pcm1796_write_cached(chip, i, 18, value); } @@ -777,6 +797,49 @@ static const struct snd_kcontrol_new rolloff_control = { .put = rolloff_put, }; +static int deemph_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct xonar_pcm179x *data = chip->model_data; + + value->value.integer.value[0] = + !!(data->pcm1796_regs[0][18 - PCM1796_REG_BASE] & PCM1796_DME); + return 0; +} + +static int deemph_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + struct xonar_pcm179x *data = chip->model_data; + unsigned int i; + int changed; + u8 reg; + + mutex_lock(&chip->mutex); + reg = data->pcm1796_regs[0][18 - PCM1796_REG_BASE]; + if (!value->value.integer.value[0]) + reg &= ~PCM1796_DME; + else + reg |= PCM1796_DME; + changed = reg != data->pcm1796_regs[0][18 - PCM1796_REG_BASE]; + if (changed) { + for (i = 0; i < data->dacs; ++i) + pcm1796_write(chip, i, 18, reg); + } + mutex_unlock(&chip->mutex); + return changed; +} + +static const struct snd_kcontrol_new deemph_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "De-emphasis Playback Switch", + .info = snd_ctl_boolean_mono_info, + .get = deemph_get, + .put = deemph_put, +}; + static const struct snd_kcontrol_new hdav_hdmi_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "HDMI Playback Switch", @@ -1011,6 +1074,10 @@ static int add_pcm1796_controls(struct oxygen *chip) snd_ctl_new1(&rolloff_control, chip)); if (err < 0) return err; + err = snd_ctl_add(chip->card, + snd_ctl_new1(&deemph_control, chip)); + if (err < 0) + return err; } return 0; } diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 23017e3bc76c..1d431c8052d6 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -1158,7 +1158,6 @@ static int riptide_suspend(struct device *dev) chip->in_suspend = 1; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); return 0; } diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index dcfa4d7a73e2..c56702e6cb60 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -2388,8 +2388,6 @@ static int rme96_suspend(struct device *dev) struct rme96 *rme96 = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend(rme96->playback_substream); - snd_pcm_suspend(rme96->capture_substream); /* save capture & playback pointers */ rme96->playback_pointer = readl(rme96->iobase + RME96_IO_GET_PLAY_POS) diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 964acf302479..6b27980d77a8 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -1214,7 +1214,6 @@ static int sis_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(sis->pcm); if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT) snd_ac97_suspend(sis->ac97[0]); if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT) diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 5523e193d556..f271ea436cff 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -3915,10 +3915,6 @@ static int snd_trident_suspend(struct device *dev) trident->in_suspend = 1; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(trident->pcm); - snd_pcm_suspend_all(trident->foldback); - snd_pcm_suspend_all(trident->spdif); - snd_ac97_suspend(trident->ac97); snd_ac97_suspend(trident->ac97_sec); return 0; diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index c488c5afa195..736ac79901b3 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -2278,8 +2278,6 @@ static int snd_via82xx_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < 2; i++) - snd_pcm_suspend_all(chip->pcms[i]); for (i = 0; i < chip->num_devs; i++) snd_via82xx_channel_reset(chip, &chip->devs[i]); synchronize_irq(chip->irq); diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index b13c8688cc8d..3f59e0279058 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -1038,8 +1038,6 @@ static int snd_via82xx_suspend(struct device *dev) int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < 2; i++) - snd_pcm_suspend_all(chip->pcms[i]); for (i = 0; i < chip->num_devs; i++) snd_via82xx_channel_reset(chip, &chip->devs[i]); synchronize_irq(chip->irq); diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index a4926fb03991..c688b7f481da 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2304,10 +2304,6 @@ static int snd_ymfpci_suspend(struct device *dev) unsigned int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); - snd_pcm_suspend_all(chip->pcm2); - snd_pcm_suspend_all(chip->pcm_spdif); - snd_pcm_suspend_all(chip->pcm_4ch); snd_ac97_suspend(chip->ac97); for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); |