mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	drm/vc4: hdmi: switch to using generic HDMI Codec infrastructure
Drop driver-specific implementation and use the generic HDMI Codec framework in order to implement the HDMI audio support. Acked-by: Maxime Ripard <mripard@kernel.org> Tested-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241224-drm-bridge-hdmi-connector-v10-8-dc89577cd438@linaro.org Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
This commit is contained in:
		
							parent
							
								
									4b5a79d7f4
								
							
						
					
					
						commit
						9640f1437a
					
				
					 3 changed files with 20 additions and 57 deletions
				
			
		|  | @ -10,6 +10,7 @@ config DRM_VC4 | ||||||
| 	depends on COMMON_CLK | 	depends on COMMON_CLK | ||||||
| 	depends on PM | 	depends on PM | ||||||
| 	select DRM_CLIENT_SELECTION | 	select DRM_CLIENT_SELECTION | ||||||
|  | 	select DRM_DISPLAY_HDMI_AUDIO_HELPER | ||||||
| 	select DRM_DISPLAY_HDMI_HELPER | 	select DRM_DISPLAY_HDMI_HELPER | ||||||
| 	select DRM_DISPLAY_HDMI_STATE_HELPER | 	select DRM_DISPLAY_HDMI_STATE_HELPER | ||||||
| 	select DRM_DISPLAY_HELPER | 	select DRM_DISPLAY_HELPER | ||||||
|  |  | ||||||
|  | @ -31,6 +31,7 @@ | ||||||
|  * encoder block has CEC support. |  * encoder block has CEC support. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <drm/display/drm_hdmi_audio_helper.h> | ||||||
| #include <drm/display/drm_hdmi_helper.h> | #include <drm/display/drm_hdmi_helper.h> | ||||||
| #include <drm/display/drm_hdmi_state_helper.h> | #include <drm/display/drm_hdmi_state_helper.h> | ||||||
| #include <drm/display/drm_scdc_helper.h> | #include <drm/display/drm_scdc_helper.h> | ||||||
|  | @ -584,6 +585,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs; | static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs; | ||||||
|  | static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs; | ||||||
| 
 | 
 | ||||||
| static int vc4_hdmi_connector_init(struct drm_device *dev, | static int vc4_hdmi_connector_init(struct drm_device *dev, | ||||||
| 				   struct vc4_hdmi *vc4_hdmi) | 				   struct vc4_hdmi *vc4_hdmi) | ||||||
|  | @ -609,6 +611,12 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		return ret; | 		return ret; | ||||||
| 
 | 
 | ||||||
|  | 	ret = drm_connector_hdmi_audio_init(connector, dev->dev, | ||||||
|  | 					    &vc4_hdmi_audio_funcs, | ||||||
|  | 					    8, false, -1); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
| 	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs); | 	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
|  | @ -1921,9 +1929,9 @@ static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi) | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int vc4_hdmi_audio_startup(struct device *dev, void *data) | static int vc4_hdmi_audio_startup(struct drm_connector *connector) | ||||||
| { | { | ||||||
| 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); | 	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); | ||||||
| 	struct drm_device *drm = vc4_hdmi->connector.dev; | 	struct drm_device *drm = vc4_hdmi->connector.dev; | ||||||
| 	unsigned long flags; | 	unsigned long flags; | ||||||
| 	int ret = 0; | 	int ret = 0; | ||||||
|  | @ -1985,9 +1993,9 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi) | ||||||
| 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); | 	spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void vc4_hdmi_audio_shutdown(struct device *dev, void *data) | static void vc4_hdmi_audio_shutdown(struct drm_connector *connector) | ||||||
| { | { | ||||||
| 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); | 	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); | ||||||
| 	struct drm_device *drm = vc4_hdmi->connector.dev; | 	struct drm_device *drm = vc4_hdmi->connector.dev; | ||||||
| 	unsigned long flags; | 	unsigned long flags; | ||||||
| 	int idx; | 	int idx; | ||||||
|  | @ -2057,13 +2065,12 @@ static int sample_rate_to_mai_fmt(int samplerate) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* HDMI audio codec callbacks */ | /* HDMI audio codec callbacks */ | ||||||
| static int vc4_hdmi_audio_prepare(struct device *dev, void *data, | static int vc4_hdmi_audio_prepare(struct drm_connector *connector, | ||||||
| 				  struct hdmi_codec_daifmt *daifmt, | 				  struct hdmi_codec_daifmt *daifmt, | ||||||
| 				  struct hdmi_codec_params *params) | 				  struct hdmi_codec_params *params) | ||||||
| { | { | ||||||
| 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); | 	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); | ||||||
| 	struct drm_device *drm = vc4_hdmi->connector.dev; | 	struct drm_device *drm = vc4_hdmi->connector.dev; | ||||||
| 	struct drm_connector *connector = &vc4_hdmi->connector; |  | ||||||
| 	struct vc4_dev *vc4 = to_vc4_dev(drm); | 	struct vc4_dev *vc4 = to_vc4_dev(drm); | ||||||
| 	unsigned int sample_rate = params->sample_rate; | 	unsigned int sample_rate = params->sample_rate; | ||||||
| 	unsigned int channels = params->channels; | 	unsigned int channels = params->channels; | ||||||
|  | @ -2075,7 +2082,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data, | ||||||
| 	int ret = 0; | 	int ret = 0; | ||||||
| 	int idx; | 	int idx; | ||||||
| 
 | 
 | ||||||
| 	dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__, | 	dev_dbg(&vc4_hdmi->pdev->dev, "%s: %u Hz, %d bit, %d channels\n", __func__, | ||||||
| 		sample_rate, params->sample_width, channels); | 		sample_rate, params->sample_width, channels); | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&vc4_hdmi->mutex); | 	mutex_lock(&vc4_hdmi->mutex); | ||||||
|  | @ -2214,40 +2221,12 @@ static const struct snd_dmaengine_pcm_config pcm_conf = { | ||||||
| 	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, | 	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static int vc4_hdmi_audio_get_eld(struct device *dev, void *data, | static const struct drm_connector_hdmi_audio_funcs vc4_hdmi_audio_funcs = { | ||||||
| 				  uint8_t *buf, size_t len) | 	.startup = vc4_hdmi_audio_startup, | ||||||
| { |  | ||||||
| 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); |  | ||||||
| 	struct drm_connector *connector = &vc4_hdmi->connector; |  | ||||||
| 
 |  | ||||||
| 	mutex_lock(&connector->eld_mutex); |  | ||||||
| 	memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); |  | ||||||
| 	mutex_unlock(&connector->eld_mutex); |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static const struct hdmi_codec_ops vc4_hdmi_codec_ops = { |  | ||||||
| 	.get_eld = vc4_hdmi_audio_get_eld, |  | ||||||
| 	.prepare = vc4_hdmi_audio_prepare, | 	.prepare = vc4_hdmi_audio_prepare, | ||||||
| 	.audio_shutdown = vc4_hdmi_audio_shutdown, | 	.shutdown = vc4_hdmi_audio_shutdown, | ||||||
| 	.audio_startup = vc4_hdmi_audio_startup, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct hdmi_codec_pdata vc4_hdmi_codec_pdata = { |  | ||||||
| 	.ops = &vc4_hdmi_codec_ops, |  | ||||||
| 	.max_i2s_channels = 8, |  | ||||||
| 	.i2s = 1, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static void vc4_hdmi_audio_codec_release(void *ptr) |  | ||||||
| { |  | ||||||
| 	struct vc4_hdmi *vc4_hdmi = ptr; |  | ||||||
| 
 |  | ||||||
| 	platform_device_unregister(vc4_hdmi->audio.codec_pdev); |  | ||||||
| 	vc4_hdmi->audio.codec_pdev = NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) | static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) | ||||||
| { | { | ||||||
| 	const struct vc4_hdmi_register *mai_data = | 	const struct vc4_hdmi_register *mai_data = | ||||||
|  | @ -2255,7 +2234,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) | ||||||
| 	struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link; | 	struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link; | ||||||
| 	struct snd_soc_card *card = &vc4_hdmi->audio.card; | 	struct snd_soc_card *card = &vc4_hdmi->audio.card; | ||||||
| 	struct device *dev = &vc4_hdmi->pdev->dev; | 	struct device *dev = &vc4_hdmi->pdev->dev; | ||||||
| 	struct platform_device *codec_pdev; |  | ||||||
| 	const __be32 *addr; | 	const __be32 *addr; | ||||||
| 	int index, len; | 	int index, len; | ||||||
| 	int ret; | 	int ret; | ||||||
|  | @ -2348,20 +2326,6 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	codec_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, |  | ||||||
| 						   PLATFORM_DEVID_AUTO, |  | ||||||
| 						   &vc4_hdmi_codec_pdata, |  | ||||||
| 						   sizeof(vc4_hdmi_codec_pdata)); |  | ||||||
| 	if (IS_ERR(codec_pdev)) { |  | ||||||
| 		dev_err(dev, "Couldn't register the HDMI codec: %ld\n", PTR_ERR(codec_pdev)); |  | ||||||
| 		return PTR_ERR(codec_pdev); |  | ||||||
| 	} |  | ||||||
| 	vc4_hdmi->audio.codec_pdev = codec_pdev; |  | ||||||
| 
 |  | ||||||
| 	ret = devm_add_action_or_reset(dev, vc4_hdmi_audio_codec_release, vc4_hdmi); |  | ||||||
| 	if (ret) |  | ||||||
| 		return ret; |  | ||||||
| 
 |  | ||||||
| 	dai_link->cpus		= &vc4_hdmi->audio.cpu; | 	dai_link->cpus		= &vc4_hdmi->audio.cpu; | ||||||
| 	dai_link->codecs	= &vc4_hdmi->audio.codec; | 	dai_link->codecs	= &vc4_hdmi->audio.codec; | ||||||
| 	dai_link->platforms	= &vc4_hdmi->audio.platform; | 	dai_link->platforms	= &vc4_hdmi->audio.platform; | ||||||
|  | @ -2374,7 +2338,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) | ||||||
| 	dai_link->stream_name = "MAI PCM"; | 	dai_link->stream_name = "MAI PCM"; | ||||||
| 	dai_link->codecs->dai_name = "i2s-hifi"; | 	dai_link->codecs->dai_name = "i2s-hifi"; | ||||||
| 	dai_link->cpus->dai_name = dev_name(dev); | 	dai_link->cpus->dai_name = dev_name(dev); | ||||||
| 	dai_link->codecs->name = dev_name(&codec_pdev->dev); | 	dai_link->codecs->name = dev_name(&vc4_hdmi->connector.hdmi_audio.codec_pdev->dev); | ||||||
| 	dai_link->platforms->name = dev_name(dev); | 	dai_link->platforms->name = dev_name(dev); | ||||||
| 
 | 
 | ||||||
| 	card->dai_link = dai_link; | 	card->dai_link = dai_link; | ||||||
|  |  | ||||||
|  | @ -104,8 +104,6 @@ struct vc4_hdmi_audio { | ||||||
| 	struct snd_soc_dai_link_component codec; | 	struct snd_soc_dai_link_component codec; | ||||||
| 	struct snd_soc_dai_link_component platform; | 	struct snd_soc_dai_link_component platform; | ||||||
| 	struct snd_dmaengine_dai_dma_data dma_data; | 	struct snd_dmaengine_dai_dma_data dma_data; | ||||||
| 	struct hdmi_audio_infoframe infoframe; |  | ||||||
| 	struct platform_device *codec_pdev; |  | ||||||
| 	bool streaming; | 	bool streaming; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Dmitry Baryshkov
						Dmitry Baryshkov