From e80b8e5c53c30df1cba45258d10b04872b7eea67 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:38:00 +0000 Subject: [PATCH 01/16] ASoC: SDCA: Add support for clock Entity properties Add support for parsing the Clock Source Entity properties from DisCo/ACPI. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-10-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 25 +++++++++++++++++++++++++ sound/soc/sdca/sdca_functions.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 6cb5ab79ee54..13edc976679a 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -784,6 +784,29 @@ struct sdca_entity_iot { bool is_dataport; }; +/** + * enum sdca_clock_type - SDCA Clock Types + * + * Indicate the synchronicity of an Clock Entity, see section 6.4.1.3 + * of the SDCA v1.0 specification. + */ +enum sdca_clock_type { + SDCA_CLOCK_TYPE_EXTERNAL = 0x00, + SDCA_CLOCK_TYPE_INTERNAL_ASYNC = 0x01, + SDCA_CLOCK_TYPE_INTERNAL_SYNC = 0x02, + SDCA_CLOCK_TYPE_INTERNAL_SOURCE_SYNC = 0x03, +}; + +/** + * struct sdca_entity_cs - information specific to Clock Source Entities + * @type: Synchronicity of the Clock Source. + * @max_delay: The maximum delay in microseconds before the clock is stable. + */ +struct sdca_entity_cs { + enum sdca_clock_type type; + unsigned int max_delay; +}; + /** * enum sdca_entity_type - SDCA Entity Type codes * @SDCA_ENTITY_TYPE_ENTITY_0: Entity 0, not actually from the @@ -846,6 +869,7 @@ enum sdca_entity_type { * @num_sources: Number of sources for the Entity. * @num_controls: Number of Controls for the Entity. * @iot: Input/Output Terminal specific Entity properties. + * @cs: Clock Source specific Entity properties. */ struct sdca_entity { const char *label; @@ -858,6 +882,7 @@ struct sdca_entity { int num_controls; union { struct sdca_entity_iot iot; + struct sdca_entity_cs cs; }; }; diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 8a143048a0ab..dd9e2dce6e65 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -881,6 +881,33 @@ static int find_sdca_entity_iot(struct device *dev, return 0; } +static int find_sdca_entity_cs(struct device *dev, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + struct sdca_entity_cs *clock = &entity->cs; + u32 tmp; + int ret; + + ret = fwnode_property_read_u32(entity_node, "mipi-sdca-cs-type", &tmp); + if (ret) { + dev_err(dev, "%s: clock type missing: %d\n", entity->label, ret); + return ret; + } + + clock->type = tmp; + + ret = fwnode_property_read_u32(entity_node, + "mipi-sdca-clock-valid-max-delay", &tmp); + if (!ret) + clock->max_delay = tmp; + + dev_info(dev, "%s: clock type %#x delay %d\n", entity->label, + clock->type, clock->max_delay); + + return 0; +} + static int find_sdca_entity(struct device *dev, struct fwnode_handle *function_node, struct fwnode_handle *entity_node, @@ -913,6 +940,9 @@ static int find_sdca_entity(struct device *dev, case SDCA_ENTITY_TYPE_OT: ret = find_sdca_entity_iot(dev, entity_node, entity); break; + case SDCA_ENTITY_TYPE_CS: + ret = find_sdca_entity_cs(dev, entity_node, entity); + break; default: break; } -- 2.50.1 From 9da195880f167ab7c2d595388decf783c9920121 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:38:01 +0000 Subject: [PATCH 02/16] ASoC: SDCA: Add support for PDE Entity properties Add support for parsing the Power Domain Entity properties from DisCo/ACPI. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-11-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 48 +++++++++++ sound/soc/sdca/sdca_functions.c | 138 ++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 13edc976679a..f001ab643fed 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -39,6 +39,11 @@ struct sdca_function_desc; */ #define SDCA_MAX_CHANNEL_COUNT 32 +/* + * Sanity check on number of PDE delays, can be expanded if needed. + */ +#define SDCA_MAX_DELAY_COUNT 256 + /** * enum sdca_function_type - SDCA Function Type codes * @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features. @@ -807,6 +812,47 @@ struct sdca_entity_cs { unsigned int max_delay; }; +/** + * enum sdca_pde_power_state - SDCA Power States + * + * SDCA Power State values from SDCA specification v1.0 Section 7.12.4. + */ +enum sdca_pde_power_state { + SDCA_PDE_PS0 = 0x0, + SDCA_PDE_PS1 = 0x1, + SDCA_PDE_PS2 = 0x2, + SDCA_PDE_PS3 = 0x3, + SDCA_PDE_PS4 = 0x4, +}; + +/** + * struct sdca_pde_delay - describes the delay changing between 2 power states + * @from_ps: The power state being exited. + * @to_ps: The power state being entered. + * @us: The delay in microseconds switching between the two states. + */ +struct sdca_pde_delay { + int from_ps; + int to_ps; + unsigned int us; +}; + +/** + * struct sdca_entity_pde - information specific to Power Domain Entities + * @managed: Dynamically allocated array pointing to each Entity + * controlled by this PDE. + * @max_delay: Dynamically allocated array of delays for switching + * between power states. + * @num_managed: Number of Entities controlled by this PDE. + * @num_max_delay: Number of delays specified for state changes. + */ +struct sdca_entity_pde { + struct sdca_entity **managed; + struct sdca_pde_delay *max_delay; + int num_managed; + int num_max_delay; +}; + /** * enum sdca_entity_type - SDCA Entity Type codes * @SDCA_ENTITY_TYPE_ENTITY_0: Entity 0, not actually from the @@ -870,6 +916,7 @@ enum sdca_entity_type { * @num_controls: Number of Controls for the Entity. * @iot: Input/Output Terminal specific Entity properties. * @cs: Clock Source specific Entity properties. + * @pde: Power Domain Entity specific Entity properties. */ struct sdca_entity { const char *label; @@ -883,6 +930,7 @@ struct sdca_entity { union { struct sdca_entity_iot iot; struct sdca_entity_cs cs; + struct sdca_entity_pde pde; }; }; diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index dd9e2dce6e65..091d55abe109 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -908,6 +908,66 @@ static int find_sdca_entity_cs(struct device *dev, return 0; } +static int find_sdca_entity_pde(struct device *dev, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + static const int mult_delay = 3; + struct sdca_entity_pde *power = &entity->pde; + struct sdca_pde_delay *delays; + int num_delays; + u32 *delay_list; + int i, j; + + num_delays = fwnode_property_count_u32(entity_node, + "mipi-sdca-powerdomain-transition-max-delay"); + if (num_delays <= 0) { + dev_err(dev, "%s: max delay list missing: %d\n", + entity->label, num_delays); + return -EINVAL; + } else if (num_delays % mult_delay != 0) { + dev_err(dev, "%s: delays not multiple of %d\n", + entity->label, mult_delay); + return -EINVAL; + } else if (num_delays > SDCA_MAX_DELAY_COUNT) { + dev_err(dev, "%s: maximum number of transition delays exceeded\n", + entity->label); + return -EINVAL; + } + + /* There are 3 values per delay */ + delays = devm_kcalloc(dev, num_delays / mult_delay, + sizeof(*delays), GFP_KERNEL); + if (!delays) + return -ENOMEM; + + delay_list = kcalloc(num_delays, sizeof(*delay_list), GFP_KERNEL); + if (!delay_list) + return -ENOMEM; + + fwnode_property_read_u32_array(entity_node, + "mipi-sdca-powerdomain-transition-max-delay", + delay_list, num_delays); + + num_delays /= mult_delay; + + for (i = 0, j = 0; i < num_delays; i++) { + delays[i].from_ps = delay_list[j++]; + delays[i].to_ps = delay_list[j++]; + delays[i].us = delay_list[j++]; + + dev_info(dev, "%s: from %#x to %#x delay %dus\n", entity->label, + delays[i].from_ps, delays[i].to_ps, delays[i].us); + } + + power->num_max_delay = num_delays; + power->max_delay = delays; + + kfree(delay_list); + + return 0; +} + static int find_sdca_entity(struct device *dev, struct fwnode_handle *function_node, struct fwnode_handle *entity_node, @@ -943,6 +1003,9 @@ static int find_sdca_entity(struct device *dev, case SDCA_ENTITY_TYPE_CS: ret = find_sdca_entity_cs(dev, entity_node, entity); break; + case SDCA_ENTITY_TYPE_PDE: + ret = find_sdca_entity_pde(dev, entity_node, entity); + break; default: break; } @@ -1047,6 +1110,21 @@ static struct sdca_entity *find_sdca_entity_by_label(struct sdca_function_data * return NULL; } +static struct sdca_entity *find_sdca_entity_by_id(struct sdca_function_data *function, + const int id) +{ + int i; + + for (i = 0; i < function->num_entities; i++) { + struct sdca_entity *entity = &function->entities[i]; + + if (entity->id == id) + return entity; + } + + return NULL; +} + static int find_sdca_entity_connection_iot(struct device *dev, struct sdca_function_data *function, struct fwnode_handle *entity_node, @@ -1087,6 +1165,62 @@ static int find_sdca_entity_connection_iot(struct device *dev, return 0; } +static int find_sdca_entity_connection_pde(struct device *dev, + struct sdca_function_data *function, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + struct sdca_entity_pde *power = &entity->pde; + struct sdca_entity **managed; + u32 *managed_list; + int num_managed; + int i; + + num_managed = fwnode_property_count_u32(entity_node, + "mipi-sdca-powerdomain-managed-list"); + if (!num_managed) { + return 0; + } else if (num_managed < 0) { + dev_err(dev, "%s: managed list missing: %d\n", entity->label, num_managed); + return num_managed; + } else if (num_managed > SDCA_MAX_ENTITY_COUNT) { + dev_err(dev, "%s: maximum number of managed entities exceeded\n", + entity->label); + return -EINVAL; + } + + managed = devm_kcalloc(dev, num_managed, sizeof(*managed), GFP_KERNEL); + if (!managed) + return -ENOMEM; + + managed_list = kcalloc(num_managed, sizeof(*managed_list), GFP_KERNEL); + if (!managed_list) + return -ENOMEM; + + fwnode_property_read_u32_array(entity_node, + "mipi-sdca-powerdomain-managed-list", + managed_list, num_managed); + + for (i = 0; i < num_managed; i++) { + managed[i] = find_sdca_entity_by_id(function, managed_list[i]); + if (!managed[i]) { + dev_err(dev, "%s: failed to find entity with id %#x\n", + entity->label, managed_list[i]); + kfree(managed_list); + return -EINVAL; + } + + dev_info(dev, "%s -> %s\n", managed[i]->label, entity->label); + } + + kfree(managed_list); + + power->num_managed = num_managed; + power->managed = managed; + + return 0; +} + static int find_sdca_entity_connection(struct device *dev, struct sdca_function_data *function, struct fwnode_handle *entity_node, @@ -1103,6 +1237,10 @@ static int find_sdca_entity_connection(struct device *dev, ret = find_sdca_entity_connection_iot(dev, function, entity_node, entity); break; + case SDCA_ENTITY_TYPE_PDE: + ret = find_sdca_entity_connection_pde(dev, function, + entity_node, entity); + break; default: ret = 0; break; -- 2.50.1 From 330cbb40bb3664a18a19760bd6dc6003d6624041 Mon Sep 17 00:00:00 2001 From: Alexey Charkov Date: Mon, 20 Jan 2025 13:01:27 +0400 Subject: [PATCH 03/16] dt-bindings: ASoC: rockchip: Add compatible for RK3588 SPDIF Add a compatible string for SPDIF on RK3588, which is similar to the one on RK3568. Signed-off-by: Alexey Charkov Acked-by: Conor Dooley Link: https://patch.msgid.link/20250120-rk3588-spdif-v1-1-1415f5871dc7@gmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rockchip-spdif.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml index c3c989ef2a2c..32dea7392e8d 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml +++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml @@ -31,6 +31,10 @@ properties: - rockchip,rk3288-spdif - rockchip,rk3308-spdif - const: rockchip,rk3066-spdif + - items: + - enum: + - rockchip,rk3588-spdif + - const: rockchip,rk3568-spdif reg: maxItems: 1 -- 2.50.1 From e97d06cb4386af4e069a2dc713de70500538d0bd Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 10 Feb 2025 12:59:37 +0100 Subject: [PATCH 04/16] ASoC: tscs454: Use str_enable_disable() in pll_power_event() Remove hard-coded strings by using the str_enable_disable() helper function. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250210115937.53654-1-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/codecs/tscs454.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tscs454.c b/sound/soc/codecs/tscs454.c index 850e5de9271e..da2f3cb1cd13 100644 --- a/sound/soc/codecs/tscs454.c +++ b/sound/soc/codecs/tscs454.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -737,9 +738,7 @@ static int pll_power_event(struct snd_soc_dapm_widget *w, ret = snd_soc_component_update_bits(component, R_PLLCTL, msk, val); if (ret < 0) { dev_err(component->dev, "Failed to %s PLL %d (%d)\n", - enable ? "enable" : "disable", - pll1 ? 1 : 2, - ret); + str_enable_disable(enable), pll1 ? 1 : 2, ret); return ret; } -- 2.50.1 From c5528214c7c0a753c908a7b353309ba665985fb4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 10 Feb 2025 14:21:28 +0100 Subject: [PATCH 05/16] ASoC: codecs: wcd93xx-sdw: fix of_property_read_bool() warnings Using of_property_read_bool() for non-boolean properties has been deprecated in favour of of_property_present() and since commit c141ecc3cecd ("of: Warn when of_property_read_bool() is used on non-boolean properties") this also generates a warning: OF: /soc@0/soundwire@3330000/wcd9380-tx@0,3: Read of boolean property 'qcom,tx-port-mapping' with a value. Switch to using of_property_present() to look for "qcom,tx-port-mapping" properties. Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20250210132128.7734-1-johan+linaro@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd937x-sdw.c | 2 +- sound/soc/codecs/wcd938x-sdw.c | 2 +- sound/soc/codecs/wcd939x-sdw.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wcd937x-sdw.c b/sound/soc/codecs/wcd937x-sdw.c index 1fbff313b965..4891fa0c963f 100644 --- a/sound/soc/codecs/wcd937x-sdw.c +++ b/sound/soc/codecs/wcd937x-sdw.c @@ -1028,7 +1028,7 @@ static int wcd9370_probe(struct sdw_slave *pdev, return -ENOMEM; /* Port map index starts at 0, however the data port for this codec start at index 1 */ - if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) { + if (of_property_present(dev->of_node, "qcom,tx-port-mapping")) { wcd->is_tx = true; ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping", &pdev->m_port_map[1], diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c index 7da8a10bd0a9..4e2ae542cee3 100644 --- a/sound/soc/codecs/wcd938x-sdw.c +++ b/sound/soc/codecs/wcd938x-sdw.c @@ -1229,7 +1229,7 @@ static int wcd9380_probe(struct sdw_slave *pdev, * Port map index starts with 0, however the data port for this codec * are from index 1 */ - if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) { + if (of_property_present(dev->of_node, "qcom,tx-port-mapping")) { wcd->is_tx = true; ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping", &pdev->m_port_map[1], diff --git a/sound/soc/codecs/wcd939x-sdw.c b/sound/soc/codecs/wcd939x-sdw.c index fca95777a75a..36868fad3e8b 100644 --- a/sound/soc/codecs/wcd939x-sdw.c +++ b/sound/soc/codecs/wcd939x-sdw.c @@ -1429,7 +1429,7 @@ static int wcd9390_probe(struct sdw_slave *pdev, const struct sdw_device_id *id) * Port map index starts with 0, however the data port for this codec * are from index 1 */ - if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) { + if (of_property_present(dev->of_node, "qcom,tx-port-mapping")) { wcd->is_tx = true; ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping", -- 2.50.1 From 21aa330fec31bb530a4ef6c9555fb157d0711112 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 6 Feb 2025 11:03:06 +0800 Subject: [PATCH 06/16] ASoC: fsl_micfil: Add decimation filter bypass mode support When decimation filter bypass mode is enabled, PDM data can be written into FIFO directly without any processing. The interface of this mode is DSD big endian format, when user needs this format, then this mode is enabled. This mode is only for the i.MX943 platform currently. Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20250206030306.2618620-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 49 ++++++++++++++++++++++++++++++++++---- sound/soc/fsl/fsl_micfil.h | 1 + 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index fa4136683392..73d8910a6188 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,7 @@ struct fsl_micfil { struct fsl_micfil_verid verid; struct fsl_micfil_param param; bool mclk_flag; /* mclk enable flag */ + bool dec_bypass; }; struct fsl_micfil_soc_data { @@ -129,7 +131,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx943 = { .fifos = 8, .fifo_depth = 32, .dataline = 0xf, - .formats = SNDRV_PCM_FMTBIT_S32_LE, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_DSD_U32_BE, .use_edma = true, .use_verid = true, .volume_sx = false, @@ -724,14 +726,14 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, if (ret) return ret; - if (micfil->vad_enabled) + if (micfil->vad_enabled && !micfil->dec_bypass) fsl_micfil_hwvad_enable(micfil); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (micfil->vad_enabled) + if (micfil->vad_enabled && !micfil->dec_bypass) fsl_micfil_hwvad_disable(micfil); /* Disable the module */ @@ -778,8 +780,9 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, { struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); unsigned int channels = params_channels(params); + snd_pcm_format_t format = params_format(params); unsigned int rate = params_rate(params); - int clk_div = 8; + int clk_div = 8, mclk_rate, div_multiply_k; int osr = MICFIL_OSR_DEFAULT; int ret; @@ -801,7 +804,39 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, micfil->mclk_flag = true; - ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8); + /* floor(K * CLKDIV) */ + switch (micfil->quality) { + case QUALITY_HIGH: + div_multiply_k = clk_div >> 1; + break; + case QUALITY_LOW: + case QUALITY_VLOW1: + div_multiply_k = clk_div << 1; + break; + case QUALITY_VLOW2: + div_multiply_k = clk_div << 2; + break; + case QUALITY_MEDIUM: + case QUALITY_VLOW0: + default: + div_multiply_k = clk_div; + break; + } + + if (format == SNDRV_PCM_FORMAT_DSD_U32_BE) { + micfil->dec_bypass = true; + /* + * According to equation 29 in RM: + * MCLK_CLK_ROOT = PDM CLK rate * 2 * floor(K * CLKDIV) + * PDM CLK rate = rate * physical bit width (32) + */ + mclk_rate = rate * div_multiply_k * 32 * 2; + } else { + micfil->dec_bypass = false; + mclk_rate = rate * clk_div * osr * 8; + } + + ret = clk_set_rate(micfil->mclk, mclk_rate); if (ret) return ret; @@ -809,6 +844,10 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; + regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, + MICFIL_CTRL2_DEC_BYPASS, + micfil->dec_bypass ? MICFIL_CTRL2_DEC_BYPASS : 0); + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2, MICFIL_CTRL2_CLKDIV | MICFIL_CTRL2_CICOSR, FIELD_PREP(MICFIL_CTRL2_CLKDIV, clk_div) | diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h index aa3661ea4ffc..fdfe4e7125bc 100644 --- a/sound/soc/fsl/fsl_micfil.h +++ b/sound/soc/fsl/fsl_micfil.h @@ -53,6 +53,7 @@ #define MICFIL_CTRL1_CHEN(ch) BIT(ch) /* MICFIL Control Register 2 -- REG_MICFILL_CTRL2 0x04 */ +#define MICFIL_CTRL2_DEC_BYPASS BIT(31) #define MICFIL_CTRL2_QSEL_SHIFT 25 #define MICFIL_CTRL2_QSEL GENMASK(27, 25) #define MICFIL_QSEL_MEDIUM_QUALITY 0 -- 2.50.1 From 91931af18bd22437e08e2471f5484d6fbdd8ab93 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 10 Feb 2025 16:33:27 -0600 Subject: [PATCH 07/16] gpiolib: add gpiod_multi_set_value_cansleep() Add a new gpiod_multi_set_value_cansleep() helper function with fewer parameters than gpiod_set_array_value_cansleep(). Calling gpiod_set_array_value_cansleep() can get quite verbose. In many cases, the first arguments all come from the same struct gpio_descs, so having a separate function where we can just pass that cuts down on the boilerplate. Signed-off-by: David Lechner Reviewed-by: Andy Shevchenko Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20250210-gpio-set-array-helper-v3-1-d6a673674da8@baylibre.com Signed-off-by: Bartosz Golaszewski --- include/linux/gpio/consumer.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index db2dfbae8edb..5cbd4afd7862 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -3,6 +3,7 @@ #define __LINUX_GPIO_CONSUMER_H #include +#include #include struct acpi_device; @@ -655,4 +656,14 @@ static inline void gpiod_unexport(struct gpio_desc *desc) #endif /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ +static inline int gpiod_multi_set_value_cansleep(struct gpio_descs *descs, + unsigned long *value_bitmap) +{ + if (IS_ERR_OR_NULL(descs)) + return PTR_ERR_OR_ZERO(descs); + + return gpiod_set_array_value_cansleep(descs->ndescs, descs->desc, + descs->info, value_bitmap); +} + #endif -- 2.50.1 From f22ba3561daa792dd138ed543e0bf48efe0b999c Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 11 Feb 2025 17:50:18 -0500 Subject: [PATCH 08/16] ASoC: SOF: imx-common: set sdev->pdata->hw_pdata after common is alloc'd 'imx_unregister_action' uses 'sdev->pdata->hw_pdata' to fetch the pointer to the common data structure. As such, if 'sdev->pdata->hw_pdata' is not set before adding 'imx_unregister_action' to the devres list, we risk derefrencing a NULL pointer if any of the calls between 'devm_add_action_or_reset' and 'sdev->pdata->hw_pdata = common' fails. Set 'sdev->pdata->hw_pdata' to point to 'common' as soon as 'common' is allocated. Fixes: 651e0ed391b1 (" ASoC: SOF: imx: introduce more common structures and functions") Signed-off-by: Laurentiu Mihalcea Reviewed-by: Frank Li Reviewed-by: Daniel Baluta Link: https://patch.msgid.link/20250211225018.2642-1-laurentiumihalcea111@gmail.com Reviewed-by: Frank Li Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/imx/imx-common.c b/sound/soc/sof/imx/imx-common.c index 82057af1436c..c3594815e60e 100644 --- a/sound/soc/sof/imx/imx-common.c +++ b/sound/soc/sof/imx/imx-common.c @@ -378,6 +378,7 @@ static int imx_probe(struct snd_sof_dev *sdev) if (!common) return dev_err_probe(sdev->dev, -ENOMEM, "failed to allocate common data\n"); + sdev->pdata->hw_pdata = common; common->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp", PLATFORM_DEVID_NONE, @@ -436,7 +437,6 @@ static int imx_probe(struct snd_sof_dev *sdev) imx_dsp_set_data(common->ipc_handle, sdev); sdev->num_cores = 1; - sdev->pdata->hw_pdata = common; sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; sdev->dsp_box.offset = get_chip_info(sdev)->ipc_info.boot_mbox_offset; -- 2.50.1 From ad0fbcebb5f6e093d433a0873758a2778d747eb8 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 10 Feb 2025 16:33:41 -0600 Subject: [PATCH 09/16] ASoC: adau1701: use gpiod_multi_set_value_cansleep Reduce verbosity by using gpiod_multi_set_value_cansleep() instead of gpiod_set_array_value_cansleep(). Acked-by: Mark Brown Reviewed-by: Linus Walleij Signed-off-by: David Lechner Acked-by: Jonathan Cameron Link: https://patch.msgid.link/20250210-gpio-set-array-helper-v3-15-d6a673674da8@baylibre.com Signed-off-by: Mark Brown --- sound/soc/codecs/adau1701.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 291249e0a2a3..6876462d8bdb 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -325,9 +325,7 @@ static int adau1701_reset(struct snd_soc_component *component, unsigned int clkd __assign_bit(1, values, 1); break; } - gpiod_set_array_value_cansleep(adau1701->gpio_pll_mode->ndescs, - adau1701->gpio_pll_mode->desc, adau1701->gpio_pll_mode->info, - values); + gpiod_multi_set_value_cansleep(adau1701->gpio_pll_mode, values); } adau1701->pll_clkdiv = clkdiv; -- 2.50.1 From 828c0aa63706410503526d0ee522b9ac3232c86b Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Thu, 13 Feb 2025 16:06:52 +0530 Subject: [PATCH 10/16] ASoC: amd: ps: use switch statements for acp pci revision id check Use switch statements for acp pci revision id check in SoundWire dma irq handling. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250213103652.1082203-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/pci-ps.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 220dca8cba85..2ff8e67c19bd 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -111,16 +111,21 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 stream_id = ACP63_SDW0_AUDIO2_RX; break; } - if (adata->acp_rev >= ACP70_PCI_REV) - adata->acp70_sdw0_dma_intr_stat[stream_id] = 1; - else + switch (adata->acp_rev) { + case ACP63_PCI_REV: adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; - + break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + adata->acp70_sdw0_dma_intr_stat[stream_id] = 1; + break; + } sdw_dma_irq_flag = 1; } } } - if (adata->acp_rev == ACP63_PCI_REV) { + switch (adata->acp_rev) { + case ACP63_PCI_REV: if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); @@ -133,7 +138,9 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; sdw_dma_irq_flag = 1; } - } else { + break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: if (ext_intr_stat1 & ACP70_P1_SDW_DMA_IRQ_MASK) { for (index = ACP70_P1_AUDIO2_RX_THRESHOLD; index <= ACP70_P1_AUDIO0_TX_THRESHOLD; index++) { @@ -166,6 +173,7 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 } } } + break; } return sdw_dma_irq_flag; } -- 2.50.1 From ae575d2145d1a2c8bb5d2835d7d54751f3b0bace Mon Sep 17 00:00:00 2001 From: Sheetal Date: Thu, 13 Feb 2025 11:12:16 +0000 Subject: [PATCH 11/16] ASoC: tegra: Remove the isomgr_bw APIs export Commit 4a91fe4c0d683 ("ASoC: tegra: Add interconnect support") exported tegra_isomgr_adma_setbw, tegra_isomgr_adma_register and tegra_isomgr_adma_register APIs, but there are no users of these that required these symbols to be exported. Hence, remove the exporting of the symbols. Fixes: 4a91fe4c0d683 ("ASoC: tegra: Add interconnect support") Signed-off-by: Sheetal Link: https://patch.msgid.link/20250213111216.1238344-1-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_isomgr_bw.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/tegra/tegra_isomgr_bw.c b/sound/soc/tegra/tegra_isomgr_bw.c index 7789efe13873..18e802bca6a6 100644 --- a/sound/soc/tegra/tegra_isomgr_bw.c +++ b/sound/soc/tegra/tegra_isomgr_bw.c @@ -75,7 +75,6 @@ int tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream, return icc_set_bw(adma_isomgr->icc_path_handle, adma_isomgr->current_bandwidth, adma_isomgr->max_bw); } -EXPORT_SYMBOL(tegra_isomgr_adma_setbw); int tegra_isomgr_adma_register(struct device *dev) { @@ -114,7 +113,6 @@ int tegra_isomgr_adma_register(struct device *dev) return 0; } -EXPORT_SYMBOL(tegra_isomgr_adma_register); void tegra_isomgr_adma_unregister(struct device *dev) { @@ -125,7 +123,6 @@ void tegra_isomgr_adma_unregister(struct device *dev) mutex_destroy(&admaif->adma_isomgr->mutex); } -EXPORT_SYMBOL(tegra_isomgr_adma_unregister); MODULE_AUTHOR("Mohan Kumar "); MODULE_DESCRIPTION("Tegra ADMA Bandwidth Request driver"); -- 2.50.1 From 994719ed6d81a6f4677875ab6730254c0bc484ea Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Wed, 12 Feb 2025 10:12:26 +0100 Subject: [PATCH 12/16] ASoC: Intel: avs: Use str_on_off() in avs_dsp_core_power() Remove hard-coded strings by using the str_on_off() helper function. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250212091227.1217-3-thorsten.blum@linux.dev Reviewed-by: Cezary Rojewski Signed-off-by: Mark Brown --- sound/soc/intel/avs/dsp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/dsp.c b/sound/soc/intel/avs/dsp.c index 7b47e52c2b39..b9de691e9b9b 100644 --- a/sound/soc/intel/avs/dsp.c +++ b/sound/soc/intel/avs/dsp.c @@ -6,6 +6,7 @@ // Amadeusz Slawinski // +#include #include #include "avs.h" #include "registers.h" @@ -39,7 +40,7 @@ int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power) AVS_ADSPCS_TIMEOUT_US); if (ret) dev_err(adev->dev, "core_mask %d power %s failed: %d\n", - core_mask, power ? "on" : "off", ret); + core_mask, str_on_off(power), ret); return ret; } -- 2.50.1 From 11c1967f1a796bf2ff56a7118147f1d39d9f5ee0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:23:20 +0000 Subject: [PATCH 13/16] ASoC: soc-pcm: no need to check dpcm->fe on dpcm_be_connect() All dpcm from for_each_dpcm_be(fe, ...) loop has same fe (that is the reason to connected to this list). We don't need to check (dpcm->fe == fe) in this loop. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmdvyk87.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ebe99d369ca9..0d556d350560 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1304,10 +1304,9 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, snd_soc_dpcm_mutex_assert_held(fe); /* only add new dpcms */ - for_each_dpcm_be(fe, stream, dpcm) { - if (dpcm->be == be && dpcm->fe == fe) + for_each_dpcm_be(fe, stream, dpcm) + if (dpcm->be == be) return 0; - } fe_substream = snd_soc_dpcm_get_substream(fe, stream); be_substream = snd_soc_dpcm_get_substream(be, stream); -- 2.50.1 From 238c863eb3d3c6ed58493bacfd1f4b36bdcfa92f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:23:52 +0000 Subject: [PATCH 14/16] ASoC: soc-core: makes snd_soc_set_dmi_name() local soc-core.c only calls snd_soc_set_dmi_name(), so we don't need to have EXPORT_SYMBOL_GPL() for it. Let's makes it local function. No one uses *flavour parameter, let's remove it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7tfyk7b.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc.h | 10 ---------- sound/soc/soc-core.c | 15 +++++++-------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 16e4e488521c..62c90ef40f1a 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -522,16 +522,6 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, unsigned int dai_fmt); -#ifdef CONFIG_DMI -int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour); -#else -static inline int snd_soc_set_dmi_name(struct snd_soc_card *card, - const char *flavour) -{ - return 0; -} -#endif - /* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); int snd_soc_params_to_frame_size(const struct snd_pcm_hw_params *params); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 26b34b688508..ae7b3e39d5ff 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1887,7 +1887,6 @@ static void append_dmi_string(struct snd_soc_card *card, const char *str) /** * snd_soc_set_dmi_name() - Register DMI names to card * @card: The card to register DMI names - * @flavour: The flavour "differentiator" for the card amongst its peers. * * An Intel machine driver may be used by many different devices but are * difficult for userspace to differentiate, since machine drivers usually @@ -1915,7 +1914,7 @@ static void append_dmi_string(struct snd_soc_card *card, const char *str) * * Returns 0 on success, otherwise a negative error code. */ -int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour) +static int snd_soc_set_dmi_name(struct snd_soc_card *card) { const char *vendor, *product, *board; @@ -1959,16 +1958,16 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour) return 0; } - /* Add flavour to dmi long name */ - if (flavour) - append_dmi_string(card, flavour); - /* set the card long name */ card->long_name = card->dmi_longname; return 0; } -EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name); +#else +static inline int snd_soc_set_dmi_name(struct snd_soc_card *card) +{ + return 0; +} #endif /* CONFIG_DMI */ static void soc_check_tplg_fes(struct snd_soc_card *card) @@ -2256,7 +2255,7 @@ static int snd_soc_bind_card(struct snd_soc_card *card) goto probe_end; /* try to set some sane longname if DMI is available */ - snd_soc_set_dmi_name(card, NULL); + snd_soc_set_dmi_name(card); soc_setup_card_name(card, card->snd_card->shortname, card->name, NULL); -- 2.50.1 From 1248d29464cc682c2a1793cfc5d4ebeb374c6738 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:24:06 +0000 Subject: [PATCH 15/16] ASoC: soc-ops: makes snd_soc_read_signed() void snd_soc_read_signed() never return error. Let's makes it void. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8zyk6x.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index c6601ef16f84..bb1fbffeef9f 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -122,10 +122,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); * This functions reads a codec register. The register value is shifted right * by 'shift' bits and masked with the given 'mask'. Afterwards it translates * the given registervalue into a signed integer if sign_bit is non-zero. - * - * Returns 0 on sucess, otherwise an error value */ -static int snd_soc_read_signed(struct snd_soc_component *component, +static void snd_soc_read_signed(struct snd_soc_component *component, unsigned int reg, unsigned int mask, unsigned int shift, unsigned int sign_bit, int *signed_val) { @@ -137,13 +135,13 @@ static int snd_soc_read_signed(struct snd_soc_component *component, if (!sign_bit) { *signed_val = val; - return 0; + return; } /* non-negative number */ if (!(val & BIT(sign_bit))) { *signed_val = val; - return 0; + return; } ret = val; @@ -157,8 +155,6 @@ static int snd_soc_read_signed(struct snd_soc_component *component, ret |= ~((int)(BIT(sign_bit) - 1)); *signed_val = ret; - - return 0; } /** @@ -266,14 +262,11 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, unsigned int mask = (1ULL << fls(max)) - 1; unsigned int invert = mc->invert; int val; - int ret; if (sign_bit) mask = BIT(sign_bit + 1) - 1; - ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); - if (ret) - return ret; + snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); ucontrol->value.integer.value[0] = val - min; if (invert) @@ -282,13 +275,9 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, if (snd_soc_volsw_is_stereo(mc)) { if (reg == reg2) - ret = snd_soc_read_signed(component, reg, mask, rshift, - sign_bit, &val); + snd_soc_read_signed(component, reg, mask, rshift, sign_bit, &val); else - ret = snd_soc_read_signed(component, reg2, mask, shift, - sign_bit, &val); - if (ret) - return ret; + snd_soc_read_signed(component, reg2, mask, shift, sign_bit, &val); ucontrol->value.integer.value[1] = val - min; if (invert) -- 2.50.1 From 7e1caa679686dde5c24d60b139f234568045758f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:24:17 +0000 Subject: [PATCH 16/16] ASoC: soc-pcm: makes dpcm_dapm_stream_event() void No one uses dpcm_dapm_stream_event() return value, and it always return 0. Let's makes it void. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87seojyk6m.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dpcm.h | 4 ++-- sound/soc/soc-pcm.c | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h index c6fb350b4b06..c1b88c3b7835 100644 --- a/include/sound/soc-dpcm.h +++ b/include/sound/soc-dpcm.h @@ -143,8 +143,8 @@ void dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream); int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream); int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd); int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream); -int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, - int event); +void dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, int event); + bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget, enum snd_soc_dapm_direction dir); int widget_in_list(struct snd_soc_dapm_widget_list *list, struct snd_soc_dapm_widget *widget); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 0d556d350560..a206a25451f7 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -400,8 +400,7 @@ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd) } /* DPCM stream event, send event to FE and all active BEs. */ -int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, - int event) +void dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, int event) { struct snd_soc_dpcm *dpcm; @@ -422,8 +421,6 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, } snd_soc_dapm_stream_event(fe, dir, event); - - return 0; } static void soc_pcm_set_dai_params(struct snd_soc_dai *dai, -- 2.50.1