Unverified Commit 6fa5963c authored by Cheng-Yi Chiang's avatar Cheng-Yi Chiang Committed by Mark Brown
Browse files

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: default avatarCheng-Yi Chiang <cychiang@chromium.org>
Link: https://lore.kernel.org/r/20190717083327.47646-2-cychiang@chromium.org


Reviewed-by: default avatarTzung-Bi Shih <tzungbi@google.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent dfe58f20
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ struct hdmi_codec_params {
	int channels;
};

typedef void (*hdmi_codec_plugged_cb)(struct device *dev,
				      bool plugged);

struct hdmi_codec_pdata;
struct hdmi_codec_ops {
	/*
@@ -88,6 +91,14 @@ struct hdmi_codec_ops {
	 */
	int (*get_dai_id)(struct snd_soc_component *comment,
			  struct device_node *endpoint);

	/*
	 * Hook callback function to handle connector plug event.
	 * Optional
	 */
	int (*hook_plugged_cb)(struct device *dev, void *data,
			       hdmi_codec_plugged_cb fn,
			       struct device *codec_dev);
};

/* HDMI codec initalization data */
@@ -99,6 +110,12 @@ struct hdmi_codec_pdata {
	void *data;
};

struct snd_soc_component;
struct snd_soc_jack;

int hdmi_codec_set_jack_detect(struct snd_soc_component *component,
			       struct snd_soc_jack *jack);

#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"

#endif /* __HDMI_CODEC_H__ */
+46 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -274,6 +275,8 @@ struct hdmi_codec_priv {
	struct snd_pcm_chmap *chmap_info;
	unsigned int chmap_idx;
	struct mutex lock;
	struct snd_soc_jack *jack;
	unsigned int jack_status;
};

static const struct snd_soc_dapm_widget hdmi_widgets[] = {
@@ -663,6 +666,49 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai)
	return 0;
}

static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
				   unsigned int jack_status)
{
	if (hcp->jack && jack_status != hcp->jack_status) {
		snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
		hcp->jack_status = jack_status;
	}
}

static void plugged_cb(struct device *dev, bool plugged)
{
	struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);

	if (plugged)
		hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
	else
		hdmi_codec_jack_report(hcp, 0);
}

/**
 * hdmi_codec_set_jack_detect - register HDMI plugged callback
 * @component: the hdmi-codec instance
 * @jack: ASoC jack to report (dis)connection events on
 */
int hdmi_codec_set_jack_detect(struct snd_soc_component *component,
			       struct snd_soc_jack *jack)
{
	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
	int ret = -EOPNOTSUPP;

	if (hcp->hcd.ops->hook_plugged_cb) {
		hcp->jack = jack;
		ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
						    hcp->hcd.data,
						    plugged_cb,
						    component->dev);
		if (ret)
			hcp->jack = NULL;
	}
	return ret;
}
EXPORT_SYMBOL_GPL(hdmi_codec_set_jack_detect);

static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
{
	struct hdmi_codec_daifmt *cf = dai->playback_dma_data;