aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_generic.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-07 05:54:34 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-12 02:43:52 -0500
commite6b85f3c9d5ea3807dee651c28d5b0d5982ae2fa (patch)
treed92d1da51d487dcaa18966427b1ce09285dd3d82 /sound/pci/hda/hda_generic.c
parentc2c803830a5d9897344cd3ffd82daddd7f9f3864 (diff)
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 <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r--sound/pci/hda/hda_generic.c65
1 files changed, 60 insertions, 5 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 296628b6ffc2..28ad5e98b341 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);
3261 * PCM definitions 3261 * PCM definitions
3262 */ 3262 */
3263 3263
3264static void call_pcm_playback_hook(struct hda_pcm_stream *hinfo,
3265 struct hda_codec *codec,
3266 struct snd_pcm_substream *substream,
3267 int action)
3268{
3269 struct hda_gen_spec *spec = codec->spec;
3270 if (spec->pcm_playback_hook)
3271 spec->pcm_playback_hook(hinfo, codec, substream, action);
3272}
3273
3264/* 3274/*
3265 * Analog playback callbacks 3275 * Analog playback callbacks
3266 */ 3276 */
@@ -3275,8 +3285,11 @@ static int playback_pcm_open(struct hda_pcm_stream *hinfo,
3275 err = snd_hda_multi_out_analog_open(codec, 3285 err = snd_hda_multi_out_analog_open(codec,
3276 &spec->multiout, substream, 3286 &spec->multiout, substream,
3277 hinfo); 3287 hinfo);
3278 if (!err) 3288 if (!err) {
3279 spec->active_streams |= 1 << STREAM_MULTI_OUT; 3289 spec->active_streams |= 1 << STREAM_MULTI_OUT;
3290 call_pcm_playback_hook(hinfo, codec, substream,
3291 HDA_GEN_PCM_ACT_OPEN);
3292 }
3280 mutex_unlock(&spec->pcm_mutex); 3293 mutex_unlock(&spec->pcm_mutex);
3281 return err; 3294 return err;
3282} 3295}
@@ -3288,8 +3301,14 @@ static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3288 struct snd_pcm_substream *substream) 3301 struct snd_pcm_substream *substream)
3289{ 3302{
3290 struct hda_gen_spec *spec = codec->spec; 3303 struct hda_gen_spec *spec = codec->spec;
3291 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 3304 int err;
3292 stream_tag, format, substream); 3305
3306 err = snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3307 stream_tag, format, substream);
3308 if (!err)
3309 call_pcm_playback_hook(hinfo, codec, substream,
3310 HDA_GEN_PCM_ACT_PREPARE);
3311 return err;
3293} 3312}
3294 3313
3295static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3314static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
@@ -3297,7 +3316,13 @@ static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3297 struct snd_pcm_substream *substream) 3316 struct snd_pcm_substream *substream)
3298{ 3317{
3299 struct hda_gen_spec *spec = codec->spec; 3318 struct hda_gen_spec *spec = codec->spec;
3300 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 3319 int err;
3320
3321 err = snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3322 if (!err)
3323 call_pcm_playback_hook(hinfo, codec, substream,
3324 HDA_GEN_PCM_ACT_CLEANUP);
3325 return err;
3301} 3326}
3302 3327
3303static int playback_pcm_close(struct hda_pcm_stream *hinfo, 3328static int playback_pcm_close(struct hda_pcm_stream *hinfo,
@@ -3307,6 +3332,8 @@ static int playback_pcm_close(struct hda_pcm_stream *hinfo,
3307 struct hda_gen_spec *spec = codec->spec; 3332 struct hda_gen_spec *spec = codec->spec;
3308 mutex_lock(&spec->pcm_mutex); 3333 mutex_lock(&spec->pcm_mutex);
3309 spec->active_streams &= ~(1 << STREAM_MULTI_OUT); 3334 spec->active_streams &= ~(1 << STREAM_MULTI_OUT);
3335 call_pcm_playback_hook(hinfo, codec, substream,
3336 HDA_GEN_PCM_ACT_CLOSE);
3310 mutex_unlock(&spec->pcm_mutex); 3337 mutex_unlock(&spec->pcm_mutex);
3311 return 0; 3338 return 0;
3312} 3339}
@@ -3323,6 +3350,8 @@ static int alt_playback_pcm_open(struct hda_pcm_stream *hinfo,
3323 err = -EBUSY; 3350 err = -EBUSY;
3324 else 3351 else
3325 spec->active_streams |= 1 << STREAM_INDEP_HP; 3352 spec->active_streams |= 1 << STREAM_INDEP_HP;
3353 call_pcm_playback_hook(hinfo, codec, substream,
3354 HDA_GEN_PCM_ACT_OPEN);
3326 mutex_unlock(&spec->pcm_mutex); 3355 mutex_unlock(&spec->pcm_mutex);
3327 return err; 3356 return err;
3328} 3357}
@@ -3334,10 +3363,34 @@ static int alt_playback_pcm_close(struct hda_pcm_stream *hinfo,
3334 struct hda_gen_spec *spec = codec->spec; 3363 struct hda_gen_spec *spec = codec->spec;
3335 mutex_lock(&spec->pcm_mutex); 3364 mutex_lock(&spec->pcm_mutex);
3336 spec->active_streams &= ~(1 << STREAM_INDEP_HP); 3365 spec->active_streams &= ~(1 << STREAM_INDEP_HP);
3366 call_pcm_playback_hook(hinfo, codec, substream,
3367 HDA_GEN_PCM_ACT_CLOSE);
3337 mutex_unlock(&spec->pcm_mutex); 3368 mutex_unlock(&spec->pcm_mutex);
3338 return 0; 3369 return 0;
3339} 3370}
3340 3371
3372static int alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3373 struct hda_codec *codec,
3374 unsigned int stream_tag,
3375 unsigned int format,
3376 struct snd_pcm_substream *substream)
3377{
3378 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
3379 call_pcm_playback_hook(hinfo, codec, substream,
3380 HDA_GEN_PCM_ACT_PREPARE);
3381 return 0;
3382}
3383
3384static int alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3385 struct hda_codec *codec,
3386 struct snd_pcm_substream *substream)
3387{
3388 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
3389 call_pcm_playback_hook(hinfo, codec, substream,
3390 HDA_GEN_PCM_ACT_CLEANUP);
3391 return 0;
3392}
3393
3341/* 3394/*
3342 * Digital out 3395 * Digital out
3343 */ 3396 */
@@ -3432,7 +3485,9 @@ static const struct hda_pcm_stream pcm_analog_alt_playback = {
3432 /* NID is set in build_pcms */ 3485 /* NID is set in build_pcms */
3433 .ops = { 3486 .ops = {
3434 .open = alt_playback_pcm_open, 3487 .open = alt_playback_pcm_open,
3435 .close = alt_playback_pcm_close 3488 .close = alt_playback_pcm_close,
3489 .prepare = alt_playback_pcm_prepare,
3490 .cleanup = alt_playback_pcm_cleanup
3436 }, 3491 },
3437}; 3492};
3438 3493