mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	The patches were generated from the RPi repo with the following command: git format-patch v6.6.34..rpi-6.1.y Some patches needed rebasing and, as usual, the applied and reverted, wireless drivers, Github workflows, READMEs and defconfigs patches were removed. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
		
			
				
	
	
		
			89 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From db9d903ae06b19201bc307be3dff716a1f2c5a80 Mon Sep 17 00:00:00 2001
 | 
						|
From: Phil Elwell <phil@raspberrypi.com>
 | 
						|
Date: Fri, 21 Jul 2023 12:07:16 +0100
 | 
						|
Subject: [PATCH 0548/1085] ASOC: dwc: Fix 16-bit audio handling
 | 
						|
 | 
						|
IMO the Synopsys datasheet could be clearer in this area, but it seems
 | 
						|
that the DMA data ports (DMATX and DMARX) expect left and right samples
 | 
						|
in alternate writes; if a stereo pair is pushed in a single 32-bit
 | 
						|
write, the upper half is ignored, leading to double speed audio with a
 | 
						|
confused stereo image. Make sure the necessary changes happen by
 | 
						|
updating the DMA configuration data in the hw_params method.
 | 
						|
 | 
						|
The set_bclk_ratio change was made at a time when it looked like it
 | 
						|
could be causing an error, but I think the division of responsibilities
 | 
						|
is clearer this way (and the kernel log clearer without the info-level
 | 
						|
message).
 | 
						|
 | 
						|
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | 
						|
---
 | 
						|
 sound/soc/dwc/dwc-i2s.c | 22 +++++++++++++++-------
 | 
						|
 1 file changed, 15 insertions(+), 7 deletions(-)
 | 
						|
 | 
						|
--- a/sound/soc/dwc/dwc-i2s.c
 | 
						|
+++ b/sound/soc/dwc/dwc-i2s.c
 | 
						|
@@ -271,23 +271,34 @@ static int dw_i2s_hw_params(struct snd_p
 | 
						|
 {
 | 
						|
 	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
 | 
						|
 	struct i2s_clk_config_data *config = &dev->config;
 | 
						|
+	union dw_i2s_snd_dma_data *dma_data = NULL;
 | 
						|
 	int ret;
 | 
						|
 
 | 
						|
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 | 
						|
+		dma_data = &dev->play_dma_data;
 | 
						|
+	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 | 
						|
+		dma_data = &dev->capture_dma_data;
 | 
						|
+	else
 | 
						|
+		return -1;
 | 
						|
+
 | 
						|
 	switch (params_format(params)) {
 | 
						|
 	case SNDRV_PCM_FORMAT_S16_LE:
 | 
						|
 		config->data_width = 16;
 | 
						|
+		dma_data->dt.addr_width = 2;
 | 
						|
 		dev->ccr = 0x00;
 | 
						|
 		dev->xfer_resolution = 0x02;
 | 
						|
 		break;
 | 
						|
 
 | 
						|
 	case SNDRV_PCM_FORMAT_S24_LE:
 | 
						|
 		config->data_width = 24;
 | 
						|
+		dma_data->dt.addr_width = 4;
 | 
						|
 		dev->ccr = 0x08;
 | 
						|
 		dev->xfer_resolution = 0x04;
 | 
						|
 		break;
 | 
						|
 
 | 
						|
 	case SNDRV_PCM_FORMAT_S32_LE:
 | 
						|
 		config->data_width = 32;
 | 
						|
+		dma_data->dt.addr_width = 4;
 | 
						|
 		dev->ccr = 0x10;
 | 
						|
 		dev->xfer_resolution = 0x05;
 | 
						|
 		break;
 | 
						|
@@ -519,24 +530,21 @@ static int dw_i2s_set_bclk_ratio(struct
 | 
						|
 	struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
 | 
						|
 	struct i2s_clk_config_data *config = &dev->config;
 | 
						|
 
 | 
						|
-	dev_err(dev->dev, "%s(%d)\n", __func__, ratio);
 | 
						|
+	dev_dbg(dev->dev, "%s(%d)\n", __func__, ratio);
 | 
						|
+	if (ratio < config->data_width * 2)
 | 
						|
+		return -EINVAL;
 | 
						|
+
 | 
						|
 	switch (ratio) {
 | 
						|
 	case 32:
 | 
						|
-		config->data_width = 16;
 | 
						|
 		dev->ccr = 0x00;
 | 
						|
-		dev->xfer_resolution = 0x02;
 | 
						|
 		break;
 | 
						|
 
 | 
						|
 	case 48:
 | 
						|
-		config->data_width = 24;
 | 
						|
 		dev->ccr = 0x08;
 | 
						|
-		dev->xfer_resolution = 0x04;
 | 
						|
 		break;
 | 
						|
 
 | 
						|
 	case 64:
 | 
						|
-		config->data_width = 32;
 | 
						|
 		dev->ccr = 0x10;
 | 
						|
-		dev->xfer_resolution = 0x05;
 | 
						|
 		break;
 | 
						|
 	default:
 | 
						|
 		return -EINVAL;
 |