Commit fc0daafe authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/hda-power' into for-next

parents b24062bd 5ccf835c
......@@ -33,30 +33,36 @@ enum {
DIGBEEP_HZ_MAX = 12000000, /* 12 KHz */
};
static void snd_hda_generate_beep(struct work_struct *work)
/* generate or stop tone */
static void generate_tone(struct hda_beep *beep, int tone)
{
struct hda_beep *beep =
container_of(work, struct hda_beep, beep_work);
struct hda_codec *codec = beep->codec;
int tone;
if (!beep->enabled)
return;
tone = beep->tone;
if (tone && !beep->playing) {
snd_hda_power_up(codec);
if (beep->power_hook)
beep->power_hook(beep, true);
beep->playing = 1;
}
/* generate tone */
snd_hda_codec_write(codec, beep->nid, 0,
AC_VERB_SET_BEEP_CONTROL, tone);
if (!tone && beep->playing) {
beep->playing = 0;
if (beep->power_hook)
beep->power_hook(beep, false);
snd_hda_power_down(codec);
}
}
static void snd_hda_generate_beep(struct work_struct *work)
{
struct hda_beep *beep =
container_of(work, struct hda_beep, beep_work);
if (beep->enabled)
generate_tone(beep, beep->tone);
}
/* (non-standard) Linear beep tone calculation for IDT/STAC codecs
*
* The tone frequency of beep generator on IDT/STAC codecs is
......@@ -130,10 +136,7 @@ static void turn_off_beep(struct hda_beep *beep)
cancel_work_sync(&beep->beep_work);
if (beep->playing) {
/* turn off beep */
snd_hda_codec_write(beep->codec, beep->nid, 0,
AC_VERB_SET_BEEP_CONTROL, 0);
beep->playing = 0;
snd_hda_power_down(beep->codec);
generate_tone(beep, 0);
}
}
......
......@@ -40,6 +40,7 @@ struct hda_beep {
unsigned int playing:1;
struct work_struct beep_work; /* scheduled task for beep event */
struct mutex mutex;
void (*power_hook)(struct hda_beep *beep, bool on);
};
#ifdef CONFIG_SND_HDA_INPUT_BEEP
......
......@@ -1502,6 +1502,8 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
if (!p)
return;
if (codec->patch_ops.stream_pm)
codec->patch_ops.stream_pm(codec, nid, true);
if (codec->pcm_format_first)
update_pcm_format(codec, p, nid, format);
update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
......@@ -1570,6 +1572,8 @@ static void really_cleanup_stream(struct hda_codec *codec,
);
memset(q, 0, sizeof(*q));
q->nid = nid;
if (codec->patch_ops.stream_pm)
codec->patch_ops.stream_pm(codec, nid, false);
}
/* clean up the all conflicting obsolete streams */
......
......@@ -200,6 +200,7 @@ struct hda_codec_ops {
int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
#endif
void (*reboot_notify)(struct hda_codec *codec);
void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on);
};
/* record for amp information cache */
......@@ -370,6 +371,7 @@ struct hda_codec {
unsigned int cached_write:1; /* write only to caches */
unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
unsigned int power_mgmt:1; /* advanced PM for each widget */
#ifdef CONFIG_PM
unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
atomic_t in_pm; /* suspend/resume being performed */
......
This diff is collapsed.
......@@ -46,7 +46,9 @@ struct nid_path {
unsigned char idx[MAX_NID_PATH_DEPTH];
unsigned char multi[MAX_NID_PATH_DEPTH];
unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */
bool active;
bool active:1; /* activated by driver */
bool pin_enabled:1; /* pins are enabled */
bool stream_enabled:1; /* stream is active */
};
/* mic/line-in auto switching entry */
......@@ -340,5 +342,6 @@ int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
hda_nid_t nid,
unsigned int power_state);
void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
#endif /* __SOUND_HDA_GENERIC_H */
......@@ -2602,53 +2602,12 @@ static int patch_alc268(struct hda_codec *codec)
* ALC269
*/
static int playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct hda_gen_spec *spec = codec->spec;
return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
hinfo);
}
static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
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);
}
static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct hda_gen_spec *spec = codec->spec;
return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
}
static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
/* NID is set in alc_build_pcms */
.ops = {
.open = playback_pcm_open,
.prepare = playback_pcm_prepare,
.cleanup = playback_pcm_cleanup
},
};
static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
/* NID is set in alc_build_pcms */
};
/* different alc269-variants */
......
......@@ -4394,6 +4394,7 @@ static const struct hda_codec_ops stac_patch_ops = {
#ifdef CONFIG_PM
.suspend = stac_suspend,
#endif
.stream_pm = snd_hda_gen_stream_pm,
.reboot_notify = stac_shutup,
};
......@@ -4487,6 +4488,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
return err;
spec = codec->spec;
codec->power_mgmt = 1;
spec->linear_tone_beep = 0;
spec->gen.mixer_nid = 0x1d;
spec->have_spdif_mux = 1;
......@@ -4592,6 +4594,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
codec->epss = 0; /* longer delay needed for D3 */
spec = codec->spec;
codec->power_mgmt = 1;
spec->linear_tone_beep = 0;
spec->gen.own_eapd_ctl = 1;
spec->gen.power_down_unused = 1;
......@@ -4641,6 +4644,7 @@ static int patch_stac92hd95(struct hda_codec *codec)
codec->epss = 0; /* longer delay needed for D3 */
spec = codec->spec;
codec->power_mgmt = 1;
spec->linear_tone_beep = 0;
spec->gen.own_eapd_ctl = 1;
spec->gen.power_down_unused = 1;
......@@ -4682,6 +4686,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
return err;
spec = codec->spec;
codec->power_mgmt = 1;
spec->linear_tone_beep = 0;
spec->gen.own_eapd_ctl = 1;
spec->gen.power_down_unused = 1;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment