On Fri, Dec 04, 2015 at 06:12:49PM +0100, Takashi Iwai wrote:
> A couple of i915_audio_component ops have been added and accessed
> directly from patch_hdmi.c.  Ideally all these should be factored out
> into hdac_i915.c.
> 
> This patch does it, adds two new helper functions for setting N/CTS
> and fetching ELD bytes.  One bonus is that the hackish widget vs port
> mapping is also moved to hdac_i915.c, so that it can be fixed /
> enhanced more cleanly.
> 
> Signed-off-by: Takashi Iwai <[email protected]>

Reviewed-by: Vinod Koul <[email protected]>

-- 
~Vinod
> ---
>  include/sound/hda_i915.h   | 14 ++++++++++
>  sound/hda/hdac_i915.c      | 66 ++++++++++++++++++++++++++++++++++++++++++++
>  sound/pci/hda/patch_hdmi.c | 69 
> +++++++++++++++++-----------------------------
>  3 files changed, 106 insertions(+), 43 deletions(-)
> 
> diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> index 930b41e5acf4..fa341fcb5829 100644
> --- a/include/sound/hda_i915.h
> +++ b/include/sound/hda_i915.h
> @@ -10,6 +10,9 @@
>  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
>  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
>  int snd_hdac_get_display_clk(struct hdac_bus *bus);
> +int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate);
> +int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
> +                        bool *audio_enabled, char *buffer, int max_bytes);
>  int snd_hdac_i915_init(struct hdac_bus *bus);
>  int snd_hdac_i915_exit(struct hdac_bus *bus);
>  int snd_hdac_i915_register_notifier(const struct 
> i915_audio_component_audio_ops *);
> @@ -26,6 +29,17 @@ static inline int snd_hdac_get_display_clk(struct hdac_bus 
> *bus)
>  {
>       return 0;
>  }
> +static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t 
> nid,
> +                                        int rate)
> +{
> +     return 0;
> +}
> +static inline int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
> +                                      bool *audio_enabled, char *buffer,
> +                                      int max_bytes)
> +{
> +     return -ENODEV;
> +}
>  static inline int snd_hdac_i915_init(struct hdac_bus *bus)
>  {
>       return -ENODEV;
> diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> index 8fef1b8d1fd8..c50177fb469f 100644
> --- a/sound/hda/hdac_i915.c
> +++ b/sound/hda/hdac_i915.c
> @@ -118,6 +118,72 @@ int snd_hdac_get_display_clk(struct hdac_bus *bus)
>  }
>  EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk);
>  
> +/* There is a fixed mapping between audio pin node and display port
> + * on current Intel platforms:
> + * Pin Widget 5 - PORT B (port = 1 in i915 driver)
> + * Pin Widget 6 - PORT C (port = 2 in i915 driver)
> + * Pin Widget 7 - PORT D (port = 3 in i915 driver)
> + */
> +static int pin2port(hda_nid_t pin_nid)
> +{
> +     return pin_nid - 4;
> +}
> +
> +/**
> + * snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate
> + * @bus: HDA core bus
> + * @nid: the pin widget NID
> + * @rate: the sample rate to set
> + *
> + * This function is supposed to be used only by a HD-audio controller
> + * driver that needs the interaction with i915 graphics.
> + *
> + * This function sets N/CTS value based on the given sample rate.
> + * Returns zero for success, or a negative error code.
> + */
> +int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate)
> +{
> +     struct i915_audio_component *acomp = bus->audio_component;
> +
> +     if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate)
> +             return -ENODEV;
> +     return acomp->ops->sync_audio_rate(acomp->dev, pin2port(nid), rate);
> +}
> +EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> +
> +/**
> + * snd_hdac_acomp_get_eld - Get the audio state and ELD via component
> + * @bus: HDA core bus
> + * @nid: the pin widget NID
> + * @audio_enabled: the pointer to store the current audio state
> + * @buffer: the buffer pointer to store ELD bytes
> + * @max_bytes: the max bytes to be stored on @buffer
> + *
> + * This function is supposed to be used only by a HD-audio controller
> + * driver that needs the interaction with i915 graphics.
> + *
> + * This function queries the current state of the audio on the given
> + * digital port and fetches the ELD bytes onto the given buffer.
> + * It returns the number of bytes for the total ELD data, zero for
> + * invalid ELD, or a negative error code.
> + *
> + * The return size is the total bytes required for the whole ELD bytes,
> + * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> + * that only a part of ELD bytes have been fetched.
> + */
> +int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
> +                        bool *audio_enabled, char *buffer, int max_bytes)
> +{
> +     struct i915_audio_component *acomp = bus->audio_component;
> +
> +     if (!acomp || !acomp->ops || !acomp->ops->get_eld)
> +             return -ENODEV;
> +
> +     return acomp->ops->get_eld(acomp->dev, pin2port(nid), audio_enabled,
> +                                buffer, max_bytes);
> +}
> +EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> +
>  static int hdac_component_master_bind(struct device *dev)
>  {
>       struct i915_audio_component *acomp = hdac_acomp;
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> index 61f004a73590..1ef0c6959e75 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -1438,17 +1438,6 @@ static void intel_not_share_assigned_cvt(struct 
> hda_codec *codec,
>       }
>  }
>  
> -/* There is a fixed mapping between audio pin node and display port
> - * on current Intel platforms:
> - * Pin Widget 5 - PORT B (port = 1 in i915 driver)
> - * Pin Widget 6 - PORT C (port = 2 in i915 driver)
> - * Pin Widget 7 - PORT D (port = 3 in i915 driver)
> - */
> -static int intel_pin2port(hda_nid_t pin_nid)
> -{
> -     return pin_nid - 4;
> -}
> -
>  /*
>   * HDA PCM callbacks
>   */
> @@ -1660,38 +1649,36 @@ static bool hdmi_present_sense_via_verbs(struct 
> hdmi_spec_per_pin *per_pin,
>  static void sync_eld_via_acomp(struct hda_codec *codec,
>                              struct hdmi_spec_per_pin *per_pin)
>  {
> -     struct i915_audio_component *acomp = codec->bus->core.audio_component;
>       struct hdmi_spec *spec = codec->spec;
>       struct hdmi_eld *eld = &spec->temp_eld;
>       int size;
>  
> -     if (acomp && acomp->ops && acomp->ops->get_eld) {
> -             mutex_lock(&per_pin->lock);
> -             size = acomp->ops->get_eld(acomp->dev,
> -                                        intel_pin2port(per_pin->pin_nid),
> -                                        &eld->monitor_present,
> -                                        eld->eld_buffer,
> -                                        ELD_MAX_SIZE);
> -             if (size > 0) {
> -                     size = min(size, ELD_MAX_SIZE);
> -                     if (snd_hdmi_parse_eld(codec, &eld->info,
> -                                            eld->eld_buffer, size) < 0)
> -                             size = -EINVAL;
> -             }
> -
> -             if (size > 0) {
> -                     eld->eld_valid = true;
> -                     eld->eld_size = size;
> -             } else {
> -                     eld->eld_valid = false;
> -                     eld->eld_size = 0;
> -             }
> -
> -             update_eld(codec, per_pin, eld);
> -             snd_jack_report(per_pin->acomp_jack,
> -                             eld->monitor_present ? SND_JACK_AVOUT : 0);
> -             mutex_unlock(&per_pin->lock);
> +     mutex_lock(&per_pin->lock);
> +     size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid,
> +                                   &eld->monitor_present, eld->eld_buffer,
> +                                   ELD_MAX_SIZE);
> +     if (size < 0)
> +             goto unlock;
> +     if (size > 0) {
> +             size = min(size, ELD_MAX_SIZE);
> +             if (snd_hdmi_parse_eld(codec, &eld->info,
> +                                    eld->eld_buffer, size) < 0)
> +                     size = -EINVAL;
> +     }
> +
> +     if (size > 0) {
> +             eld->eld_valid = true;
> +             eld->eld_size = size;
> +     } else {
> +             eld->eld_valid = false;
> +             eld->eld_size = 0;
>       }
> +
> +     update_eld(codec, per_pin, eld);
> +     snd_jack_report(per_pin->acomp_jack,
> +                     eld->monitor_present ? SND_JACK_AVOUT : 0);
> + unlock:
> +     mutex_unlock(&per_pin->lock);
>  }
>  
>  static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
> @@ -1857,7 +1844,6 @@ static int generic_hdmi_playback_pcm_prepare(struct 
> hda_pcm_stream *hinfo,
>       struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
>       hda_nid_t pin_nid = per_pin->pin_nid;
>       struct snd_pcm_runtime *runtime = substream->runtime;
> -     struct i915_audio_component *acomp = codec->bus->core.audio_component;
>       bool non_pcm;
>       int pinctl;
>  
> @@ -1876,10 +1862,7 @@ static int generic_hdmi_playback_pcm_prepare(struct 
> hda_pcm_stream *hinfo,
>  
>       /* Call sync_audio_rate to set the N/CTS/M manually if necessary */
>       /* Todo: add DP1.2 MST audio support later */
> -     if (acomp && acomp->ops && acomp->ops->sync_audio_rate)
> -             acomp->ops->sync_audio_rate(acomp->dev,
> -                             intel_pin2port(pin_nid),
> -                             runtime->rate);
> +     snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate);
>  
>       non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
>       mutex_lock(&per_pin->lock);
> -- 
> 2.6.3
> 
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to