RE: [EXT] Re: [PATCH v1 5/5] drm: bridge: dw_hdmi: Audio: Add General Parallel Audio (GPA) driver
From: Sandor Yu
Date: Thu Apr 07 2022 - 04:32:00 EST
Hi,
> -----Original Message-----
> From: Neil Armstrong <narmstrong@xxxxxxxxxxxx>
> Sent: 2022年4月6日 17:28
> To: Sandor Yu <sandor.yu@xxxxxxx>; dri-devel@xxxxxxxxxxxxxxxxxxxxx;
> linux-kernel@xxxxxxxxxxxxxxx; andrzej.hajda@xxxxxxxxx;
> robert.foss@xxxxxxxxxx; Laurent.pinchart@xxxxxxxxxxxxxxxx;
> jonas@xxxxxxxxx; jernej.skrabec@xxxxxxxxx
> Cc: S.J. Wang <shengjiu.wang@xxxxxxx>; cai.huoqing@xxxxxxxxx;
> maxime@xxxxxxxxxx; harry.wentland@xxxxxxx; hverkuil-cisco@xxxxxxxxx;
> amuel@xxxxxxxxxxxx
> Subject: [EXT] Re: [PATCH v1 5/5] drm: bridge: dw_hdmi: Audio: Add General
> Parallel Audio (GPA) driver
>
> Caution: EXT Email
>
> Hi,
>
> On 06/04/2022 10:48, Sandor.yu@xxxxxxx wrote:
> > From: Sandor Yu <Sandor.yu@xxxxxxx>
> >
> > General Parallel Audio (GPA) interface is one of the supported audio
> > interface for synopsys HDMI module, which has verified for i.MX8MP
> > platform.
> > This is initial version for GPA.
> >
> > Signed-off-by: Shengjiu Wang <shengjiu.wang@xxxxxxx>
> > Signed-off-by: Sandor Yu <Sandor.yu@xxxxxxx>
> > ---
> > drivers/gpu/drm/bridge/synopsys/Kconfig | 11 +
> > drivers/gpu/drm/bridge/synopsys/Makefile | 1 +
> > .../drm/bridge/synopsys/dw-hdmi-gp-audio.c | 199
> ++++++++++++++++++
> > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 128 ++++++++++-
> > drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 13 +-
> > include/drm/bridge/dw_hdmi.h | 5 +
> > 6 files changed, 354 insertions(+), 3 deletions(-)
> > create mode 100644
> > drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
> > b/drivers/gpu/drm/bridge/synopsys/Kconfig
> > index 21a1be3ced0f..e398b58c996d 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> > +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> > @@ -25,6 +25,17 @@ config DRM_DW_HDMI_I2S_AUDIO
> > Support the I2S Audio interface which is part of the Synopsys
> > Designware HDMI block.
> >
> > +config DRM_DW_HDMI_GP_AUDIO
> > + tristate "Synopsys Designware GP Audio interface"
> > + depends on DRM_DW_HDMI && SND
> > + select SND_PCM
> > + select SND_PCM_ELD
> > + select SND_PCM_IEC958
> > + help
> > + Support the GP Audio interface which is part of the Synopsys
> > + Designware HDMI block. This is used in conjunction with
> > + the i.MX865 HDMI driver.
>
> What does that mean ? it can only be used with i.MX865 HDMI driver ?
> If not, remove reference to i.MX865 HDMI driver.
>
GP audio driver could be used for different SOCs, i.MX865 specific description will be removed.
> > +
> > config DRM_DW_HDMI_CEC
> > tristate "Synopsis Designware CEC interface"
> > depends on DRM_DW_HDMI
> > diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
> > b/drivers/gpu/drm/bridge/synopsys/Makefile
> > index 91d746ad5de1..ce715562e9e5 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> > +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> > @@ -1,6 +1,7 @@
> > # SPDX-License-Identifier: GPL-2.0-only
> > obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> > obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> > +obj-$(CONFIG_DRM_DW_HDMI_GP_AUDIO) += dw-hdmi-gp-audio.o
> > obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> > obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c
> > new file mode 100644
> > index 000000000000..10a957c85a83
> > --- /dev/null
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-gp-audio.c
> > @@ -0,0 +1,199 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * dw-hdmi-gp-audio.c
> > + *
> > + * Copyright 2020-2022 NXP
> > + */
> > +#include <linux/io.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/module.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/dmaengine.h>
> > +#include <linux/dma-mapping.h>
> > +#include <drm/bridge/dw_hdmi.h>
> > +#include <drm/drm_edid.h>
> > +#include <drm/drm_connector.h>
> > +
> > +#include <sound/hdmi-codec.h>
> > +#include <sound/asoundef.h>
> > +#include <sound/core.h>
> > +#include <sound/initval.h>
> > +#include <sound/pcm.h>
> > +#include <sound/pcm_drm_eld.h>
> > +#include <sound/pcm_iec958.h>
> > +#include <sound/dmaengine_pcm.h>
> > +
> > +#include "dw-hdmi-audio.h"
> > +
> > +#define DRIVER_NAME "dw-hdmi-gp-audio"
> > +#define DRV_NAME "hdmi-gp-audio"
> > +
> > +struct snd_dw_hdmi {
> > + struct dw_hdmi_audio_data data;
> > + struct platform_device *audio_pdev;
> > + unsigned int pos;
> > +};
> > +
> > +struct dw_hdmi_channel_conf {
> > + u8 conf1;
> > + u8 ca;
> > +};
> > +
> > +/*
> > + * The default mapping of ALSA channels to HDMI channels and speaker
> > + * allocation bits. Note that we can't do channel remapping here -
> > + * channels must be in the same order.
> > + *
> > + * Mappings for alsa-lib pcm/surround*.conf files:
> > + *
> > + * Front Sur4.0 Sur4.1 Sur5.0 Sur5.1 Sur7.1
> > + * Channels 2 4 6 6 6 8
> > + *
> > + * Our mapping from ALSA channel to CEA686D speaker name and HDMI
> channel:
> > + *
> > + * Number of ALSA channels
> > + * ALSA Channel 2 3 4 5 6 7
> 8
> > + * 0 FL:0 = = = = =
> =
> > + * 1 FR:1 = = = = =
> =
> > + * 2 FC:3 RL:4 LFE:2 = = =
> > + * 3 RR:5 RL:4 FC:3 = =
> > + * 4 RR:5 RL:4 =
> =
> > + * 5 RR:5 =
> =
> > + * 6 RC:6
> =
> > + * 7 RLC/FRC
> RLC/FRC
> > + */
> > +static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] = {
> > + { 0x03, 0x00 }, /* FL,FR */
> > + { 0x0b, 0x02 }, /* FL,FR,FC */
> > + { 0x33, 0x08 }, /* FL,FR,RL,RR */
> > + { 0x37, 0x09 }, /* FL,FR,LFE,RL,RR */
> > + { 0x3f, 0x0b }, /* FL,FR,LFE,FC,RL,RR */
> > + { 0x7f, 0x0f }, /* FL,FR,LFE,FC,RL,RR,RC */
> > + { 0xff, 0x13 }, /* FL,FR,LFE,FC,RL,RR,[FR]RC,[FR]LC */ };
> > +
> > +static int audio_hw_params(struct device *dev, void *data,
> > + struct hdmi_codec_daifmt *daifmt,
> > + struct hdmi_codec_params *params) {
> > + struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
> > + int ret = 0;
> > + u8 ca;
> > +
> > + dw_hdmi_set_sample_rate(dw->data.hdmi, params->sample_rate);
> > +
> > + ca = default_hdmi_channel_config[params->channels - 2].ca;
> > +
> > + dw_hdmi_set_channel_count(dw->data.hdmi, params->channels);
> > + dw_hdmi_set_channel_allocation(dw->data.hdmi, ca);
> > +
> > + dw_hdmi_set_sample_non_pcm(dw->data.hdmi,
> > + params->iec.status[0] &
> IEC958_AES0_NONAUDIO);
> > + dw_hdmi_set_sample_width(dw->data.hdmi,
> params->sample_width);
> > +
> > + return ret;
> > +}
> > +
> > +static void audio_shutdown(struct device *dev, void *data) { }
> > +
> > +static int audio_mute_stream(struct device *dev, void *data,
> > + bool enable, int direction) {
> > + struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
> > + int ret = 0;
> > +
> > + if (!enable)
> > + dw_hdmi_audio_enable(dw->data.hdmi);
> > + else
> > + dw_hdmi_audio_disable(dw->data.hdmi);
> > +
> > + return ret;
> > +}
> > +
> > +static int audio_get_eld(struct device *dev, void *data,
> > + u8 *buf, size_t len) {
> > + struct dw_hdmi_audio_data *audio = data;
> > + u8 *eld;
> > +
> > + eld = audio->get_eld(audio->hdmi);
> > + if (eld)
> > + memcpy(buf, eld, min_t(size_t, MAX_ELD_BYTES, len));
> > + else
> > + /* Pass en empty ELD if connector not available */
> > + memset(buf, 0, len);
> > +
> > + return 0;
> > +}
> > +
> > +static int audio_hook_plugged_cb(struct device *dev, void *data,
> > + hdmi_codec_plugged_cb fn,
> > + struct device *codec_dev) {
> > + struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
> > +
> > + return dw_hdmi_set_plugged_cb(dw->data.hdmi, fn, codec_dev); }
> > +
> > +static const struct hdmi_codec_ops audio_codec_ops = {
> > + .hw_params = audio_hw_params,
> > + .audio_shutdown = audio_shutdown,
> > + .mute_stream = audio_mute_stream,
> > + .get_eld = audio_get_eld,
> > + .hook_plugged_cb = audio_hook_plugged_cb, };
> > +
> > +static int snd_dw_hdmi_probe(struct platform_device *pdev) {
> > + struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
> > + struct snd_dw_hdmi *dw;
> > +
> > + const struct hdmi_codec_pdata codec_data = {
> > + .i2s = 1,
> > + .spdif = 0,
> > + .ops = &audio_codec_ops,
> > + .max_i2s_channels = 8,
> > + .data = data,
> > + };
> > +
> > + dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
> > + if (!dw)
> > + return -ENOMEM;
> > +
> > + dw->data = *data;
> > +
> > + platform_set_drvdata(pdev, dw);
> > +
> > + dw->audio_pdev = platform_device_register_data(&pdev->dev,
> > +
> HDMI_CODEC_DRV_NAME, 1,
> > +
> &codec_data,
> > +
> > + sizeof(codec_data));
> > +
> > + return PTR_ERR_OR_ZERO(dw->audio_pdev); }
> > +
> > +static int snd_dw_hdmi_remove(struct platform_device *pdev) {
> > + struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
> > +
> > + platform_device_unregister(dw->audio_pdev);
> > +
> > + return 0;
> > +}
> > +
> > +static struct platform_driver snd_dw_hdmi_driver = {
> > + .probe = snd_dw_hdmi_probe,
> > + .remove = snd_dw_hdmi_remove,
> > + .driver = {
> > + .name = DRIVER_NAME,
> > + },
> > +};
> > +
> > +module_platform_driver(snd_dw_hdmi_driver);
> > +
> > +MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@xxxxxxx>");
> > +MODULE_DESCRIPTION("Synopsis Designware HDMI GPA ALSA
> interface");
> > +MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME);
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > index c6e701acd416..1385d8f7870e 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -191,7 +191,10 @@ struct dw_hdmi {
> >
> > spinlock_t audio_lock;
> > struct mutex audio_mutex;
> > + unsigned int sample_non_pcm;
> > + unsigned int sample_width;
> > unsigned int sample_rate;
> > + unsigned int channels;
> > unsigned int audio_cts;
> > unsigned int audio_n;
> > bool audio_enable;
> > @@ -589,6 +592,8 @@ static unsigned int hdmi_compute_n(unsigned int
> freq, unsigned long pixel_clk)
> > n = 4096;
> > else if (pixel_clk == 74176000 || pixel_clk == 148352000)
> > n = 11648;
> > + else if (pixel_clk == 297000000)
> > + n = 3072;
> > else
> > n = 4096;
> > n *= mult;
> > @@ -601,6 +606,8 @@ static unsigned int hdmi_compute_n(unsigned int
> freq, unsigned long pixel_clk)
> > n = 17836;
> > else if (pixel_clk == 148352000)
> > n = 8918;
> > + else if (pixel_clk == 297000000)
> > + n = 4704;
> > else
> > n = 6272;
> > n *= mult;
> > @@ -615,6 +622,8 @@ static unsigned int hdmi_compute_n(unsigned int
> freq, unsigned long pixel_clk)
> > n = 11648;
> > else if (pixel_clk == 148352000)
> > n = 5824;
> > + else if (pixel_clk == 297000000)
> > + n = 5120;
> > else
> > n = 6144;
> > n *= mult;
> > @@ -660,7 +669,7 @@ static void hdmi_set_clk_regenerator(struct
> dw_hdmi *hdmi,
> > config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
> >
> > /* Only compute CTS when using internal AHB audio */
> > - if (config3 & HDMI_CONFIG3_AHBAUDDMA) {
> > + if ((config3 & HDMI_CONFIG3_AHBAUDDMA) || (config3 &
> > + HDMI_CONFIG3_GPAUD)) {
>
> Update the comment to include GPAUD.
I will update it.
>
> > /*
> > * Compute the CTS value from the N value. Note that
> CTS and N
> > * can be up to 20 bits in total, so we need 64-bit
> > math. Also @@ -702,6 +711,22 @@ static void
> hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
> > mutex_unlock(&hdmi->audio_mutex);
> > }
> >
> > +void dw_hdmi_set_sample_width(struct dw_hdmi *hdmi, unsigned int
> > +width) {
> > + mutex_lock(&hdmi->audio_mutex);
> > + hdmi->sample_width = width;
> > + mutex_unlock(&hdmi->audio_mutex); }
> > +EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_width);
> > +
> > +void dw_hdmi_set_sample_non_pcm(struct dw_hdmi *hdmi, unsigned int
> > +non_pcm) {
> > + mutex_lock(&hdmi->audio_mutex);
> > + hdmi->sample_non_pcm = non_pcm;
> > + mutex_unlock(&hdmi->audio_mutex); }
> > +EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_non_pcm);
> > +
> > void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int
> rate)
> > {
> > mutex_lock(&hdmi->audio_mutex);
> > @@ -717,6 +742,7 @@ void dw_hdmi_set_channel_count(struct dw_hdmi
> *hdmi, unsigned int cnt)
> > u8 layout;
> >
> > mutex_lock(&hdmi->audio_mutex);
> > + hdmi->channels = cnt;
> >
> > /*
> > * For >2 channel PCM audio, we need to select layout 1 @@
> > -765,6 +791,87 @@ static u8 *hdmi_audio_get_eld(struct dw_hdmi *hdmi)
> > return hdmi->curr_conn->eld;
> > }
> >
> > +static void dw_hdmi_gp_audio_enable(struct dw_hdmi *hdmi) {
> > + int sample_freq = 0x2, org_sample_freq = 0xD;
> > + int ch_mask = BIT(hdmi->channels) - 1;
> > +
> > + switch (hdmi->sample_rate) {
> > + case 32000:
> > + sample_freq = 0x03;
> > + org_sample_freq = 0x0C;
> > + break;
> > + case 44100:
> > + sample_freq = 0x00;
> > + org_sample_freq = 0x0F;
> > + break;
> > + case 48000:
> > + sample_freq = 0x02;
> > + org_sample_freq = 0x0D;
> > + break;
> > + case 88200:
> > + sample_freq = 0x08;
> > + org_sample_freq = 0x07;
> > + break;
> > + case 96000:
> > + sample_freq = 0x0A;
> > + org_sample_freq = 0x05;
> > + break;
> > + case 176400:
> > + sample_freq = 0x0C;
> > + org_sample_freq = 0x03;
> > + break;
> > + case 192000:
> > + sample_freq = 0x0E;
> > + org_sample_freq = 0x01;
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
> > + hdmi_enable_audio_clk(hdmi, true);
> > +
> > + hdmi_writeb(hdmi, 0x1, HDMI_FC_AUDSCHNLS0);
> > + hdmi_writeb(hdmi, hdmi->channels, HDMI_FC_AUDSCHNLS2);
> > + hdmi_writeb(hdmi, 0x22, HDMI_FC_AUDSCHNLS3);
> > + hdmi_writeb(hdmi, 0x22, HDMI_FC_AUDSCHNLS4);
> > + hdmi_writeb(hdmi, 0x11, HDMI_FC_AUDSCHNLS5);
> > + hdmi_writeb(hdmi, 0x11, HDMI_FC_AUDSCHNLS6);
> > + hdmi_writeb(hdmi, (0x3 << 4) | sample_freq,
> HDMI_FC_AUDSCHNLS7);
> > + hdmi_writeb(hdmi, (org_sample_freq << 4) | 0xb,
> > + HDMI_FC_AUDSCHNLS8);
> > +
> > + hdmi_writeb(hdmi, ch_mask, HDMI_GP_CONF1);
> > + hdmi_writeb(hdmi, 0x02, HDMI_GP_CONF2);
> > + hdmi_writeb(hdmi, 0x01, HDMI_GP_CONF0);
> > +
> > + hdmi_modb(hdmi, 0x3, 0x3, HDMI_FC_DATAUTO3);
> > +
> > + /* hbr */
> > + if (hdmi->sample_rate == 192000 && hdmi->channels == 8 &&
> > + hdmi->sample_width == 32 && hdmi->sample_non_pcm) {
> > + hdmi_modb(hdmi, 0x01, 0x01, HDMI_GP_CONF2);
> > + }
> > +
> > + if (hdmi->phy.ops->enable_audio)
> > + hdmi->phy.ops->enable_audio(hdmi, hdmi->phy.data,
> > + hdmi->channels,
> > + hdmi->sample_width,
> > + hdmi->sample_rate,
> > +
> hdmi->sample_non_pcm); }
> > +
> > +static void dw_hdmi_gp_audio_disable(struct dw_hdmi *hdmi) {
> > + hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0);
> > +
> > + hdmi_modb(hdmi, 0, 0x3, HDMI_FC_DATAUTO3);
> > + if (hdmi->phy.ops->disable_audio)
> > + hdmi->phy.ops->disable_audio(hdmi, hdmi->phy.data);
> > +
> > + hdmi_enable_audio_clk(hdmi, false); }
> > +
> > static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
> > {
> > hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); @@
> -3259,6
> > +3366,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device
> *pdev,
> > hdmi->plat_data = plat_data;
> > hdmi->dev = dev;
> > hdmi->sample_rate = 48000;
> > + hdmi->channels = 2;
> > hdmi->disabled = true;
> > hdmi->rxsense = true;
> > hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
> @@
> > -3482,6 +3590,24 @@ struct dw_hdmi *dw_hdmi_probe(struct
> platform_device *pdev,
> > pdevinfo.size_data = sizeof(audio);
> > pdevinfo.dma_mask = DMA_BIT_MASK(32);
> > hdmi->audio = platform_device_register_full(&pdevinfo);
> > + } else if (iores && config3 & HDMI_CONFIG3_GPAUD) {
> > + struct dw_hdmi_audio_data audio;
> > +
> > + audio.phys = iores->start;
> > + audio.base = hdmi->regs;
> > + audio.irq = irq;
> > + audio.hdmi = hdmi;
> > + audio.get_eld = hdmi_audio_get_eld;
> > +
> > + hdmi->enable_audio = dw_hdmi_gp_audio_enable;
> > + hdmi->disable_audio = dw_hdmi_gp_audio_disable;
> > +
> > + pdevinfo.name = "dw-hdmi-gp-audio";
> > + pdevinfo.id = PLATFORM_DEVID_NONE;
> > + pdevinfo.data = &audio;
> > + pdevinfo.size_data = sizeof(audio);
> > + pdevinfo.dma_mask = DMA_BIT_MASK(32);
> > + hdmi->audio = platform_device_register_full(&pdevinfo);
> > }
> >
> > if (!plat_data->disable_cec && (config0 & HDMI_CONFIG0_CEC)) {
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > index 1999db05bc3b..99aa1c03343b 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > @@ -158,8 +158,17 @@
> > #define HDMI_FC_SPDDEVICEINF 0x1062
> > #define HDMI_FC_AUDSCONF 0x1063
> > #define HDMI_FC_AUDSSTAT 0x1064
> > -#define HDMI_FC_AUDSCHNLS7 0x106e
> > -#define HDMI_FC_AUDSCHNLS8 0x106f
> > +#define HDMI_FC_AUDSV 0x1065
> > +#define HDMI_FC_AUDSU 0x1066
> > +#define HDMI_FC_AUDSCHNLS0 0x1067
> > +#define HDMI_FC_AUDSCHNLS1 0x1068
> > +#define HDMI_FC_AUDSCHNLS2 0x1069
> > +#define HDMI_FC_AUDSCHNLS3 0x106A
> > +#define HDMI_FC_AUDSCHNLS4 0x106B
> > +#define HDMI_FC_AUDSCHNLS5 0x106C
> > +#define HDMI_FC_AUDSCHNLS6 0x106D
> > +#define HDMI_FC_AUDSCHNLS7 0x106E
> > +#define HDMI_FC_AUDSCHNLS8 0x106F
> > #define HDMI_FC_DATACH0FILL 0x1070
> > #define HDMI_FC_DATACH1FILL 0x1071
> > #define HDMI_FC_DATACH2FILL 0x1072
> > diff --git a/include/drm/bridge/dw_hdmi.h
> > b/include/drm/bridge/dw_hdmi.h index 70082f80a8c8..7f73c3398a54
> 100644
> > --- a/include/drm/bridge/dw_hdmi.h
> > +++ b/include/drm/bridge/dw_hdmi.h
> > @@ -121,6 +121,9 @@ struct dw_hdmi_phy_ops {
> > void (*update_hpd)(struct dw_hdmi *hdmi, void *data,
> > bool force, bool disabled, bool rxsense);
> > void (*setup_hpd)(struct dw_hdmi *hdmi, void *data);
> > + void (*enable_audio)(struct dw_hdmi *hdmi, void *data, int channel,
> > + int width, int rate, int non_pcm);
> > + void (*disable_audio)(struct dw_hdmi *hdmi, void *data);
> > };
> >
> > struct dw_hdmi_plat_data {
> > @@ -173,6 +176,8 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi
> *hdmi,
> > bool hpd, bool rx_sense);
> >
> > int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi,
> hdmi_codec_plugged_cb fn,
> > struct device *codec_dev);
> > +void dw_hdmi_set_sample_non_pcm(struct dw_hdmi *hdmi, unsigned int
> > +non_pcm); void dw_hdmi_set_sample_width(struct dw_hdmi *hdmi,
> > +unsigned int width);
> > void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int
> rate);
> > void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int
> cnt);
> > void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8
> > *channel_status);
>
> Thanks,
> Neil
Thanks,
Sandor