diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-01-07 05:54:34 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-12 02:43:52 -0500 |
commit | e6b85f3c9d5ea3807dee651c28d5b0d5982ae2fa (patch) | |
tree | d92d1da51d487dcaa18966427b1ce09285dd3d82 /sound/pci/hda/hda_generic.c | |
parent | c2c803830a5d9897344cd3ffd82daddd7f9f3864 (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.c | 65 |
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 | ||
3264 | static 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 | ||
3295 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 3314 | static 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 | ||
3303 | static int playback_pcm_close(struct hda_pcm_stream *hinfo, | 3328 | static 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 | ||
3372 | static 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 | |||
3384 | static 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 | ||