144 lines
4.9 KiB
Diff
144 lines
4.9 KiB
Diff
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
|
index d7e65c869415..2ea9f69d312b 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
|
@@ -40,8 +40,11 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
|
|
{
|
|
struct dw_hdmi_i2s_audio_data *audio = data;
|
|
struct dw_hdmi *hdmi = audio->hdmi;
|
|
+ int sample_width = hparms->sample_width;
|
|
+ int ca = hparms->cea.channel_allocation;
|
|
u8 conf0 = 0;
|
|
u8 conf1 = 0;
|
|
+ u8 conf2 = 0;
|
|
u8 inputclkfs = 0;
|
|
|
|
/* it cares I2S only */
|
|
@@ -57,6 +60,17 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
|
|
inputclkfs = HDMI_AUD_INPUTCLKFS_64FS;
|
|
conf0 = (HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_EN0);
|
|
|
|
+ if (hparms->format == SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE) {
|
|
+ conf2 |= HDMI_AUD_CONF2_NLPCM;
|
|
+ if (hparms->channels == 8)
|
|
+ conf2 |= HDMI_AUD_CONF2_HBR;
|
|
+
|
|
+ sample_width = 21;
|
|
+ ca = 0;
|
|
+ }
|
|
+
|
|
+ hdmi_write(audio, conf2, HDMI_AUD_CONF2);
|
|
+
|
|
/* Enable the required i2s lanes */
|
|
switch (hparms->channels) {
|
|
case 7 ... 8:
|
|
@@ -70,10 +84,13 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
|
|
/* Fall-thru */
|
|
}
|
|
|
|
- switch (hparms->sample_width) {
|
|
+ switch (sample_width) {
|
|
case 16:
|
|
conf1 = HDMI_AUD_CONF1_WIDTH_16;
|
|
break;
|
|
+ case 21:
|
|
+ conf1 = HDMI_AUD_CONF1_WIDTH_21;
|
|
+ break;
|
|
case 24:
|
|
case 32:
|
|
conf1 = HDMI_AUD_CONF1_WIDTH_24;
|
|
@@ -104,7 +121,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
|
|
dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
|
|
dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
|
|
dw_hdmi_set_channel_count(hdmi, hparms->channels);
|
|
- dw_hdmi_set_channel_allocation(hdmi, hparms->cea.channel_allocation);
|
|
+ dw_hdmi_set_channel_allocation(hdmi, ca);
|
|
|
|
hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS);
|
|
hdmi_write(audio, conf0, HDMI_AUD_CONF0);
|
|
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
|
|
index 1999db05bc3b..bff849a336f7 100644
|
|
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
|
|
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
|
|
@@ -917,8 +917,13 @@ enum {
|
|
HDMI_AUD_CONF1_MODE_BURST_1 = 0x60,
|
|
HDMI_AUD_CONF1_MODE_BURST_2 = 0x80,
|
|
HDMI_AUD_CONF1_WIDTH_16 = 0x10,
|
|
+ HDMI_AUD_CONF1_WIDTH_21 = 0x15,
|
|
HDMI_AUD_CONF1_WIDTH_24 = 0x18,
|
|
|
|
+/* AUD_CONF1 field values */
|
|
+ HDMI_AUD_CONF2_NLPCM = 0x02,
|
|
+ HDMI_AUD_CONF2_HBR = 0x01,
|
|
+
|
|
/* AUD_CTS3 field values */
|
|
HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
|
|
HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
|
|
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
|
|
index 83b17682e01c..7448afae6495 100644
|
|
--- a/include/sound/hdmi-codec.h
|
|
+++ b/include/sound/hdmi-codec.h
|
|
@@ -45,6 +45,7 @@ struct hdmi_codec_params {
|
|
int sample_rate;
|
|
int sample_width;
|
|
int channels;
|
|
+ snd_pcm_format_t format;
|
|
};
|
|
|
|
typedef void (*hdmi_codec_plugged_cb)(struct device *dev,
|
|
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
|
|
index f005751da2cc..90c10f19ea5a 100644
|
|
--- a/sound/soc/codecs/hdmi-codec.c
|
|
+++ b/sound/soc/codecs/hdmi-codec.c
|
|
@@ -486,6 +486,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
|
hp.sample_width = params_width(params);
|
|
hp.sample_rate = params_rate(params);
|
|
hp.channels = params_channels(params);
|
|
+ hp.format = params_format(params);
|
|
|
|
return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
|
|
cf, &hp);
|
|
@@ -606,7 +607,8 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
|
|
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
|
|
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
|
|
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
|
|
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
|
|
+ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\
|
|
+ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
|
|
|
|
static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
|
struct snd_soc_dai *dai)
|
|
diff -ruPN linux/sound/soc/rockchip/rockchip_i2s.c linux-new/sound/soc/rockchip/rockchip_i2s.c
|
|
--- linux/sound/soc/rockchip/rockchip_i2s.c 2022-03-02 11:42:57.000000000 +0100
|
|
+++ linux-new/sound/soc/rockchip/rockchip_i2s.c 2022-03-06 11:27:08.442421292 +0100
|
|
@@ -320,6 +320,9 @@
|
|
case SNDRV_PCM_FORMAT_S32_LE:
|
|
val |= I2S_TXCR_VDW(32);
|
|
break;
|
|
+ case SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE:
|
|
+ val |= I2S_TXCR_VDW(21);
|
|
+ break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
@@ -466,7 +469,8 @@
|
|
SNDRV_PCM_FMTBIT_S16_LE |
|
|
SNDRV_PCM_FMTBIT_S20_3LE |
|
|
SNDRV_PCM_FMTBIT_S24_LE |
|
|
- SNDRV_PCM_FMTBIT_S32_LE),
|
|
+ SNDRV_PCM_FMTBIT_S32_LE |
|
|
+ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE),
|
|
},
|
|
.capture = {
|
|
.stream_name = "Capture",
|
|
@@ -477,7 +481,8 @@
|
|
SNDRV_PCM_FMTBIT_S16_LE |
|
|
SNDRV_PCM_FMTBIT_S20_3LE |
|
|
SNDRV_PCM_FMTBIT_S24_LE |
|
|
- SNDRV_PCM_FMTBIT_S32_LE),
|
|
+ SNDRV_PCM_FMTBIT_S32_LE |
|
|
+ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE),
|
|
},
|
|
.ops = &rockchip_i2s_dai_ops,
|
|
.symmetric_rates = 1,
|