diff options
Diffstat (limited to 'sound/pci/ymfpci/ymfpci_main.c')
-rw-r--r-- | sound/pci/ymfpci/ymfpci_main.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index f3260e658b8a..a8159b81e9c4 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -27,6 +27,7 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/mutex.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/control.h> @@ -897,6 +898,18 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream) struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ymfpci_pcm *ypcm; + int err; + + runtime->hw = snd_ymfpci_playback; + /* FIXME? True value is 256/48 = 5.33333 ms */ + err = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIOD_TIME, + 5334, UINT_MAX); + if (err < 0) + return err; + err = snd_pcm_hw_rule_noresample(runtime, 48000); + if (err < 0) + return err; ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); if (ypcm == NULL) @@ -904,11 +917,8 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream) ypcm->chip = chip; ypcm->type = PLAYBACK_VOICE; ypcm->substream = substream; - runtime->hw = snd_ymfpci_playback; runtime->private_data = ypcm; runtime->private_free = snd_ymfpci_pcm_free_substream; - /* FIXME? True value is 256/48 = 5.33333 ms */ - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX); return 0; } @@ -1013,6 +1023,18 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream, struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ymfpci_pcm *ypcm; + int err; + + runtime->hw = snd_ymfpci_capture; + /* FIXME? True value is 256/48 = 5.33333 ms */ + err = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIOD_TIME, + 5334, UINT_MAX); + if (err < 0) + return err; + err = snd_pcm_hw_rule_noresample(runtime, 48000); + if (err < 0) + return err; ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); if (ypcm == NULL) @@ -1022,9 +1044,6 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream, ypcm->substream = substream; ypcm->capture_bank_number = capture_bank_number; chip->capture_substream[capture_bank_number] = substream; - runtime->hw = snd_ymfpci_capture; - /* FIXME? True value is 256/48 = 5.33333 ms */ - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX); runtime->private_data = ypcm; runtime->private_free = snd_ymfpci_pcm_free_substream; snd_ymfpci_hw_start(chip); @@ -1595,6 +1614,14 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } +static struct snd_kcontrol_new snd_ymfpci_dup4ch __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "4ch Duplication", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = snd_ymfpci_info_dup4ch, + .get = snd_ymfpci_get_dup4ch, + .put = snd_ymfpci_put_dup4ch, +}; static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { { @@ -1615,7 +1642,7 @@ YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL), YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL), YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL), YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL), -YMFPCI_DOUBLE("FM Legacy Volume", 0, YDSXGR_LEGACYOUTVOL), +YMFPCI_DOUBLE("FM Legacy Playback Volume", 0, YDSXGR_LEGACYOUTVOL), YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL), YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL), YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL), @@ -1623,13 +1650,6 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "4ch Duplication", - .info = snd_ymfpci_info_dup4ch, - .get = snd_ymfpci_get_dup4ch, - .put = snd_ymfpci_put_dup4ch, -}, }; @@ -1819,6 +1839,12 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) return err; } + if (chip->ac97->ext_id & AC97_EI_SDAC) { + kctl = snd_ctl_new1(&snd_ymfpci_dup4ch, chip); + err = snd_ctl_add(chip->card, kctl); + if (err < 0) + return err; + } /* add S/PDIF control */ if (snd_BUG_ON(!chip->pcm_spdif)) @@ -2291,6 +2317,10 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state) for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); + pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, + &chip->saved_dsxg_legacy); + pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, + &chip->saved_dsxg_elegacy); snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); snd_ymfpci_disable_dsp(chip); @@ -2325,6 +2355,11 @@ int snd_ymfpci_resume(struct pci_dev *pci) snd_ac97_resume(chip->ac97); + pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, + chip->saved_dsxg_legacy); + pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, + chip->saved_dsxg_elegacy); + /* start hw again */ if (chip->start_count > 0) { spin_lock_irq(&chip->reg_lock); |