diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-12-01 06:39:38 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-12-10 08:41:07 -0500 |
commit | e2dc7d7d8ed3019f72855af1c3dcda3fb456b488 (patch) | |
tree | 5cccbc6953734de5a81082e6adbd8ebac4a4ca4b | |
parent | 788d441a164caea0a5d82e1d5bcd161820bfe62a (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.h | 14 | ||||
-rw-r--r-- | sound/hda/hdac_i915.c | 66 | ||||
-rw-r--r-- | 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 @@ | |||
10 | int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); | 10 | int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); |
11 | int snd_hdac_display_power(struct hdac_bus *bus, bool enable); | 11 | int snd_hdac_display_power(struct hdac_bus *bus, bool enable); |
12 | int snd_hdac_get_display_clk(struct hdac_bus *bus); | 12 | int snd_hdac_get_display_clk(struct hdac_bus *bus); |
13 | int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate); | ||
14 | int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, | ||
15 | bool *audio_enabled, char *buffer, int max_bytes); | ||
13 | int snd_hdac_i915_init(struct hdac_bus *bus); | 16 | int snd_hdac_i915_init(struct hdac_bus *bus); |
14 | int snd_hdac_i915_exit(struct hdac_bus *bus); | 17 | int snd_hdac_i915_exit(struct hdac_bus *bus); |
15 | int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *); | 18 | 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) | |||
26 | { | 29 | { |
27 | return 0; | 30 | return 0; |
28 | } | 31 | } |
32 | static inline int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, | ||
33 | int rate) | ||
34 | { | ||
35 | return 0; | ||
36 | } | ||
37 | static 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 | } | ||
29 | static inline int snd_hdac_i915_init(struct hdac_bus *bus) | 43 | static 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 | } |
119 | EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk); | 119 | EXPORT_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 | */ | ||
127 | static 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 | */ | ||
144 | int 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 | } | ||
152 | EXPORT_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 | */ | ||
174 | int 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 | } | ||
185 | EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld); | ||
186 | |||
121 | static int hdac_component_master_bind(struct device *dev) | 187 | static 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 | */ | ||
1452 | static 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, | |||
1668 | static void sync_eld_via_acomp(struct hda_codec *codec, | 1657 | static 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 | ||
1705 | static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | 1692 | static 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); |