[ALSA] Add PM support to SB-support code
Modules: SB drivers,SB16/AWE driver Add PM support to SB-support code. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
cb60e5f5b2
commit
5bdb6a1629
4 changed files with 153 additions and 0 deletions
|
@ -107,6 +107,10 @@ struct snd_sb {
|
|||
spinlock_t midi_input_lock;
|
||||
|
||||
struct snd_info_entry *proc_entry;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
unsigned char saved_regs[0x20];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* I/O ports */
|
||||
|
@ -290,6 +294,10 @@ int snd_sbdsp_create(struct snd_card *card,
|
|||
void snd_sbmixer_write(struct snd_sb *chip, unsigned char reg, unsigned char data);
|
||||
unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg);
|
||||
int snd_sbmixer_new(struct snd_sb *chip);
|
||||
#ifdef CONFIG_PM
|
||||
void snd_sbmixer_suspend(struct snd_sb *chip);
|
||||
void snd_sbmixer_resume(struct snd_sb *chip);
|
||||
#endif
|
||||
|
||||
/* sb8_init.c */
|
||||
int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm);
|
||||
|
|
|
@ -307,10 +307,12 @@ static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
|
|||
spin_lock(&chip->reg_lock);
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
chip->mode |= SB_RATE_LOCK_PLAYBACK;
|
||||
snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
|
||||
/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
|
||||
if (chip->mode & SB_RATE_LOCK_CAPTURE)
|
||||
|
@ -374,10 +376,12 @@ static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
|
|||
spin_lock(&chip->reg_lock);
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
chip->mode |= SB_RATE_LOCK_CAPTURE;
|
||||
snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
|
||||
/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
|
||||
if (chip->mode & SB_RATE_LOCK_PLAYBACK)
|
||||
|
|
|
@ -293,6 +293,10 @@ EXPORT_SYMBOL(snd_sbmixer_write);
|
|||
EXPORT_SYMBOL(snd_sbmixer_read);
|
||||
EXPORT_SYMBOL(snd_sbmixer_new);
|
||||
EXPORT_SYMBOL(snd_sbmixer_add_ctl);
|
||||
#ifdef CONFIG_PM
|
||||
EXPORT_SYMBOL(snd_sbmixer_suspend);
|
||||
EXPORT_SYMBOL(snd_sbmixer_resume);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
|
|
|
@ -853,3 +853,140 @@ int snd_sbmixer_new(struct snd_sb *chip)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static unsigned char sb20_saved_regs[] = {
|
||||
SB_DSP20_MASTER_DEV,
|
||||
SB_DSP20_PCM_DEV,
|
||||
SB_DSP20_FM_DEV,
|
||||
SB_DSP20_CD_DEV,
|
||||
};
|
||||
|
||||
static unsigned char sbpro_saved_regs[] = {
|
||||
SB_DSP_MASTER_DEV,
|
||||
SB_DSP_PCM_DEV,
|
||||
SB_DSP_PLAYBACK_FILT,
|
||||
SB_DSP_FM_DEV,
|
||||
SB_DSP_CD_DEV,
|
||||
SB_DSP_LINE_DEV,
|
||||
SB_DSP_MIC_DEV,
|
||||
SB_DSP_CAPTURE_SOURCE,
|
||||
SB_DSP_CAPTURE_FILT,
|
||||
};
|
||||
|
||||
static unsigned char sb16_saved_regs[] = {
|
||||
SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
|
||||
SB_DSP4_3DSE,
|
||||
SB_DSP4_BASS_DEV, SB_DSP4_BASS_DEV + 1,
|
||||
SB_DSP4_TREBLE_DEV, SB_DSP4_TREBLE_DEV + 1,
|
||||
SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
|
||||
SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
|
||||
SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
|
||||
SB_DSP4_OUTPUT_SW,
|
||||
SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
|
||||
SB_DSP4_LINE_DEV, SB_DSP4_LINE_DEV + 1,
|
||||
SB_DSP4_MIC_DEV,
|
||||
SB_DSP4_SPEAKER_DEV,
|
||||
SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1,
|
||||
SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1,
|
||||
SB_DSP4_MIC_AGC
|
||||
};
|
||||
|
||||
static unsigned char dt019x_saved_regs[] = {
|
||||
SB_DT019X_MASTER_DEV,
|
||||
SB_DT019X_PCM_DEV,
|
||||
SB_DT019X_SYNTH_DEV,
|
||||
SB_DT019X_CD_DEV,
|
||||
SB_DT019X_MIC_DEV,
|
||||
SB_DT019X_SPKR_DEV,
|
||||
SB_DT019X_LINE_DEV,
|
||||
SB_DSP4_OUTPUT_SW,
|
||||
SB_DT019X_OUTPUT_SW2,
|
||||
SB_DT019X_CAPTURE_SW,
|
||||
};
|
||||
|
||||
static unsigned char als4000_saved_regs[] = {
|
||||
SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
|
||||
SB_DSP4_OUTPUT_SW,
|
||||
SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
|
||||
SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
|
||||
SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
|
||||
SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
|
||||
SB_DSP4_MIC_AGC,
|
||||
SB_DSP4_MIC_DEV,
|
||||
SB_DSP4_SPEAKER_DEV,
|
||||
SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1,
|
||||
SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1,
|
||||
SB_DT019X_OUTPUT_SW2,
|
||||
SB_ALS4000_MONO_IO_CTRL,
|
||||
SB_ALS4000_MIC_IN_GAIN,
|
||||
SB_ALS4000_3D_SND_FX,
|
||||
SB_ALS4000_3D_TIME_DELAY,
|
||||
};
|
||||
|
||||
static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
|
||||
{
|
||||
unsigned char *val = chip->saved_regs;
|
||||
snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
|
||||
for (; num_regs; num_regs--)
|
||||
*val++ = snd_sbmixer_read(chip, *regs++);
|
||||
}
|
||||
|
||||
static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
|
||||
{
|
||||
unsigned char *val = chip->saved_regs;
|
||||
snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
|
||||
for (; num_regs; num_regs--)
|
||||
snd_sbmixer_write(chip, *regs++, *val++);
|
||||
}
|
||||
|
||||
void snd_sbmixer_suspend(struct snd_sb *chip)
|
||||
{
|
||||
switch (chip->hardware) {
|
||||
case SB_HW_20:
|
||||
case SB_HW_201:
|
||||
save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
|
||||
break;
|
||||
case SB_HW_PRO:
|
||||
save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
|
||||
break;
|
||||
case SB_HW_16:
|
||||
case SB_HW_ALS100:
|
||||
save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
|
||||
break;
|
||||
case SB_HW_ALS4000:
|
||||
save_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs));
|
||||
break;
|
||||
case SB_HW_DT019X:
|
||||
save_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void snd_sbmixer_resume(struct snd_sb *chip)
|
||||
{
|
||||
switch (chip->hardware) {
|
||||
case SB_HW_20:
|
||||
case SB_HW_201:
|
||||
restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
|
||||
break;
|
||||
case SB_HW_PRO:
|
||||
restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
|
||||
break;
|
||||
case SB_HW_16:
|
||||
case SB_HW_ALS100:
|
||||
restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
|
||||
break;
|
||||
case SB_HW_ALS4000:
|
||||
restore_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs));
|
||||
break;
|
||||
case SB_HW_DT019X:
|
||||
restore_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue