Skip to content

Commit

Permalink
ALSA: hda: 92HD75xx fixes
Browse files Browse the repository at this point in the history
Fixed several noise issues with DACs and ADCs on some 92HD75xxx based codecs
with certain revision id's.

Signed-off-by: Matthew Ranostay <mranostay@embeddedalley.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
Matthew Ranostay authored and Jaroslav Kysela committed Aug 15, 2008
1 parent 4682eee commit 8daaaa9
Showing 1 changed file with 82 additions and 5 deletions.
87 changes: 82 additions & 5 deletions sound/pci/hda/patch_sigmatel.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ struct sigmatel_spec {
unsigned int gpio_data;
unsigned int gpio_mute;

/* stream */
unsigned int stream_delay;

/* analog loopback */
unsigned char aloopback_mask;
unsigned char aloopback_shift;
Expand Down Expand Up @@ -190,6 +193,7 @@ struct sigmatel_spec {
unsigned int cur_dmux[2];
struct hda_input_mux *input_mux;
unsigned int cur_mux[3];
unsigned int powerdown_adcs;

/* i/o switches */
unsigned int io_switch[2];
Expand Down Expand Up @@ -1996,6 +2000,8 @@ static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct sigmatel_spec *spec = codec->spec;
if (spec->stream_delay)
msleep(spec->stream_delay);
return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
hinfo);
}
Expand Down Expand Up @@ -2059,9 +2065,14 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct sigmatel_spec *spec = codec->spec;
hda_nid_t nid = spec->adc_nids[substream->number];

snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
stream_tag, 0, format);
if (spec->powerdown_adcs) {
msleep(40);
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
}
snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
return 0;
}

Expand All @@ -2070,8 +2081,12 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct snd_pcm_substream *substream)
{
struct sigmatel_spec *spec = codec->spec;
hda_nid_t nid = spec->adc_nids[substream->number];

snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
snd_hda_codec_cleanup_stream(codec, nid);
if (spec->powerdown_adcs)
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
return 0;
}

Expand Down Expand Up @@ -3296,6 +3311,12 @@ static int stac92xx_init(struct hda_codec *codec)

snd_hda_sequence_write(codec, spec->init);

/* power down adcs initially */
if (spec->powerdown_adcs)
for (i = 0; i < spec->num_adcs; i++)
snd_hda_codec_write_cache(codec,
spec->adc_nids[i], 0,
AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
/* set up pins */
if (spec->hp_detect) {
/* Enable unsolicited responses on the HP widget */
Expand Down Expand Up @@ -3930,6 +3951,47 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
return 0;
}

#ifdef SND_HDA_NEEDS_RESUME
static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
{
struct sigmatel_spec *spec = codec->spec;
int i;
snd_hda_codec_write_cache(codec, codec->afg, 0,
AC_VERB_SET_POWER_STATE, pwr);

msleep(1);
for (i = 0; i < spec->num_adcs; i++) {
snd_hda_codec_write_cache(codec,
spec->adc_nids[i], 0,
AC_VERB_SET_POWER_STATE, pwr);
}
};

static int stac92hd71xx_resume(struct hda_codec *codec)
{
stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
return stac92xx_resume(codec);
}

static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
{
stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
return 0;
};

#endif

static struct hda_codec_ops stac92hd71bxx_patch_ops = {
.build_controls = stac92xx_build_controls,
.build_pcms = stac92xx_build_pcms,
.init = stac92xx_init,
.free = stac92xx_free,
.unsol_event = stac92xx_unsol_event,
#ifdef SND_HDA_NEEDS_RESUME
.resume = stac92hd71xx_resume,
.suspend = stac92hd71xx_suspend,
#endif
};

static int patch_stac92hd71bxx(struct hda_codec *codec)
{
Expand All @@ -3941,6 +4003,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
return -ENOMEM;

codec->spec = spec;
codec->patch_ops = stac92xx_patch_ops;
spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
spec->pin_nids = stac92hd71bxx_pin_nids;
Expand Down Expand Up @@ -3972,6 +4035,14 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
spec->init = stac92hd71bxx_core_init;
break;
case 0x111d7608: /* 5 Port with Analog Mixer */
if ((codec->revision_id & 0xf) == 0 ||
(codec->revision_id & 0xf) == 1) {
#ifdef SND_HDA_NEEDS_RESUME
codec->patch_ops = stac92hd71bxx_patch_ops;
#endif
spec->stream_delay = 40; /* 40 milliseconds */
}

/* no output amps */
spec->num_pwrs = 0;
spec->mixer = stac92hd71bxx_analog_mixer;
Expand All @@ -3981,6 +4052,13 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
stac92xx_set_config_reg(codec, 0xf, 0x40f000f0);
break;
case 0x111d7603: /* 6 Port with Analog Mixer */
if ((codec->revision_id & 0xf) == 1) {
#ifdef SND_HDA_NEEDS_RESUME
codec->patch_ops = stac92hd71bxx_patch_ops;
#endif
spec->stream_delay = 40; /* 40 milliseconds */
}

/* no output amps */
spec->num_pwrs = 0;
/* fallthru */
Expand All @@ -3997,6 +4075,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
spec->gpio_dir = 0x01;
spec->gpio_data = 0x01;

spec->powerdown_adcs = 1;
spec->digbeep_nid = 0x26;
spec->mux_nids = stac92hd71bxx_mux_nids;
spec->adc_nids = stac92hd71bxx_adc_nids;
Expand Down Expand Up @@ -4029,8 +4108,6 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
return err;
}

codec->patch_ops = stac92xx_patch_ops;

return 0;
};

Expand Down

0 comments on commit 8daaaa9

Please sign in to comment.