[Intel-gfx] [PATCH 4/4] ALSA: hda - Add display audio routing API for haswell
Wang, Xingchao
xingchao.wang at intel.com
Mon Jun 17 14:53:57 CEST 2013
> -----Original Message-----
> From: Takashi Iwai [mailto:tiwai at suse.de]
> Sent: Monday, June 17, 2013 5:04 PM
> To: Wang Xingchao
> Cc: daniel.vetter at ffwll.ch; alsa-devel at alsa-project.org;
> intel-gfx at lists.freedesktop.org; david.henningsson at canonical.com; Wang,
> Xingchao
> Subject: Re: [PATCH 4/4] ALSA: hda - Add display audio routing API for haswell
>
> At Fri, 14 Jun 2013 23:20:29 +0800,
> Wang Xingchao wrote:
> >
> > ALSA side use these apis to know display audio routing map in gfx
> > side. And use the API to disable unused pin's audio output.
>
> Adding more and more such exported functions doesn't look scaling.
> Better to define an ops struct and export it.
Thanks Takashi, under discussion with Daniel in another thread, need improvement to make the API clean.
I will rework the patch when get some agreement.
Thanks
--xingchao
>
>
> Takashi
>
> >
> > Signed-off-by: Wang Xingchao <xingchao.wang at linux.intel.com>
> > ---
> > sound/pci/hda/hda_i915.c | 83
> ++++++++++++++++++++++++++++++++++++++++++++++
> > sound/pci/hda/hda_i915.h | 4 +++
> > sound/pci/hda/patch_hdmi.c | 20 +++++++++--
> > 3 files changed, 104 insertions(+), 3 deletions(-)
> >
> > diff --git a/sound/pci/hda/hda_i915.c b/sound/pci/hda/hda_i915.c index
> > 76c13d5..7ac446f 100644
> > --- a/sound/pci/hda/hda_i915.c
> > +++ b/sound/pci/hda/hda_i915.c
> > @@ -22,9 +22,73 @@
> > #include <drm/i915_powerwell.h>
> > #include "hda_i915.h"
> >
> > +/* Haswell power well */
> > static void (*get_power)(void);
> > static void (*put_power)(void);
> >
> > +/* Haswell audio routing */
> > +static int (*get_using_pipe)(int);
> > +static int (*disable_unused_pipe)(int, int *); static int
> > +(*restore_eld)(void);
> > +
> > +#define i915_pipe_name(p) ((p) + 'A')
> > +
> > +static int busy_pins[3] = {0, 0, 0};
> > +
> > +int hdmi_disable_unused_pipe(int pin_idx, int pipe_idx) {
> > + busy_pins[pin_idx] = 1;
> > + if (disable_unused_pipe)
> > + disable_unused_pipe(pipe_idx, busy_pins);
> > +
> > + return 0;
> > +}
> > +EXPORT_SYMBOL(hdmi_disable_unused_pipe);
> > +
> > +void hdmi_restore_pineld(int pin_idx) {
> > + busy_pins[pin_idx] = 0;
> > + if (restore_eld)
> > + restore_eld();
> > +}
> > +EXPORT_SYMBOL(hdmi_restore_pineld);
> > +
> > +int hdmi_get_using_pipe(int pin_idx)
> > +{
> > + int pipe = -1;
> > +
> > + if (get_using_pipe)
> > + pipe = get_using_pipe(pin_idx);
> > +
> > + if (pipe != -1)
> > + snd_printd("HDMI: pin %d get using pipe %c\n", pin_idx,
> > +i915_pipe_name(pipe));
> > +
> > + return pipe;
> > +}
> > +EXPORT_SYMBOL(hdmi_get_using_pipe);
> > +
> > +static int init_audio_routing(void)
> > +{
> > + get_using_pipe = symbol_request(i915_using_pipe);
> > + if (!get_using_pipe)
> > + return -ENODEV;
> > +
> > + disable_unused_pipe = symbol_request(i915_disable_pipe);
> > + if (!disable_unused_pipe) {
> > + get_using_pipe = NULL;
> > + return -ENODEV;
> > + }
> > +
> > + restore_eld = symbol_request(i915_restore_pineld);
> > + if (!restore_eld) {
> > + restore_eld = NULL;
> > + get_using_pipe = NULL;
> > + return -ENODEV;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > void hda_display_power(bool enable)
> > {
> > if (!get_power || !put_power)
> > @@ -57,6 +121,10 @@ int hda_i915_init(void)
> >
> > snd_printd("HDA driver get symbol successfully from i915 module\n");
> >
> > + err = init_audio_routing();
> > + if (err < 0)
> > + snd_printd("HDA driver get audior routing APIs failed!\n");
> > +
> > return err;
> > }
> >
> > @@ -71,5 +139,20 @@ int hda_i915_exit(void)
> > put_power = NULL;
> > }
> >
> > + if (get_using_pipe) {
> > + symbol_put(get_using_pipe);
> > + get_using_pipe = NULL;
> > + }
> > +
> > + if (disable_unused_pipe) {
> > + symbol_put(disable_unused_pipe);
> > + disable_unused_pipe = NULL;
> > + }
> > +
> > + if (restore_eld) {
> > + symbol_put(restore_eld);
> > + restore_eld = NULL;
> > + }
> > +
> > return 0;
> > }
> > diff --git a/sound/pci/hda/hda_i915.h b/sound/pci/hda/hda_i915.h index
> > 5a63da2..52d6f09 100644
> > --- a/sound/pci/hda/hda_i915.h
> > +++ b/sound/pci/hda/hda_i915.h
> > @@ -32,4 +32,8 @@ static inline int hda_i915_exit(void) } #endif
> >
> > +extern int hdmi_get_using_pipe(int pin_idx); extern int
> > +hdmi_disable_unused_pipe(int pin_idx, int pipe_idx); extern void
> > +hdmi_restore_pineld(int pin_idx);
> > +
> > #endif
> > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > index d766f40..2a1e977 100644
> > --- a/sound/pci/hda/patch_hdmi.c
> > +++ b/sound/pci/hda/patch_hdmi.c
> > @@ -39,6 +39,7 @@
> > #include "hda_codec.h"
> > #include "hda_local.h"
> > #include "hda_jack.h"
> > +#include "hda_i915.h"
> >
> > static bool static_hdmi_pcm;
> > module_param(static_hdmi_pcm, bool, 0644); @@ -1131,6 +1132,7 @@
> > static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
> > struct hdmi_spec_per_pin *per_pin;
> > struct hdmi_eld *eld;
> > struct hdmi_spec_per_cvt *per_cvt = NULL;
> > + int pipe_idx;
> >
> > /* Validate hinfo */
> > pin_idx = hinfo_to_pin_index(spec, hinfo); @@ -1139,12 +1141,21 @@
> > static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
> > per_pin = get_pin(spec, pin_idx);
> > eld = &per_pin->sink_eld;
> >
> > + if (codec->vendor_id == 0x80862807) {
> > + hsw_verify_cvt_D0(spec, codec);
> > +
> > + pipe_idx = hdmi_get_using_pipe(pin_idx);
> > + if (pipe_idx < 0)
> > + snd_printdd("HDMI: Pin %d has no valid pipe in use\n", pin_idx);
> > + else {
> > + hdmi_disable_unused_pipe(pin_idx, pipe_idx);
> > + msleep(10);
> > + }
> > + }
> > +
> > if (!eld->monitor_present || !eld->eld_valid)
> > return -EIO;
> >
> > - if (codec->vendor_id == 0x80862807)
> > - hsw_verify_cvt_D0(spec, codec);
> > -
> > /* Dynamically assign converter to stream */
> > for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
> > per_cvt = get_cvt(spec, cvt_idx);
> > @@ -1514,6 +1525,9 @@ static int hdmi_pcm_close(struct
> hda_pcm_stream *hinfo,
> > snd_hda_spdif_ctls_unassign(codec, pin_idx);
> > per_pin->chmap_set = false;
> > memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
> > +
> > + if (codec->vendor_id == 0x80862807)
> > + hdmi_restore_pineld(pin_idx);
> > }
> >
> > return 0;
> > --
> > 1.8.1.2
> >
More information about the Intel-gfx
mailing list