#undef IO_DEBUG
-void snd_sbmixer_write(sb_t *chip, unsigned char reg, unsigned char data)
+void snd_sbmixer_write(struct snd_sb *chip, unsigned char reg, unsigned char data)
{
outb(reg, SBP(chip, MIXER_ADDR));
udelay(10);
#endif
}
-unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg)
+unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg)
{
unsigned char result;
* Single channel mixer element
*/
-static int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sbmixer_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
int mask = (kcontrol->private_value >> 24) & 0xff;
return 0;
}
-static int snd_sbmixer_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 16) & 0xff;
return 0;
}
-static int snd_sbmixer_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 16) & 0x07;
* Double channel mixer element
*/
-static int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sbmixer_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
int mask = (kcontrol->private_value >> 24) & 0xff;
return 0;
}
-static int snd_sbmixer_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
return 0;
}
-static int snd_sbmixer_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
* DT-019x / ALS-007 capture/input switch
*/
-static int snd_dt019x_input_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
static char *texts[5] = {
"CD", "Mic", "Line", "Synth", "Master"
return 0;
}
-static int snd_dt019x_input_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
unsigned char oval;
return 0;
}
-static int snd_dt019x_input_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int change;
unsigned char nval, oval;
* SBPRO input multiplexer
*/
-static int snd_sb8mixer_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
static char *texts[3] = {
"Mic", "CD", "Line"
}
-static int snd_sb8mixer_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb8mixer_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
unsigned char oval;
return 0;
}
-static int snd_sb8mixer_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb8mixer_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int change;
unsigned char nval, oval;
* SB16 input switch
*/
-static int snd_sb16mixer_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb16mixer_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 4;
return 0;
}
-static int snd_sb16mixer_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16mixer_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg1 = kcontrol->private_value & 0xff;
int reg2 = (kcontrol->private_value >> 8) & 0xff;
return 0;
}
-static int snd_sb16mixer_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- sb_t *sb = snd_kcontrol_chip(kcontrol);
+ struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg1 = kcontrol->private_value & 0xff;
int reg2 = (kcontrol->private_value >> 8) & 0xff;
*/
/*
*/
-int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value)
+int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int type, unsigned long value)
{
- static snd_kcontrol_new_t newctls[] = {
+ static struct snd_kcontrol_new newctls[] = {
[SB_MIX_SINGLE] = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.info = snd_sbmixer_info_single,
.put = snd_dt019x_input_sw_put,
},
};
- snd_kcontrol_t *ctl;
+ struct snd_kcontrol *ctl;
int err;
ctl = snd_ctl_new1(&newctls[type], chip);
strlcpy(ctl->id.name, name, sizeof(ctl->id.name));
ctl->id.index = index;
ctl->private_value = value;
- if ((err = snd_ctl_add(chip->card, ctl)) < 0) {
- snd_ctl_free_one(ctl);
+ if ((err = snd_ctl_add(chip->card, ctl)) < 0)
return err;
- }
return 0;
}
/*
*/
-static int snd_sbmixer_init(sb_t *chip,
+static int snd_sbmixer_init(struct snd_sb *chip,
struct sbmix_elem **controls,
int controls_count,
unsigned char map[][2],
char *name)
{
unsigned long flags;
- snd_card_t *card = chip->card;
+ struct snd_card *card = chip->card;
int idx, err;
/* mixer reset */
return 0;
}
-int snd_sbmixer_new(sb_t *chip)
+int snd_sbmixer_new(struct snd_sb *chip)
{
- snd_card_t * card;
+ struct snd_card *card;
int err;
snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
}
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