diff options
author | Cheng-Yi Chiang <cychiang@chromium.org> | 2019-07-17 04:33:23 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-09-09 09:50:03 -0400 |
commit | 6fa5963c37a2e3335eba0b7455e35a01318ebc15 (patch) | |
tree | db022d21562efc12856c2efa7b5a82f3e601560c | |
parent | dfe58f2011595e7512bde9dffbd0abfc3a736ab7 (diff) |
ASoC: hdmi-codec: Add an op to set callback function for plug event
Add an op in hdmi_codec_ops so codec driver can register callback
function to handle plug event.
Driver in DRM can use this callback function to report connector status.
Signed-off-by: Cheng-Yi Chiang <cychiang@chromium.org>
Link: https://lore.kernel.org/r/20190717083327.47646-2-cychiang@chromium.org
Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | include/sound/hdmi-codec.h | 17 | ||||
-rw-r--r-- | sound/soc/codecs/hdmi-codec.c | 46 |
2 files changed, 63 insertions, 0 deletions
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h index 7fea496f1f34..83b17682e01c 100644 --- a/include/sound/hdmi-codec.h +++ b/include/sound/hdmi-codec.h | |||
@@ -47,6 +47,9 @@ struct hdmi_codec_params { | |||
47 | int channels; | 47 | int channels; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | typedef void (*hdmi_codec_plugged_cb)(struct device *dev, | ||
51 | bool plugged); | ||
52 | |||
50 | struct hdmi_codec_pdata; | 53 | struct hdmi_codec_pdata; |
51 | struct hdmi_codec_ops { | 54 | struct hdmi_codec_ops { |
52 | /* | 55 | /* |
@@ -88,6 +91,14 @@ struct hdmi_codec_ops { | |||
88 | */ | 91 | */ |
89 | int (*get_dai_id)(struct snd_soc_component *comment, | 92 | int (*get_dai_id)(struct snd_soc_component *comment, |
90 | struct device_node *endpoint); | 93 | struct device_node *endpoint); |
94 | |||
95 | /* | ||
96 | * Hook callback function to handle connector plug event. | ||
97 | * Optional | ||
98 | */ | ||
99 | int (*hook_plugged_cb)(struct device *dev, void *data, | ||
100 | hdmi_codec_plugged_cb fn, | ||
101 | struct device *codec_dev); | ||
91 | }; | 102 | }; |
92 | 103 | ||
93 | /* HDMI codec initalization data */ | 104 | /* HDMI codec initalization data */ |
@@ -99,6 +110,12 @@ struct hdmi_codec_pdata { | |||
99 | void *data; | 110 | void *data; |
100 | }; | 111 | }; |
101 | 112 | ||
113 | struct snd_soc_component; | ||
114 | struct snd_soc_jack; | ||
115 | |||
116 | int hdmi_codec_set_jack_detect(struct snd_soc_component *component, | ||
117 | struct snd_soc_jack *jack); | ||
118 | |||
102 | #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec" | 119 | #define HDMI_CODEC_DRV_NAME "hdmi-audio-codec" |
103 | 120 | ||
104 | #endif /* __HDMI_CODEC_H__ */ | 121 | #endif /* __HDMI_CODEC_H__ */ |
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 0bf1c8cad108..b5fd8f08726e 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/string.h> | 8 | #include <linux/string.h> |
9 | #include <sound/core.h> | 9 | #include <sound/core.h> |
10 | #include <sound/jack.h> | ||
10 | #include <sound/pcm.h> | 11 | #include <sound/pcm.h> |
11 | #include <sound/pcm_params.h> | 12 | #include <sound/pcm_params.h> |
12 | #include <sound/soc.h> | 13 | #include <sound/soc.h> |
@@ -274,6 +275,8 @@ struct hdmi_codec_priv { | |||
274 | struct snd_pcm_chmap *chmap_info; | 275 | struct snd_pcm_chmap *chmap_info; |
275 | unsigned int chmap_idx; | 276 | unsigned int chmap_idx; |
276 | struct mutex lock; | 277 | struct mutex lock; |
278 | struct snd_soc_jack *jack; | ||
279 | unsigned int jack_status; | ||
277 | }; | 280 | }; |
278 | 281 | ||
279 | static const struct snd_soc_dapm_widget hdmi_widgets[] = { | 282 | static const struct snd_soc_dapm_widget hdmi_widgets[] = { |
@@ -663,6 +666,49 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai) | |||
663 | return 0; | 666 | return 0; |
664 | } | 667 | } |
665 | 668 | ||
669 | static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp, | ||
670 | unsigned int jack_status) | ||
671 | { | ||
672 | if (hcp->jack && jack_status != hcp->jack_status) { | ||
673 | snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT); | ||
674 | hcp->jack_status = jack_status; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | static void plugged_cb(struct device *dev, bool plugged) | ||
679 | { | ||
680 | struct hdmi_codec_priv *hcp = dev_get_drvdata(dev); | ||
681 | |||
682 | if (plugged) | ||
683 | hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT); | ||
684 | else | ||
685 | hdmi_codec_jack_report(hcp, 0); | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * hdmi_codec_set_jack_detect - register HDMI plugged callback | ||
690 | * @component: the hdmi-codec instance | ||
691 | * @jack: ASoC jack to report (dis)connection events on | ||
692 | */ | ||
693 | int hdmi_codec_set_jack_detect(struct snd_soc_component *component, | ||
694 | struct snd_soc_jack *jack) | ||
695 | { | ||
696 | struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); | ||
697 | int ret = -EOPNOTSUPP; | ||
698 | |||
699 | if (hcp->hcd.ops->hook_plugged_cb) { | ||
700 | hcp->jack = jack; | ||
701 | ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent, | ||
702 | hcp->hcd.data, | ||
703 | plugged_cb, | ||
704 | component->dev); | ||
705 | if (ret) | ||
706 | hcp->jack = NULL; | ||
707 | } | ||
708 | return ret; | ||
709 | } | ||
710 | EXPORT_SYMBOL_GPL(hdmi_codec_set_jack_detect); | ||
711 | |||
666 | static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) | 712 | static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) |
667 | { | 713 | { |
668 | struct hdmi_codec_daifmt *cf = dai->playback_dma_data; | 714 | struct hdmi_codec_daifmt *cf = dai->playback_dma_data; |