From: Takashi Iwai <tiwai@suse.de>
To: "Subhransu S. Prusty" <subhransu.s.prusty@intel.com>
Cc: patches.audio@intel.com, Vinod Koul <vinod.koul@intel.com>,
alsa-devel@alsa-project.org, broonie@kernel.org,
lgirdwood@gmail.com
Subject: Re: [PATCH 05/15] ASoC: hdac_hdmi: Add hotplug notification and read eld
Date: Tue, 01 Dec 2015 13:37:37 +0100 [thread overview]
Message-ID: <s5hwpsypcoe.wl-tiwai@suse.de> (raw)
In-Reply-To: <1448992031-8271-5-git-send-email-subhransu.s.prusty@intel.com>
On Tue, 01 Dec 2015 18:47:01 +0100,
Subhransu S. Prusty wrote:
>
> This patch uses i915 component framework to register for hotplug
> notification. And once it identifies valid pin sense and valid eld,
> reads the eld into the corresponding pin map buffer. For now it
> directly sends the verbs and reads the eld. Later this will use
> the i915 framework to populate ELD buffer once available.
This will have the same problem as we had in patch_hdmi.c.
When a sound driver goes to sleep before i915 and i915 triggers the
eld_notify for audio disablement, it can be screwed up.
See the commit 8ae743e82f0b86f3b860c27fc2c8f574cf959fd0
ALSA: hda - Skip ELD notification during system suspend
in for-linus branch of sound git tree.
Takashi
>
> Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
> sound/soc/codecs/hdac_hdmi.c | 125 ++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 118 insertions(+), 7 deletions(-)
>
> diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
> index 0869855..203c99f 100644
> --- a/sound/soc/codecs/hdac_hdmi.c
> +++ b/sound/soc/codecs/hdac_hdmi.c
> @@ -34,6 +34,9 @@
>
> #define HDA_MAX_CONNECTIONS 32
>
> +#define ELD_MAX_SIZE 256
> +#define ELD_FIXED_BYTES 20
> +
> struct hdac_hdmi_cvt_params {
> unsigned int channels_min;
> unsigned int channels_max;
> @@ -48,11 +51,22 @@ struct hdac_hdmi_cvt {
> struct hdac_hdmi_cvt_params params;
> };
>
> +struct hdmi_eld {
> + bool monitor_present;
> + bool eld_valid;
> + int eld_size;
> + char eld_buffer[ELD_MAX_SIZE];
> +};
> +
> struct hdac_hdmi_pin {
> struct list_head head;
> hda_nid_t nid;
> int num_mux_nids;
> hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
> + struct hdmi_eld eld;
> + struct hdac_ext_device *edev;
> + int repoll_count;
> + struct delayed_work work;
> };
>
> struct hdac_hdmi_dai_pin_map {
> @@ -246,7 +260,6 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
> struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
> struct hdac_hdmi_priv *hdmi = hdac->private_data;
> struct hdac_hdmi_dai_pin_map *dai_map;
> - int val;
>
> if (dai->id > 0) {
> dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
> @@ -255,12 +268,11 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
>
> dai_map = &hdmi->dai_map[dai->id];
>
> - val = snd_hdac_codec_read(&hdac->hdac, dai_map->pin->nid, 0,
> - AC_VERB_GET_PIN_SENSE, 0);
> - dev_info(&hdac->hdac.dev, "Val for AC_VERB_GET_PIN_SENSE: %x\n", val);
> -
> - if ((!(val & AC_PINSENSE_PRESENCE)) || (!(val & AC_PINSENSE_ELDV))) {
> - dev_err(&hdac->hdac.dev, "Monitor presence invalid with val: %x\n", val);
> + if ((!dai_map->pin->eld.monitor_present) ||
> + (!dai_map->pin->eld.eld_valid)) {
> + dev_err(&hdac->hdac.dev, "Failed: montior present? %d eld valid?: %d\n",
> + dai_map->pin->eld.monitor_present,
> + dai_map->pin->eld.eld_valid);
> return -ENODEV;
> }
>
> @@ -432,6 +444,68 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
> return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
> }
>
> +static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
> +{
> + struct hdac_ext_device *edev = pin->edev;
> + int val;
> +
> + if (!edev)
> + return;
> +
> + pin->repoll_count = repoll;
> +
> + pm_runtime_get_sync(&edev->hdac.dev);
> + val = snd_hdac_codec_read(&edev->hdac, pin->nid, 0,
> + AC_VERB_GET_PIN_SENSE, 0);
> +
> + dev_dbg(&edev->hdac.dev, "Pin sense val %x for pin: %d\n",
> + val, pin->nid);
> + pin->eld.monitor_present = !!(val & AC_PINSENSE_PRESENCE);
> + pin->eld.eld_valid = !!(val & AC_PINSENSE_ELDV);
> +
> + if (!pin->eld.monitor_present || !pin->eld.eld_valid) {
> + dev_info(&edev->hdac.dev, "%s: disconnect or eld_invalid\n",
> + __func__);
> + goto put_hdac_device;
> + }
> +
> + if (pin->eld.monitor_present && pin->eld.eld_valid) {
> + /* TODO: Use i915 cmpnt framework when available */
> + if (snd_hdac_get_eld(&edev->hdac, pin->nid,
> + pin->eld.eld_buffer,
> + &pin->eld.eld_size) == 0) {
> + print_hex_dump_bytes("Eld: ", DUMP_PREFIX_OFFSET,
> + pin->eld.eld_buffer, pin->eld.eld_size);
> + } else {
> + dev_err(&edev->hdac.dev, "ELD invalid\n");
> + pin->eld.monitor_present = false;
> + pin->eld.eld_valid = false;
> + }
> +
> + }
> +
> + /*
> + * Sometimes the pin_sense may present invalid monitor
> + * present and eld_valid. If eld data is not valid loop, few
> + * more times to get correct pin sense and valid eld.
> + */
> + if ((!pin->eld.monitor_present || !pin->eld.eld_valid) && repoll)
> + schedule_delayed_work(&pin->work, msecs_to_jiffies(300));
> +
> +put_hdac_device:
> + pm_runtime_put_sync(&edev->hdac.dev);
> +}
> +static void hdac_hdmi_repoll_eld(struct work_struct *work)
> +{
> + struct hdac_hdmi_pin *pin =
> + container_of(to_delayed_work(work), struct hdac_hdmi_pin, work);
> +
> + /* picked from legacy */
> + if (pin->repoll_count++ > 6)
> + pin->repoll_count = 0;
> +
> + hdac_hdmi_present_sense(pin, pin->repoll_count);
> +}
> static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
> {
> struct hdac_hdmi_priv *hdmi = edev->private_data;
> @@ -446,6 +520,9 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
> list_add_tail(&pin->head, &hdmi->pin_list);
> hdmi->num_pin++;
>
> + pin->edev = edev;
> + INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld);
> +
> return 0;
> }
>
> @@ -503,17 +580,50 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
> return hdac_hdmi_init_dai_map(edev);
> }
>
> +static void hdac_hdmi_eld_notify_cb(void *aptr, int port)
> +{
> + struct hdac_ext_device *edev = aptr;
> + struct hdac_hdmi_priv *hdmi = edev->private_data;
> + struct hdac_hdmi_pin *pin;
> + /* Don't know how this mapping is derived */
> + hda_nid_t pin_nid = port + 0x04;
> +
> + dev_dbg(&edev->hdac.dev, "%s: for pin: %d\n", __func__, pin_nid);
> +
> + list_for_each_entry(pin, &hdmi->pin_list, head) {
> + if (pin->nid == pin_nid)
> + hdac_hdmi_present_sense(pin, 1);
> + }
> +}
> +
> +static struct i915_audio_component_audio_ops aops = {
> + .pin_eld_notify = hdac_hdmi_eld_notify_cb,
> +};
> +
> static int hdmi_codec_probe(struct snd_soc_codec *codec)
> {
> struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
> struct hdac_hdmi_priv *hdmi = edev->private_data;
> struct snd_soc_dapm_context *dapm =
> snd_soc_component_get_dapm(&codec->component);
> + struct hdac_hdmi_pin *pin;
> + int ret;
>
> edev->scodec = codec;
>
> create_fill_widget_route_map(dapm, &hdmi->dai_map[0]);
>
> + aops.audio_ptr = edev;
> + ret = snd_hdac_i915_register_notifier(&aops);
> + if (ret < 0) {
> + dev_err(&edev->hdac.dev, "notifier register failed: err: %d\n",
> + ret);
> + return ret;
> + }
> +
> + list_for_each_entry(pin, &hdmi->pin_list, head)
> + hdac_hdmi_eld_notify_cb(edev, (pin->nid - 0x04));
> +
> /* Imp: Store the card pointer in hda_codec */
> edev->card = dapm->card->snd_card;
>
> @@ -644,6 +754,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
> if (!bus)
> return 0;
>
> +
> err = snd_hdac_display_power(bus, true);
> if (err < 0) {
> dev_err(bus->dev, "Cannot turn on display power on i915\n");
> --
> 1.9.1
>
next prev parent reply other threads:[~2015-12-01 12:37 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-01 17:42 [PATCH 00/15] ASoC: hdac_hdmi: Add DP & notification support Subhransu S. Prusty
2015-12-01 17:46 ` [PATCH 01/15] ASoC: hdac_hdmi: Fix to check num nodes correctly Subhransu S. Prusty
2015-12-01 12:27 ` Takashi Iwai
2015-12-01 19:08 ` Subhransu S. Prusty
2015-12-01 17:46 ` [PATCH 02/15] ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids Subhransu S. Prusty
2016-01-08 13:44 ` Applied "ASoC: hdac_hdmi: Fix to warn instead of err for no connected nids" to the asoc tree Mark Brown
2015-12-01 17:46 ` [PATCH 03/15] ASoC: hdac_hdmi - Use list to add pins and converters Subhransu S. Prusty
2015-12-01 12:47 ` Takashi Iwai
2015-12-01 22:50 ` Subhransu S. Prusty
2015-12-01 18:52 ` Takashi Iwai
2015-12-02 9:31 ` Takashi Iwai
2015-12-03 10:36 ` Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 04/15] ALSA: hda - Add helper to read eld data Subhransu S. Prusty
2015-12-01 12:39 ` Takashi Iwai
2015-12-01 19:12 ` Subhransu S. Prusty
2015-12-01 13:55 ` Takashi Iwai
2015-12-01 17:47 ` [PATCH 05/15] ASoC: hdac_hdmi: Add hotplug notification and read eld Subhransu S. Prusty
2015-12-01 12:37 ` Takashi Iwai [this message]
2015-12-01 20:14 ` Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 06/15] ALSA: pcm: Add DRM helper to set constraint for format Subhransu S. Prusty
2015-12-01 12:55 ` Takashi Iwai
2015-12-02 12:27 ` Subhransu S. Prusty
2015-12-02 9:23 ` Takashi Iwai
2015-12-01 17:47 ` [PATCH 07/15] ASoC: hdac_hdmi: Apply constraints based on ELD Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 08/15] ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 09/15] ASoC: hdac_hdmi - create dais based on number of streams Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 10/15] ASoC: hdac_hdmi: Create widget/route based on nodes enumerated Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 11/15] ASoC: hdac_hdmi: Assign pin for stream based on dapm connection Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 12/15] drm/edid: Add API to help find connection type Subhransu S. Prusty
2015-12-02 9:53 ` Jani Nikula
2015-12-02 17:07 ` Thierry Reding
2015-12-03 16:08 ` [alsa-devel] " Subhransu S. Prusty
2015-12-03 11:09 ` Jani Nikula
2015-12-03 11:21 ` Thierry Reding
2015-12-03 17:14 ` Subhransu S. Prusty
2015-12-02 17:16 ` Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 13/15] ASoC: hdac_hdmi: Add infoframe support for dp audio Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 14/15] ASoC: hdac_hdmi: Add codec suspend/resume handler Subhransu S. Prusty
2015-12-01 17:47 ` [PATCH 15/15] ASoC: hdac_hdmi: Keep display active while enumerating codec Subhransu S. Prusty
2015-12-01 12:57 ` Takashi Iwai
2015-12-01 21:48 ` Subhransu S. Prusty
2015-12-01 16:33 ` Takashi Iwai
2015-12-01 16:48 ` Babu, Ramesh
2015-12-01 17:08 ` Takashi Iwai
2015-12-02 15:37 ` Subhransu S. Prusty
2015-12-02 10:24 ` Takashi Iwai
2015-12-02 10:31 ` Takashi Iwai
2015-12-02 16:23 ` Subhransu S. Prusty
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5hwpsypcoe.wl-tiwai@suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=patches.audio@intel.com \
--cc=subhransu.s.prusty@intel.com \
--cc=vinod.koul@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.