[PATCH 4/4] ALSA: hda - Add display audio routing API for haswell

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux