From e6b85f3c9d5ea3807dee651c28d5b0d5982ae2fa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 7 Jan 2013 11:54:34 +0100 Subject: ALSA: hda - Add pcm_playback_hook to hda_gen_spec The new hook which is called at each PCM playback ops. It can be used to control the codec-specific power-saving feature in each codec driver. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 65 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 5 deletions(-) (limited to 'sound/pci/hda/hda_generic.c') diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 296628b6ffc..28ad5e98b34 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -3261,6 +3261,16 @@ EXPORT_SYMBOL_HDA(snd_hda_gen_build_controls); * PCM definitions */ +static void call_pcm_playback_hook(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream, + int action) +{ + struct hda_gen_spec *spec = codec->spec; + if (spec->pcm_playback_hook) + spec->pcm_playback_hook(hinfo, codec, substream, action); +} + /* * Analog playback callbacks */ @@ -3275,8 +3285,11 @@ static int playback_pcm_open(struct hda_pcm_stream *hinfo, err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, hinfo); - if (!err) + if (!err) { spec->active_streams |= 1 << STREAM_MULTI_OUT; + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_OPEN); + } mutex_unlock(&spec->pcm_mutex); return err; } @@ -3288,8 +3301,14 @@ static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { struct hda_gen_spec *spec = codec->spec; - return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, - stream_tag, format, substream); + int err; + + err = snd_hda_multi_out_analog_prepare(codec, &spec->multiout, + stream_tag, format, substream); + if (!err) + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_PREPARE); + return err; } static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, @@ -3297,7 +3316,13 @@ static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { struct hda_gen_spec *spec = codec->spec; - return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); + int err; + + err = snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); + if (!err) + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_CLEANUP); + return err; } static int playback_pcm_close(struct hda_pcm_stream *hinfo, @@ -3307,6 +3332,8 @@ static int playback_pcm_close(struct hda_pcm_stream *hinfo, struct hda_gen_spec *spec = codec->spec; mutex_lock(&spec->pcm_mutex); spec->active_streams &= ~(1 << STREAM_MULTI_OUT); + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_CLOSE); mutex_unlock(&spec->pcm_mutex); return 0; } @@ -3323,6 +3350,8 @@ static int alt_playback_pcm_open(struct hda_pcm_stream *hinfo, err = -EBUSY; else spec->active_streams |= 1 << STREAM_INDEP_HP; + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_OPEN); mutex_unlock(&spec->pcm_mutex); return err; } @@ -3334,10 +3363,34 @@ static int alt_playback_pcm_close(struct hda_pcm_stream *hinfo, struct hda_gen_spec *spec = codec->spec; mutex_lock(&spec->pcm_mutex); spec->active_streams &= ~(1 << STREAM_INDEP_HP); + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_CLOSE); mutex_unlock(&spec->pcm_mutex); return 0; } +static int alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_PREPARE); + return 0; +} + +static int alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + snd_hda_codec_cleanup_stream(codec, hinfo->nid); + call_pcm_playback_hook(hinfo, codec, substream, + HDA_GEN_PCM_ACT_CLEANUP); + return 0; +} + /* * Digital out */ @@ -3432,7 +3485,9 @@ static const struct hda_pcm_stream pcm_analog_alt_playback = { /* NID is set in build_pcms */ .ops = { .open = alt_playback_pcm_open, - .close = alt_playback_pcm_close + .close = alt_playback_pcm_close, + .prepare = alt_playback_pcm_prepare, + .cleanup = alt_playback_pcm_cleanup }, }; -- cgit v1.2.3