> -----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 > >