summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-12-01 06:39:38 -0500
committerTakashi Iwai <tiwai@suse.de>2015-12-10 08:41:07 -0500
commite2dc7d7d8ed3019f72855af1c3dcda3fb456b488 (patch)
tree5cccbc6953734de5a81082e6adbd8ebac4a4ca4b
parent788d441a164caea0a5d82e1d5bcd161820bfe62a (diff)
ALSA: hda - Move audio component accesses to hdac_i915.c
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. Reviewed-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/hda_i915.h14
-rw-r--r--sound/hda/hdac_i915.c66
-rw-r--r--sound/pci/hda/patch_hdmi.c69
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 @@
10int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); 10int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
11int snd_hdac_display_power(struct hdac_bus *bus, bool enable); 11int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
12int snd_hdac_get_display_clk(struct hdac_bus *bus); 12int snd_hdac_get_display_clk(struct hdac_bus *bus);
13int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate);
14int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
15 bool *audio_enabled, char *buffer, int max_bytes);
13int snd_hdac_i915_init(struct hdac_bus *bus); 16int snd_hdac_i915_init(struct hdac_bus *bus);
14int snd_hdac_i915_exit(struct hdac_bus *bus); 17int snd_hdac_i915_exit(struct hdac_bus *bus);
15int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *); 18int 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)
26{ 29{
27 return 0; 30 return 0;
28} 31}
32static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid,
33 int rate)
34{
35 return 0;
36}
37static inline int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
38 bool *audio_enabled, char *buffer,
39 int max_bytes)
40{
41 return -ENODEV;
42}
29static inline int snd_hdac_i915_init(struct hdac_bus *bus) 43static inline int snd_hdac_i915_init(struct hdac_bus *bus)
30{ 44{
31 return -ENODEV; 45 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)
118} 118}
119EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk); 119EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk);
120 120
121/* There is a fixed mapping between audio pin node and display port
122 * on current Intel platforms:
123 * Pin Widget 5 - PORT B (port = 1 in i915 driver)
124 * Pin Widget 6 - PORT C (port = 2 in i915 driver)
125 * Pin Widget 7 - PORT D (port = 3 in i915 driver)
126 */
127static int pin2port(hda_nid_t pin_nid)
128{
129 return pin_nid - 4;
130}
131
132/**
133 * snd_hdac_sync_audio_rate - Set N/CTS based on the sample rate
134 * @bus: HDA core bus
135 * @nid: the pin widget NID
136 * @rate: the sample rate to set
137 *
138 * This function is supposed to be used only by a HD-audio controller
139 * driver that needs the interaction with i915 graphics.
140 *
141 * This function sets N/CTS value based on the given sample rate.
142 * Returns zero for success, or a negative error code.
143 */
144int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate)
145{
146 struct i915_audio_component *acomp = bus->audio_component;
147
148 if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate)
149 return -ENODEV;
150 return acomp->ops->sync_audio_rate(acomp->dev, pin2port(nid), rate);
151}
152EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
153
154/**
155 * snd_hdac_acomp_get_eld - Get the audio state and ELD via component
156 * @bus: HDA core bus
157 * @nid: the pin widget NID
158 * @audio_enabled: the pointer to store the current audio state
159 * @buffer: the buffer pointer to store ELD bytes
160 * @max_bytes: the max bytes to be stored on @buffer
161 *
162 * This function is supposed to be used only by a HD-audio controller
163 * driver that needs the interaction with i915 graphics.
164 *
165 * This function queries the current state of the audio on the given
166 * digital port and fetches the ELD bytes onto the given buffer.
167 * It returns the number of bytes for the total ELD data, zero for
168 * invalid ELD, or a negative error code.
169 *
170 * The return size is the total bytes required for the whole ELD bytes,
171 * thus it may be over @max_bytes. If it's over @max_bytes, it implies
172 * that only a part of ELD bytes have been fetched.
173 */
174int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid,
175 bool *audio_enabled, char *buffer, int max_bytes)
176{
177 struct i915_audio_component *acomp = bus->audio_component;
178
179 if (!acomp || !acomp->ops || !acomp->ops->get_eld)
180 return -ENODEV;
181
182 return acomp->ops->get_eld(acomp->dev, pin2port(nid), audio_enabled,
183 buffer, max_bytes);
184}
185EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
186
121static int hdac_component_master_bind(struct device *dev) 187static int hdac_component_master_bind(struct device *dev)
122{ 188{
123 struct i915_audio_component *acomp = hdac_acomp; 189 struct i915_audio_component *acomp = hdac_acomp;
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index e91a3223fe5f..cd9b0ffc91dc 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1443,17 +1443,6 @@ static void intel_not_share_assigned_cvt(struct hda_codec *codec,
1443 } 1443 }
1444} 1444}
1445 1445
1446/* There is a fixed mapping between audio pin node and display port
1447 * on current Intel platforms:
1448 * Pin Widget 5 - PORT B (port = 1 in i915 driver)
1449 * Pin Widget 6 - PORT C (port = 2 in i915 driver)
1450 * Pin Widget 7 - PORT D (port = 3 in i915 driver)
1451 */
1452static int intel_pin2port(hda_nid_t pin_nid)
1453{
1454 return pin_nid - 4;
1455}
1456
1457/* 1446/*
1458 * HDA PCM callbacks 1447 * HDA PCM callbacks
1459 */ 1448 */
@@ -1668,38 +1657,36 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
1668static void sync_eld_via_acomp(struct hda_codec *codec, 1657static void sync_eld_via_acomp(struct hda_codec *codec,
1669 struct hdmi_spec_per_pin *per_pin) 1658 struct hdmi_spec_per_pin *per_pin)
1670{ 1659{
1671 struct i915_audio_component *acomp = codec->bus->core.audio_component;
1672 struct hdmi_spec *spec = codec->spec; 1660 struct hdmi_spec *spec = codec->spec;
1673 struct hdmi_eld *eld = &spec->temp_eld; 1661 struct hdmi_eld *eld = &spec->temp_eld;
1674 int size; 1662 int size;
1675 1663
1676 if (acomp && acomp->ops && acomp->ops->get_eld) { 1664 mutex_lock(&per_pin->lock);
1677 mutex_lock(&per_pin->lock); 1665 size = snd_hdac_acomp_get_eld(&codec->bus->core, per_pin->pin_nid,
1678 size = acomp->ops->get_eld(acomp->dev, 1666 &eld->monitor_present, eld->eld_buffer,
1679 intel_pin2port(per_pin->pin_nid), 1667 ELD_MAX_SIZE);
1680 &eld->monitor_present, 1668 if (size < 0)
1681 eld->eld_buffer, 1669 goto unlock;
1682 ELD_MAX_SIZE); 1670 if (size > 0) {
1683 if (size > 0) { 1671 size = min(size, ELD_MAX_SIZE);
1684 size = min(size, ELD_MAX_SIZE); 1672 if (snd_hdmi_parse_eld(codec, &eld->info,
1685 if (snd_hdmi_parse_eld(codec, &eld->info, 1673 eld->eld_buffer, size) < 0)
1686 eld->eld_buffer, size) < 0) 1674 size = -EINVAL;
1687 size = -EINVAL; 1675 }
1688 } 1676
1689 1677 if (size > 0) {
1690 if (size > 0) { 1678 eld->eld_valid = true;
1691 eld->eld_valid = true; 1679 eld->eld_size = size;
1692 eld->eld_size = size; 1680 } else {
1693 } else { 1681 eld->eld_valid = false;
1694 eld->eld_valid = false; 1682 eld->eld_size = 0;
1695 eld->eld_size = 0;
1696 }
1697
1698 update_eld(codec, per_pin, eld);
1699 snd_jack_report(per_pin->acomp_jack,
1700 eld->monitor_present ? SND_JACK_AVOUT : 0);
1701 mutex_unlock(&per_pin->lock);
1702 } 1683 }
1684
1685 update_eld(codec, per_pin, eld);
1686 snd_jack_report(per_pin->acomp_jack,
1687 eld->monitor_present ? SND_JACK_AVOUT : 0);
1688 unlock:
1689 mutex_unlock(&per_pin->lock);
1703} 1690}
1704 1691
1705static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) 1692static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
@@ -1865,7 +1852,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1865 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 1852 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1866 hda_nid_t pin_nid = per_pin->pin_nid; 1853 hda_nid_t pin_nid = per_pin->pin_nid;
1867 struct snd_pcm_runtime *runtime = substream->runtime; 1854 struct snd_pcm_runtime *runtime = substream->runtime;
1868 struct i915_audio_component *acomp = codec->bus->core.audio_component;
1869 bool non_pcm; 1855 bool non_pcm;
1870 int pinctl; 1856 int pinctl;
1871 1857
@@ -1884,10 +1870,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1884 1870
1885 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */ 1871 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */
1886 /* Todo: add DP1.2 MST audio support later */ 1872 /* Todo: add DP1.2 MST audio support later */
1887 if (acomp && acomp->ops && acomp->ops->sync_audio_rate) 1873 snd_hdac_sync_audio_rate(&codec->bus->core, pin_nid, runtime->rate);
1888 acomp->ops->sync_audio_rate(acomp->dev,
1889 intel_pin2port(pin_nid),
1890 runtime->rate);
1891 1874
1892 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); 1875 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
1893 mutex_lock(&per_pin->lock); 1876 mutex_lock(&per_pin->lock);