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,
 |