[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;
|
spinlock_t midi_input_lock;
|
||||||
|
|
||||||
struct snd_info_entry *proc_entry;
|
struct snd_info_entry *proc_entry;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
unsigned char saved_regs[0x20];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* I/O ports */
|
/* 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);
|
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);
|
unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg);
|
||||||
int snd_sbmixer_new(struct snd_sb *chip);
|
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 */
|
/* sb8_init.c */
|
||||||
int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm);
|
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);
|
spin_lock(&chip->reg_lock);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
|
case SNDRV_PCM_TRIGGER_RESUME:
|
||||||
chip->mode |= SB_RATE_LOCK_PLAYBACK;
|
chip->mode |= SB_RATE_LOCK_PLAYBACK;
|
||||||
snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
|
snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
|
||||||
break;
|
break;
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
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);
|
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) */
|
/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
|
||||||
if (chip->mode & SB_RATE_LOCK_CAPTURE)
|
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);
|
spin_lock(&chip->reg_lock);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
|
case SNDRV_PCM_TRIGGER_RESUME:
|
||||||
chip->mode |= SB_RATE_LOCK_CAPTURE;
|
chip->mode |= SB_RATE_LOCK_CAPTURE;
|
||||||
snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
|
snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
|
||||||
break;
|
break;
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
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);
|
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) */
|
/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
|
||||||
if (chip->mode & SB_RATE_LOCK_PLAYBACK)
|
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_read);
|
||||||
EXPORT_SYMBOL(snd_sbmixer_new);
|
EXPORT_SYMBOL(snd_sbmixer_new);
|
||||||
EXPORT_SYMBOL(snd_sbmixer_add_ctl);
|
EXPORT_SYMBOL(snd_sbmixer_add_ctl);
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
EXPORT_SYMBOL(snd_sbmixer_suspend);
|
||||||
|
EXPORT_SYMBOL(snd_sbmixer_resume);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INIT part
|
* INIT part
|
||||||
|
|
|
@ -853,3 +853,140 @@ int snd_sbmixer_new(struct snd_sb *chip)
|
||||||
}
|
}
|
||||||
return 0;
|
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…
Add table
Reference in a new issue