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 <tiwai@xxxxxxx> Reviewed-by: Vinod Koul <vinod.koul@xxxxxxxxx> -- ~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 Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx