Skip to content

Commit ea54cfa

Browse files
committed
drm/msm/hdmi: use DRM HDMI Audio framework
In order to simplify the driver even further and to remove the boilerplate code, rewrite the audio interface to use the DRM HDMI Audio framework. Audio InfoFames are controlled centrally via the DRM HDMI framework. Correct InfoFrame data is programmed at the atomic_pre_enable() time (if it was set before, drm_atomic_helper_connector_hdmi_update_infoframes() takes care of writing all InfoFrames, including the Audio one.) or during msm_hdmi_bridge_audio_prepare() when the new stream is started. All audio data frame management is deferred to msm_hdmi_bridge_audio_prepare() and msm_hdmi_bridge_audio_shutdown(). Reviewed-by: Maxime Ripard <[email protected]> Reviewed-by: Abhinav Kumar <[email protected]> Signed-off-by: Dmitry Baryshkov <[email protected]> Patchwork: https://patchwork.freedesktop.org/patch/639663/ Link: https://lore.kernel.org/r/[email protected]
1 parent d7d57ec commit ea54cfa

File tree

4 files changed

+71
-111
lines changed

4 files changed

+71
-111
lines changed

drivers/gpu/drm/msm/hdmi/hdmi.c

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <drm/drm_of.h>
1515
#include <drm/display/drm_hdmi_state_helper.h>
1616

17-
#include <sound/hdmi-codec.h>
1817
#include "hdmi.h"
1918

2019
void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
@@ -245,87 +244,6 @@ static const struct hdmi_platform_config hdmi_tx_8974_config = {
245244
.hpd_freq = hpd_clk_freq_8x74,
246245
};
247246

248-
/*
249-
* HDMI audio codec callbacks
250-
*/
251-
static int msm_hdmi_audio_hw_params(struct device *dev, void *data,
252-
struct hdmi_codec_daifmt *daifmt,
253-
struct hdmi_codec_params *params)
254-
{
255-
struct hdmi *hdmi = dev_get_drvdata(dev);
256-
unsigned int rate;
257-
int ret;
258-
259-
DRM_DEV_DEBUG(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate,
260-
params->sample_width, params->cea.channels);
261-
262-
switch (params->sample_rate) {
263-
case 32000:
264-
rate = HDMI_SAMPLE_RATE_32KHZ;
265-
break;
266-
case 44100:
267-
rate = HDMI_SAMPLE_RATE_44_1KHZ;
268-
break;
269-
case 48000:
270-
rate = HDMI_SAMPLE_RATE_48KHZ;
271-
break;
272-
case 88200:
273-
rate = HDMI_SAMPLE_RATE_88_2KHZ;
274-
break;
275-
case 96000:
276-
rate = HDMI_SAMPLE_RATE_96KHZ;
277-
break;
278-
case 176400:
279-
rate = HDMI_SAMPLE_RATE_176_4KHZ;
280-
break;
281-
case 192000:
282-
rate = HDMI_SAMPLE_RATE_192KHZ;
283-
break;
284-
default:
285-
DRM_DEV_ERROR(dev, "rate[%d] not supported!\n",
286-
params->sample_rate);
287-
return -EINVAL;
288-
}
289-
290-
ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(hdmi->connector,
291-
&params->cea);
292-
if (ret)
293-
return ret;
294-
295-
msm_hdmi_audio_info_setup(hdmi, rate, params->cea.channels);
296-
297-
return 0;
298-
}
299-
300-
static void msm_hdmi_audio_shutdown(struct device *dev, void *data)
301-
{
302-
struct hdmi *hdmi = dev_get_drvdata(dev);
303-
304-
drm_atomic_helper_connector_hdmi_clear_audio_infoframe(hdmi->connector);
305-
msm_hdmi_audio_disable(hdmi);
306-
}
307-
308-
static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = {
309-
.hw_params = msm_hdmi_audio_hw_params,
310-
.audio_shutdown = msm_hdmi_audio_shutdown,
311-
};
312-
313-
static struct hdmi_codec_pdata codec_data = {
314-
.ops = &msm_hdmi_audio_codec_ops,
315-
.max_i2s_channels = 8,
316-
.i2s = 1,
317-
};
318-
319-
static int msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev)
320-
{
321-
hdmi->audio_pdev = platform_device_register_data(dev,
322-
HDMI_CODEC_DRV_NAME,
323-
PLATFORM_DEVID_AUTO,
324-
&codec_data,
325-
sizeof(codec_data));
326-
return PTR_ERR_OR_ZERO(hdmi->audio_pdev);
327-
}
328-
329247
static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
330248
{
331249
struct msm_drm_private *priv = dev_get_drvdata(master);
@@ -337,12 +255,6 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
337255
return err;
338256
priv->hdmi = hdmi;
339257

340-
err = msm_hdmi_register_audio_driver(hdmi, dev);
341-
if (err) {
342-
DRM_ERROR("Failed to attach an audio codec %d\n", err);
343-
hdmi->audio_pdev = NULL;
344-
}
345-
346258
return 0;
347259
}
348260

@@ -352,9 +264,6 @@ static void msm_hdmi_unbind(struct device *dev, struct device *master,
352264
struct msm_drm_private *priv = dev_get_drvdata(master);
353265

354266
if (priv->hdmi) {
355-
if (priv->hdmi->audio_pdev)
356-
platform_device_unregister(priv->hdmi->audio_pdev);
357-
358267
if (priv->hdmi->bridge)
359268
msm_hdmi_hpd_disable(priv->hdmi);
360269

drivers/gpu/drm/msm/hdmi/hdmi.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ struct hdmi_hdcp_ctrl;
3333
struct hdmi {
3434
struct drm_device *dev;
3535
struct platform_device *pdev;
36-
struct platform_device *audio_pdev;
3736

3837
const struct hdmi_platform_config *config;
3938

@@ -205,17 +204,16 @@ static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev)
205204
/*
206205
* audio:
207206
*/
208-
#define HDMI_SAMPLE_RATE_32KHZ 0
209-
#define HDMI_SAMPLE_RATE_44_1KHZ 1
210-
#define HDMI_SAMPLE_RATE_48KHZ 2
211-
#define HDMI_SAMPLE_RATE_88_2KHZ 3
212-
#define HDMI_SAMPLE_RATE_96KHZ 4
213-
#define HDMI_SAMPLE_RATE_176_4KHZ 5
214-
#define HDMI_SAMPLE_RATE_192KHZ 6
207+
struct hdmi_codec_daifmt;
208+
struct hdmi_codec_params;
215209

216210
int msm_hdmi_audio_update(struct hdmi *hdmi);
217-
int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels);
218-
int msm_hdmi_audio_disable(struct hdmi *hdmi);
211+
int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
212+
struct drm_bridge *bridge,
213+
struct hdmi_codec_daifmt *daifmt,
214+
struct hdmi_codec_params *params);
215+
void msm_hdmi_bridge_audio_shutdown(struct drm_connector *connector,
216+
struct drm_bridge *bridge);
219217

220218
/*
221219
* hdmi bridge:

drivers/gpu/drm/msm/hdmi/hdmi_audio.c

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
* Author: Rob Clark <[email protected]>
55
*/
66

7+
#include <drm/display/drm_hdmi_state_helper.h>
8+
79
#include <linux/hdmi.h>
10+
11+
#include <sound/hdmi-codec.h>
12+
813
#include "hdmi.h"
914

1015
/* Supported HDMI Audio sample rates */
@@ -192,29 +197,72 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
192197
return 0;
193198
}
194199

195-
int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels)
200+
int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
201+
struct drm_bridge *bridge,
202+
struct hdmi_codec_daifmt *daifmt,
203+
struct hdmi_codec_params *params)
196204
{
197-
if (!hdmi)
198-
return -ENXIO;
199-
200-
if ((rate < 0) || (rate >= MSM_HDMI_SAMPLE_RATE_MAX))
205+
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
206+
struct hdmi *hdmi = hdmi_bridge->hdmi;
207+
unsigned int rate;
208+
int ret;
209+
210+
drm_dbg_driver(bridge->dev, "%u Hz, %d bit, %d channels\n",
211+
params->sample_rate,
212+
params->sample_width,
213+
params->cea.channels);
214+
215+
switch (params->sample_rate) {
216+
case 32000:
217+
rate = MSM_HDMI_SAMPLE_RATE_32KHZ;
218+
break;
219+
case 44100:
220+
rate = MSM_HDMI_SAMPLE_RATE_44_1KHZ;
221+
break;
222+
case 48000:
223+
rate = MSM_HDMI_SAMPLE_RATE_48KHZ;
224+
break;
225+
case 88200:
226+
rate = MSM_HDMI_SAMPLE_RATE_88_2KHZ;
227+
break;
228+
case 96000:
229+
rate = MSM_HDMI_SAMPLE_RATE_96KHZ;
230+
break;
231+
case 176400:
232+
rate = MSM_HDMI_SAMPLE_RATE_176_4KHZ;
233+
break;
234+
case 192000:
235+
rate = MSM_HDMI_SAMPLE_RATE_192KHZ;
236+
break;
237+
default:
238+
drm_err(bridge->dev, "rate[%d] not supported!\n",
239+
params->sample_rate);
201240
return -EINVAL;
241+
}
242+
243+
ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
244+
&params->cea);
245+
if (ret)
246+
return ret;
202247

203248
hdmi->audio.rate = rate;
204-
hdmi->audio.channels = channels;
249+
hdmi->audio.channels = params->cea.channels;
205250
hdmi->audio.enabled = true;
206251

207252
return msm_hdmi_audio_update(hdmi);
208253
}
209254

210-
int msm_hdmi_audio_disable(struct hdmi *hdmi)
255+
void msm_hdmi_bridge_audio_shutdown(struct drm_connector *connector,
256+
struct drm_bridge *bridge)
211257
{
212-
if (!hdmi)
213-
return -ENXIO;
258+
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
259+
struct hdmi *hdmi = hdmi_bridge->hdmi;
260+
261+
drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
214262

215263
hdmi->audio.rate = 0;
216264
hdmi->audio.channels = 2;
217265
hdmi->audio.enabled = false;
218266

219-
return msm_hdmi_audio_update(hdmi);
267+
msm_hdmi_audio_update(hdmi);
220268
}

drivers/gpu/drm/msm/hdmi/hdmi_bridge.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,8 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
477477
.hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid,
478478
.hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe,
479479
.hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe,
480+
.hdmi_audio_prepare = msm_hdmi_bridge_audio_prepare,
481+
.hdmi_audio_shutdown = msm_hdmi_bridge_audio_shutdown,
480482
};
481483

482484
static void
@@ -514,6 +516,9 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi)
514516
DRM_BRIDGE_OP_DETECT |
515517
DRM_BRIDGE_OP_HDMI |
516518
DRM_BRIDGE_OP_EDID;
519+
bridge->hdmi_audio_max_i2s_playback_channels = 8;
520+
bridge->hdmi_audio_dev = &hdmi->pdev->dev;
521+
bridge->hdmi_audio_dai_port = -1;
517522

518523
ret = devm_drm_bridge_add(hdmi->dev->dev, bridge);
519524
if (ret)

0 commit comments

Comments
 (0)