From 5b4288792ff246cf2bda0c81cebcc02d1f631ca3 Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Wed, 22 Jan 2025 18:41:26 +0200 Subject: [PATCH 001/651] ASoC: cpcap: Implement .set_bias_level With VAUDIO regulator being always on, we have to put it in low-power mode when codec is not in use to decrease power usage. Do so by implementing driver .set_bias_level callback. Signed-off-by: Ivaylo Dimitrov Link: https://patch.msgid.link/20250122164129.807247-3-ivo.g.dimitrov.75@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/cpcap.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index 04304a7ad915..53f549ede6a6 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -260,6 +261,7 @@ struct cpcap_audio { int codec_clk_id; int codec_freq; int codec_format; + struct regulator *vaudio; }; static int cpcap_st_workaround(struct snd_soc_dapm_widget *w, @@ -1637,6 +1639,11 @@ static int cpcap_soc_probe(struct snd_soc_component *component) snd_soc_component_set_drvdata(component, cpcap); cpcap->component = component; + cpcap->vaudio = devm_regulator_get(component->dev, "VAUDIO"); + if (IS_ERR(cpcap->vaudio)) + return dev_err_probe(component->dev, PTR_ERR(cpcap->vaudio), + "Cannot get VAUDIO regulator\n"); + cpcap->regmap = dev_get_regmap(component->dev->parent, NULL); if (!cpcap->regmap) return -ENODEV; @@ -1649,6 +1656,27 @@ static int cpcap_soc_probe(struct snd_soc_component *component) return cpcap_audio_reset(component, false); } +static int cpcap_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) +{ + struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); + + switch (level) { + case SND_SOC_BIAS_OFF: + break; + case SND_SOC_BIAS_PREPARE: + regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_NORMAL); + break; + case SND_SOC_BIAS_STANDBY: + regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_STANDBY); + break; + case SND_SOC_BIAS_ON: + break; + } + + return 0; +} + static const struct snd_soc_component_driver soc_codec_dev_cpcap = { .probe = cpcap_soc_probe, .controls = cpcap_snd_controls, @@ -1657,6 +1685,7 @@ static const struct snd_soc_component_driver soc_codec_dev_cpcap = { .num_dapm_widgets = ARRAY_SIZE(cpcap_dapm_widgets), .dapm_routes = intercon, .num_dapm_routes = ARRAY_SIZE(intercon), + .set_bias_level = cpcap_set_bias_level, .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, From 02d4a97ce30c0494ce6a614cd54d583caa0f8016 Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Wed, 22 Jan 2025 18:41:27 +0200 Subject: [PATCH 002/651] dt-bindings: mfd: motorola-cpcap: Document audio-codec interrupts Add DT binding for the audio-codec headset detection interrupts. Signed-off-by: Ivaylo Dimitrov Link: https://patch.msgid.link/20250122164129.807247-4-ivo.g.dimitrov.75@gmail.com Acked-by: Rob Herring (Arm) Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/mfd/motorola-cpcap.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt b/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt index 190230216de8..f00827c9b67f 100644 --- a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt +++ b/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt @@ -31,6 +31,10 @@ node must be named "audio-codec". Required properties for the audio-codec subnode: - #sound-dai-cells = <1>; +- interrupts : should contain jack detection interrupts, with headset + detect interrupt matching "hs" and microphone bias 2 + detect interrupt matching "mb2" in interrupt-names. +- interrupt-names : Contains "hs", "mb2" The audio-codec provides two DAIs. The first one is connected to the Stereo HiFi DAC and the second one is connected to the Voice DAC. @@ -52,6 +56,8 @@ Example: audio-codec { #sound-dai-cells = <1>; + interrupts-extended = <&cpcap 9 0>, <&cpcap 10 0>; + interrupt-names = "hs", "mb2"; /* HiFi */ port@0 { From 7ed1b265021dd13ce5619501b388e489ddc8e204 Mon Sep 17 00:00:00 2001 From: Ivaylo Dimitrov Date: Wed, 22 Jan 2025 18:41:29 +0200 Subject: [PATCH 003/651] ASoC: cpcap: Implement jack detection cpcap has headphones/microphone and PTT button detection logic, implement code to support it. Signed-off-by: Ivaylo Dimitrov Link: https://patch.msgid.link/20250122164129.807247-6-ivo.g.dimitrov.75@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/cpcap.c | 171 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index 53f549ede6a6..3eb862643b53 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -14,9 +14,18 @@ #include #include #include +#include +#include #include #include +/* Register 8 - CPCAP_REG_INTS1 --- Interrupt Sense 1 */ +#define CPCAP_BIT_HS_S 9 /* Headset */ +#define CPCAP_BIT_MB2_S 10 /* Mic Bias2 */ + +/* Register 9 - CPCAP_REG_INTS2 --- Interrupt Sense 2 */ +#define CPCAP_BIT_PTT_S 11 /* Push To Talk */ + /* Register 512 CPCAP_REG_VAUDIOC --- Audio Regulator and Bias Voltage */ #define CPCAP_BIT_AUDIO_LOW_PWR 6 #define CPCAP_BIT_AUD_LOWPWR_SPEED 5 @@ -262,6 +271,9 @@ struct cpcap_audio { int codec_freq; int codec_format; struct regulator *vaudio; + int hsirq; + int mb2irq; + struct snd_soc_jack jack; }; static int cpcap_st_workaround(struct snd_soc_dapm_widget *w, @@ -1628,14 +1640,105 @@ static int cpcap_audio_reset(struct snd_soc_component *component, return 0; } +static irqreturn_t cpcap_hs_irq_thread(int irq, void *data) +{ + struct snd_soc_component *component = data; + struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); + struct regmap *regmap = cpcap->regmap; + int status = 0; + int mask = SND_JACK_HEADSET; + int val; + + if (!regmap_test_bits(regmap, CPCAP_REG_INTS1, BIT(CPCAP_BIT_HS_S))) { + val = BIT(CPCAP_BIT_MB_ON2) | BIT(CPCAP_BIT_PTT_CMP_EN); + regmap_update_bits(regmap, CPCAP_REG_TXI, val, val); + + val = BIT(CPCAP_BIT_ST_HS_CP_EN); + regmap_update_bits(regmap, CPCAP_REG_RXOA, val, val); + + regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_NORMAL); + + /* Give PTTS time to settle */ + msleep(20); + + if (!regmap_test_bits(regmap, CPCAP_REG_INTS2, + BIT(CPCAP_BIT_PTT_S))) { + /* Headphones detected. (May also be a headset with the + * MFB pressed.) + */ + status = SND_JACK_HEADPHONE; + dev_info(component->dev, "HP plugged in\n"); + } else if (regmap_test_bits(regmap, CPCAP_REG_INTS1, + BIT(CPCAP_BIT_MB2_S)) == 1) { + status = SND_JACK_HEADSET; + dev_info(component->dev, "HS plugged in\n"); + } else + dev_info(component->dev, "Unsupported HS plugged in\n"); + } else { + bool mic = cpcap->jack.status & SND_JACK_MICROPHONE; + + dev_info(component->dev, "H%s disconnect\n", mic ? "S" : "P"); + val = BIT(CPCAP_BIT_MB_ON2) | BIT(CPCAP_BIT_PTT_CMP_EN); + regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, val, 0); + + val = BIT(CPCAP_BIT_ST_HS_CP_EN); + regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, val, 0); + + regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_STANDBY); + + mask |= SND_JACK_BTN_0; + } + + snd_soc_jack_report(&cpcap->jack, status, mask); + + return IRQ_HANDLED; +} + +static irqreturn_t cpcap_mb2_irq_thread(int irq, void *data) +{ + struct snd_soc_component *component = data; + struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); + struct regmap *regmap = cpcap->regmap; + int status = 0; + int mb2; + int ptt; + + if (regmap_test_bits(regmap, CPCAP_REG_INTS1, BIT(CPCAP_BIT_HS_S)) == 1) + return IRQ_HANDLED; + + mb2 = regmap_test_bits(regmap, CPCAP_REG_INTS1, BIT(CPCAP_BIT_MB2_S)); + ptt = regmap_test_bits(regmap, CPCAP_REG_INTS2, BIT(CPCAP_BIT_PTT_S)); + + /* Initial detection might have been with MFB pressed */ + if (!(cpcap->jack.status & SND_JACK_MICROPHONE)) { + if (ptt == 1 && mb2 == 1) { + dev_info(component->dev, "MIC plugged in\n"); + snd_soc_jack_report(&cpcap->jack, SND_JACK_MICROPHONE, + SND_JACK_MICROPHONE); + } + + return IRQ_HANDLED; + } + + if (!mb2 || !ptt) + status = SND_JACK_BTN_0; + + snd_soc_jack_report(&cpcap->jack, status, SND_JACK_BTN_0); + + return IRQ_HANDLED; +} + static int cpcap_soc_probe(struct snd_soc_component *component) { + struct platform_device *pdev = to_platform_device(component->dev); + struct snd_soc_card *card = component->card; struct cpcap_audio *cpcap; int err; cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL); if (!cpcap) return -ENOMEM; + snd_soc_component_set_drvdata(component, cpcap); cpcap->component = component; @@ -1644,6 +1747,16 @@ static int cpcap_soc_probe(struct snd_soc_component *component) return dev_err_probe(component->dev, PTR_ERR(cpcap->vaudio), "Cannot get VAUDIO regulator\n"); + err = snd_soc_card_jack_new(card, "Headphones", + SND_JACK_HEADSET | SND_JACK_BTN_0, + &cpcap->jack); + if (err < 0) { + dev_err(component->dev, "Cannot create HS jack: %i\n", err); + return err; + } + + snd_jack_set_key(cpcap->jack.jack, SND_JACK_BTN_0, KEY_MEDIA); + cpcap->regmap = dev_get_regmap(component->dev->parent, NULL); if (!cpcap->regmap) return -ENODEV; @@ -1653,7 +1766,58 @@ static int cpcap_soc_probe(struct snd_soc_component *component) if (err) return err; - return cpcap_audio_reset(component, false); + cpcap->hsirq = platform_get_irq_byname(pdev, "hs"); + if (cpcap->hsirq < 0) + return cpcap->hsirq; + + err = devm_request_threaded_irq(component->dev, cpcap->hsirq, NULL, + cpcap_hs_irq_thread, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "cpcap-codec-hs", + component); + if (err) { + dev_warn(component->dev, "no HS irq%i: %i\n", + cpcap->hsirq, err); + return err; + } + + cpcap->mb2irq = platform_get_irq_byname(pdev, "mb2"); + if (cpcap->mb2irq < 0) + return cpcap->mb2irq; + + err = devm_request_threaded_irq(component->dev, cpcap->mb2irq, NULL, + cpcap_mb2_irq_thread, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "cpcap-codec-mb2", + component); + if (err) { + dev_warn(component->dev, "no MB2 irq%i: %i\n", + cpcap->mb2irq, err); + return err; + } + + err = cpcap_audio_reset(component, false); + if (err) + return err; + + cpcap_hs_irq_thread(cpcap->hsirq, component); + + enable_irq_wake(cpcap->hsirq); + enable_irq_wake(cpcap->mb2irq); + + return 0; +} + +static void cpcap_soc_remove(struct snd_soc_component *component) +{ + struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); + + disable_irq_wake(cpcap->hsirq); + disable_irq_wake(cpcap->mb2irq); } static int cpcap_set_bias_level(struct snd_soc_component *component, @@ -1661,6 +1825,10 @@ static int cpcap_set_bias_level(struct snd_soc_component *component, { struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); + /* VAIDIO should be kept in normal mode in order MIC/PTT to work */ + if (cpcap->jack.status & SND_JACK_MICROPHONE) + return 0; + switch (level) { case SND_SOC_BIAS_OFF: break; @@ -1679,6 +1847,7 @@ static int cpcap_set_bias_level(struct snd_soc_component *component, static const struct snd_soc_component_driver soc_codec_dev_cpcap = { .probe = cpcap_soc_probe, + .remove = cpcap_soc_remove, .controls = cpcap_snd_controls, .num_controls = ARRAY_SIZE(cpcap_snd_controls), .dapm_widgets = cpcap_dapm_widgets, From c9e9aa80022c6db71bc097a621a6145f39aa0ade Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Sat, 1 Feb 2025 00:50:21 +0000 Subject: [PATCH 004/651] ASoC: mediatek: Remove unused mtk_memif_set_rate mtk_memif_set_rate() has been unused since it was added in the 2019 commit 9cdf85a19b3a ("ASoC: mediatek: common: add some helpers to control mtk_memif") Remove it. (The _substream version is used, and is left in) Signed-off-by: Dr. David Alan Gilbert Link: https://patch.msgid.link/20250201005021.447726-1-linux@treblig.org Signed-off-by: Mark Brown --- sound/soc/mediatek/common/mtk-afe-fe-dai.c | 20 -------------------- sound/soc/mediatek/common/mtk-afe-fe-dai.h | 2 -- 2 files changed, 22 deletions(-) diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c index 3044d9ab3d4d..3809068f5620 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c @@ -500,26 +500,6 @@ static int mtk_memif_set_rate_fs(struct mtk_base_afe *afe, return 0; } -int mtk_memif_set_rate(struct mtk_base_afe *afe, - int id, unsigned int rate) -{ - int fs = 0; - - if (!afe->get_dai_fs) { - dev_err(afe->dev, "%s(), error, afe->get_dai_fs == NULL\n", - __func__); - return -EINVAL; - } - - fs = afe->get_dai_fs(afe, id, rate); - - if (fs < 0) - return -EINVAL; - - return mtk_memif_set_rate_fs(afe, id, fs); -} -EXPORT_SYMBOL_GPL(mtk_memif_set_rate); - int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream, int id, unsigned int rate) { diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.h b/sound/soc/mediatek/common/mtk-afe-fe-dai.h index 8cec90671827..b6d0f2b27e86 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.h +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.h @@ -42,8 +42,6 @@ int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, size_t dma_bytes); int mtk_memif_set_channel(struct mtk_base_afe *afe, int id, unsigned int channel); -int mtk_memif_set_rate(struct mtk_base_afe *afe, - int id, unsigned int rate); int mtk_memif_set_rate_substream(struct snd_pcm_substream *substream, int id, unsigned int rate); int mtk_memif_set_format(struct mtk_base_afe *afe, From f9a5c4b6afc79073491acdab7f1e943ee3a19fbb Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 7 Jan 2025 15:44:07 +0000 Subject: [PATCH 005/651] ASoC: rt722-sdca: Add some missing readable registers Add a few missing registers from the readable register callback. Suggested-by: Shuming Fan Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250107154408.814455-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt722-sdca-sdw.c | 49 +++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c index 25fc13687bc8..602547c5fb3f 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.c +++ b/sound/soc/codecs/rt722-sdca-sdw.c @@ -28,9 +28,50 @@ static bool rt722_sdca_readable_register(struct device *dev, unsigned int reg) 0): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_GE49, RT722_SDCA_CTL_DETECTED_MODE, 0): - case SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, - 0) ... SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, - RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_XU03, RT722_SDCA_CTL_SELECTED_MODE, + 0): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, + RT722_SDCA_CTL_FU_MUTE, CH_L) ... + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, + RT722_SDCA_CTL_FU_MUTE, CH_R): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_XU0D, + RT722_SDCA_CTL_SELECTED_MODE, 0): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, + RT722_SDCA_CTL_FU_MUTE, CH_L) ... + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, + RT722_SDCA_CTL_FU_MUTE, CH_R): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE40, + RT722_SDCA_CTL_REQ_POWER_STATE, 0): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE12, + RT722_SDCA_CTL_REQ_POWER_STATE, 0): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS01, + RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS11, + RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, + RT722_SDCA_CTL_FU_MUTE, CH_01) ... + SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, + RT722_SDCA_CTL_FU_MUTE, CH_04): + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_IT26, + RT722_SDCA_CTL_VENDOR_DEF, 0): + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_PDE2A, + RT722_SDCA_CTL_REQ_POWER_STATE, 0): + case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_CS1F, + RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): + case SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, + RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ... + SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, + RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, + RT722_SDCA_CTL_FU_MUTE, CH_L) ... + SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, + RT722_SDCA_CTL_FU_MUTE, CH_R): + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_OT23, + RT722_SDCA_CTL_VENDOR_DEF, CH_08): + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_PDE23, + RT722_SDCA_CTL_REQ_POWER_STATE, 0): + case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_CS31, + RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): case RT722_BUF_ADDR_HID1 ... RT722_BUF_ADDR_HID2: return true; default: @@ -74,6 +115,7 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int re case 0x5600000 ... 0x5600007: case 0x5700000 ... 0x5700004: case 0x5800000 ... 0x5800004: + case 0x5810000: case 0x5b00003: case 0x5c00011: case 0x5d00006: @@ -81,6 +123,7 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int re case 0x5f00030: case 0x6100000 ... 0x6100051: case 0x6100055 ... 0x6100057: + case 0x6100060: case 0x6100062: case 0x6100064 ... 0x6100065: case 0x6100067: From 299ce4beaf714abe76e3ad106f2e745748f693e9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 7 Jan 2025 15:44:08 +0000 Subject: [PATCH 006/651] ASoC: rt722-sdca: Make use of new expanded MBQ regmap Now the MBQ regmap implementation handles multiple sizes, this driver can combine its two register maps into one. So remove mbq_regmap and combine all the registers into regmap. Also as rt722_sdca_adc_mux_get/put() only exist to access mbq_regmap, rather than doing any processing, these can now be dropped and the normal DAPM helpers used. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250107154408.814455-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt722-sdca-sdw.c | 81 ++++++------------ sound/soc/codecs/rt722-sdca-sdw.h | 99 +++++++++++----------- sound/soc/codecs/rt722-sdca.c | 135 +++++++----------------------- sound/soc/codecs/rt722-sdca.h | 4 +- 4 files changed, 105 insertions(+), 214 deletions(-) diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c index 602547c5fb3f..2b0f82697b47 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.c +++ b/sound/soc/codecs/rt722-sdca-sdw.c @@ -16,7 +16,7 @@ #include "rt722-sdca.h" #include "rt722-sdca-sdw.h" -static bool rt722_sdca_readable_register(struct device *dev, unsigned int reg) +static int rt722_sdca_mbq_size(struct device *dev, unsigned int reg) { switch (reg) { case 0x2f01 ... 0x2f0a: @@ -73,32 +73,7 @@ static bool rt722_sdca_readable_register(struct device *dev, unsigned int reg) case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_CS31, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): case RT722_BUF_ADDR_HID1 ... RT722_BUF_ADDR_HID2: - return true; - default: - return false; - } -} - -static bool rt722_sdca_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case 0x2f01: - case 0x2f54: - case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_GE49, RT722_SDCA_CTL_DETECTED_MODE, - 0): - case SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, - 0) ... SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, - RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): - case RT722_BUF_ADDR_HID1 ... RT722_BUF_ADDR_HID2: - return true; - default: - return false; - } -} - -static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int reg) -{ - switch (reg) { + return 1; case 0x2000000 ... 0x2000024: case 0x2000029 ... 0x200004a: case 0x2000051 ... 0x2000052: @@ -151,15 +126,32 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int re RT722_SDCA_CTL_FU_CH_GAIN, CH_L): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PLATFORM_FU44, RT722_SDCA_CTL_FU_CH_GAIN, CH_R): - return true; + return 2; default: - return false; + return 0; } } -static bool rt722_sdca_mbq_volatile_register(struct device *dev, unsigned int reg) +static struct regmap_sdw_mbq_cfg rt722_mbq_config = { + .mbq_size = rt722_sdca_mbq_size, +}; + +static bool rt722_sdca_readable_register(struct device *dev, unsigned int reg) +{ + return rt722_sdca_mbq_size(dev, reg) > 0; +} + +static bool rt722_sdca_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { + case 0x2f01: + case 0x2f54: + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_GE49, RT722_SDCA_CTL_DETECTED_MODE, + 0): + case SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, + 0) ... SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, + RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): + case RT722_BUF_ADDR_HID1 ... RT722_BUF_ADDR_HID2: case 0x2000000: case 0x200000d: case 0x2000019: @@ -178,7 +170,7 @@ static bool rt722_sdca_mbq_volatile_register(struct device *dev, unsigned int re static const struct regmap_config rt722_sdca_regmap = { .reg_bits = 32, - .val_bits = 8, + .val_bits = 16, .readable_reg = rt722_sdca_readable_register, .volatile_reg = rt722_sdca_volatile_register, .max_register = 0x44ffffff, @@ -189,20 +181,6 @@ static const struct regmap_config rt722_sdca_regmap = { .use_single_write = true, }; -static const struct regmap_config rt722_sdca_mbq_regmap = { - .name = "sdw-mbq", - .reg_bits = 32, - .val_bits = 16, - .readable_reg = rt722_sdca_mbq_readable_register, - .volatile_reg = rt722_sdca_mbq_volatile_register, - .max_register = 0x41000312, - .reg_defaults = rt722_sdca_mbq_defaults, - .num_reg_defaults = ARRAY_SIZE(rt722_sdca_mbq_defaults), - .cache_type = REGCACHE_MAPLE, - .use_single_read = true, - .use_single_write = true, -}; - static int rt722_sdca_update_status(struct sdw_slave *slave, enum sdw_slave_status status) { @@ -412,18 +390,14 @@ static const struct sdw_slave_ops rt722_sdca_slave_ops = { static int rt722_sdca_sdw_probe(struct sdw_slave *slave, const struct sdw_device_id *id) { - struct regmap *regmap, *mbq_regmap; + struct regmap *regmap; /* Regmap Initialization */ - mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt722_sdca_mbq_regmap); - if (IS_ERR(mbq_regmap)) - return PTR_ERR(mbq_regmap); - - regmap = devm_regmap_init_sdw(slave, &rt722_sdca_regmap); + regmap = devm_regmap_init_sdw_mbq_cfg(slave, &rt722_sdca_regmap, &rt722_mbq_config); if (IS_ERR(regmap)) return PTR_ERR(regmap); - return rt722_sdca_init(&slave->dev, regmap, mbq_regmap, slave); + return rt722_sdca_init(&slave->dev, regmap, slave); } static int rt722_sdca_sdw_remove(struct sdw_slave *slave) @@ -461,7 +435,6 @@ static int __maybe_unused rt722_sdca_dev_suspend(struct device *dev) cancel_delayed_work_sync(&rt722->jack_btn_check_work); regcache_cache_only(rt722->regmap, true); - regcache_cache_only(rt722->mbq_regmap, true); return 0; } @@ -531,8 +504,6 @@ regmap_sync: slave->unattach_request = 0; regcache_cache_only(rt722->regmap, false); regcache_sync(rt722->regmap); - regcache_cache_only(rt722->mbq_regmap, false); - regcache_sync(rt722->mbq_regmap); return 0; } diff --git a/sound/soc/codecs/rt722-sdca-sdw.h b/sound/soc/codecs/rt722-sdca-sdw.h index 5b43e86f75d1..80b014456940 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.h +++ b/sound/soc/codecs/rt722-sdca-sdw.h @@ -31,50 +31,9 @@ static const struct reg_default rt722_sdca_reg_defaults[] = { { 0x2f5b, 0x07 }, { 0x2f5c, 0x27 }, { 0x2f5d, 0x07 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS01, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, - 0), 0x09 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS11, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, - 0), 0x09 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE12, RT722_SDCA_CTL_REQ_POWER_STATE, - 0), 0x03 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE40, RT722_SDCA_CTL_REQ_POWER_STATE, - 0), 0x03 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, RT722_SDCA_CTL_FU_MUTE, CH_L), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, RT722_SDCA_CTL_FU_MUTE, CH_R), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, RT722_SDCA_CTL_FU_MUTE, CH_L), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, RT722_SDCA_CTL_FU_MUTE, CH_R), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_CS1F, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, - 0), 0x09 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_01), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_02), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_03), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_04), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_PDE2A, RT722_SDCA_CTL_REQ_POWER_STATE, 0), - 0x03 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_IT26, RT722_SDCA_CTL_VENDOR_DEF, 0), - 0x00 }, - { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_CS31, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), - 0x09 }, - { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, RT722_SDCA_CTL_FU_MUTE, CH_L), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, RT722_SDCA_CTL_FU_MUTE, CH_R), - 0x01 }, - { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_PDE23, RT722_SDCA_CTL_REQ_POWER_STATE, 0), - 0x03 }, - { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_OT23, RT722_SDCA_CTL_VENDOR_DEF, 0), 0x00 }, -}; - -static const struct reg_default rt722_sdca_mbq_defaults[] = { { 0x200003c, 0xc214 }, { 0x2000046, 0x8004 }, + { 0x5810000, 0x702d }, { 0x6100006, 0x0005 }, { 0x6100010, 0x2630 }, { 0x6100011, 0x152f }, @@ -86,27 +45,34 @@ static const struct reg_default rt722_sdca_mbq_defaults[] = { { 0x6100028, 0x2a2a }, { 0x6100029, 0x4141 }, { 0x6100055, 0x0000 }, - { 0x5810000, 0x702d }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, RT722_SDCA_CTL_FU_MUTE, CH_L), + 0x01 }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, RT722_SDCA_CTL_FU_MUTE, CH_R), + 0x01 }, { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, RT722_SDCA_CTL_FU_VOLUME, CH_L), 0x0000 }, { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, RT722_SDCA_CTL_FU_VOLUME, CH_R), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, RT722_SDCA_CTL_FU_MUTE, CH_L), + 0x01 }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, RT722_SDCA_CTL_FU_MUTE, CH_R), + 0x01 }, { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, RT722_SDCA_CTL_FU_VOLUME, CH_L), 0x0000 }, { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, RT722_SDCA_CTL_FU_VOLUME, CH_R), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE12, RT722_SDCA_CTL_REQ_POWER_STATE, + 0), 0x03 }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS01, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, + 0), 0x09 }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS11, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, + 0), 0x09 }, + { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE40, RT722_SDCA_CTL_REQ_POWER_STATE, + 0), 0x03 }, { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PLATFORM_FU44, RT722_SDCA_CTL_FU_CH_GAIN, CH_L), 0x0000 }, { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PLATFORM_FU44, RT722_SDCA_CTL_FU_CH_GAIN, CH_R), 0x0000 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, - CH_01), 0x0000 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, - CH_02), 0x0000 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, - CH_03), 0x0000 }, - { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, - CH_04), 0x0000 }, { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_FU15, RT722_SDCA_CTL_FU_CH_GAIN, CH_01), 0x0000 }, { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_FU15, RT722_SDCA_CTL_FU_CH_GAIN, CH_02), @@ -115,10 +81,41 @@ static const struct reg_default rt722_sdca_mbq_defaults[] = { 0x0000 }, { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_FU15, RT722_SDCA_CTL_FU_CH_GAIN, CH_04), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_01), + 0x01 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_02), + 0x01 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_03), + 0x01 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_MUTE, CH_04), + 0x01 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, + CH_01), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, + CH_02), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, + CH_03), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME, + CH_04), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_PDE2A, RT722_SDCA_CTL_REQ_POWER_STATE, 0), + 0x03 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_CS1F, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, + 0), 0x09 }, + { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_IT26, RT722_SDCA_CTL_VENDOR_DEF, 0), + 0x00 }, + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, RT722_SDCA_CTL_FU_MUTE, CH_L), + 0x01 }, + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, RT722_SDCA_CTL_FU_MUTE, CH_R), + 0x01 }, { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, RT722_SDCA_CTL_FU_VOLUME, CH_L), 0x0000 }, { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, RT722_SDCA_CTL_FU_VOLUME, CH_R), 0x0000 }, + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_PDE23, RT722_SDCA_CTL_REQ_POWER_STATE, 0), + 0x03 }, + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_CS31, RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0), + 0x09 }, + { SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_OT23, RT722_SDCA_CTL_VENDOR_DEF, 0), 0x00 }, }; #endif /* __RT722_SDW_H__ */ diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c index e17a142d03b9..f093ce841b3f 100644 --- a/sound/soc/codecs/rt722-sdca.c +++ b/sound/soc/codecs/rt722-sdca.c @@ -25,11 +25,13 @@ #include "rt722-sdca.h" +#define RT722_NID_ADDR(nid, reg) ((nid) << 20 | (reg)) + int rt722_sdca_index_write(struct rt722_sdca_priv *rt722, unsigned int nid, unsigned int reg, unsigned int value) { - struct regmap *regmap = rt722->mbq_regmap; - unsigned int addr = (nid << 20) | reg; + struct regmap *regmap = rt722->regmap; + unsigned int addr = RT722_NID_ADDR(nid, reg); int ret; ret = regmap_write(regmap, addr, value); @@ -45,8 +47,8 @@ int rt722_sdca_index_read(struct rt722_sdca_priv *rt722, unsigned int nid, unsigned int reg, unsigned int *value) { int ret; - struct regmap *regmap = rt722->mbq_regmap; - unsigned int addr = (nid << 20) | reg; + struct regmap *regmap = rt722->regmap; + unsigned int addr = RT722_NID_ADDR(nid, reg); ret = regmap_read(regmap, addr, value); if (ret < 0) @@ -361,8 +363,8 @@ static int rt722_sdca_set_gain_put(struct snd_kcontrol *kcontrol, strstr(ucontrol->id.name, "FU0F Capture Volume")) adc_vol_flag = 1; - regmap_read(rt722->mbq_regmap, mc->reg, &lvalue); - regmap_read(rt722->mbq_regmap, mc->rreg, &rvalue); + regmap_read(rt722->regmap, mc->reg, &lvalue); + regmap_read(rt722->regmap, mc->rreg, &rvalue); /* L Channel */ gain_l_val = ucontrol->value.integer.value[0]; @@ -402,13 +404,13 @@ static int rt722_sdca_set_gain_put(struct snd_kcontrol *kcontrol, return 0; /* Lch*/ - regmap_write(rt722->mbq_regmap, mc->reg, gain_l_val); + regmap_write(rt722->regmap, mc->reg, gain_l_val); /* Rch */ - regmap_write(rt722->mbq_regmap, mc->rreg, gain_r_val); + regmap_write(rt722->regmap, mc->rreg, gain_r_val); - regmap_read(rt722->mbq_regmap, mc->reg, &read_l); - regmap_read(rt722->mbq_regmap, mc->rreg, &read_r); + regmap_read(rt722->regmap, mc->reg, &read_l); + regmap_read(rt722->regmap, mc->rreg, &read_r); if (read_r == gain_r_val && read_l == gain_l_val) return changed; @@ -431,8 +433,8 @@ static int rt722_sdca_set_gain_get(struct snd_kcontrol *kcontrol, strstr(ucontrol->id.name, "FU0F Capture Volume")) adc_vol_flag = 1; - regmap_read(rt722->mbq_regmap, mc->reg, &read_l); - regmap_read(rt722->mbq_regmap, mc->rreg, &read_r); + regmap_read(rt722->regmap, mc->reg, &read_l); + regmap_read(rt722->regmap, mc->rreg, &read_r); if (mc->shift == 8) /* boost gain */ ctl_l = read_l / tendB; @@ -604,7 +606,7 @@ static int rt722_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol, /* check all channels */ for (i = 0; i < p->count; i++) { - regmap_read(rt722->mbq_regmap, p->reg_base + i, ®value); + regmap_read(rt722->regmap, p->reg_base + i, ®value); if (!adc_vol_flag) /* boost gain */ ctl = regvalue / boost_step; @@ -637,7 +639,7 @@ static int rt722_sdca_dmic_set_gain_put(struct snd_kcontrol *kcontrol, /* check all channels */ for (i = 0; i < p->count; i++) { - regmap_read(rt722->mbq_regmap, p->reg_base + i, ®value[i]); + regmap_read(rt722->regmap, p->reg_base + i, ®value[i]); gain_val[i] = ucontrol->value.integer.value[i]; if (gain_val[i] > p->max) @@ -658,7 +660,7 @@ static int rt722_sdca_dmic_set_gain_put(struct snd_kcontrol *kcontrol, return 0; for (i = 0; i < p->count; i++) { - err = regmap_write(rt722->mbq_regmap, p->reg_base + i, gain_val[i]); + err = regmap_write(rt722->regmap, p->reg_base + i, gain_val[i]); if (err < 0) dev_err(&rt722->slave->dev, "%s: %#08x can't be set\n", __func__, p->reg_base + i); @@ -739,77 +741,6 @@ static const struct snd_kcontrol_new rt722_sdca_controls[] = { 4, 3, boost_vol_tlv), }; -static int rt722_sdca_adc_mux_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component); - unsigned int val = 0, mask_sft; - - if (strstr(ucontrol->id.name, "ADC 22 Mux")) - mask_sft = 12; - else if (strstr(ucontrol->id.name, "ADC 24 Mux")) - mask_sft = 4; - else if (strstr(ucontrol->id.name, "ADC 25 Mux")) - mask_sft = 0; - else - return -EINVAL; - - rt722_sdca_index_read(rt722, RT722_VENDOR_HDA_CTL, - RT722_HDA_LEGACY_MUX_CTL0, &val); - - ucontrol->value.enumerated.item[0] = (val >> mask_sft) & 0x7; - - return 0; -} - -static int rt722_sdca_adc_mux_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = - snd_soc_dapm_kcontrol_component(kcontrol); - struct snd_soc_dapm_context *dapm = - snd_soc_dapm_kcontrol_dapm(kcontrol); - struct rt722_sdca_priv *rt722 = snd_soc_component_get_drvdata(component); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned int *item = ucontrol->value.enumerated.item; - unsigned int val, val2 = 0, change, mask_sft; - - if (item[0] >= e->items) - return -EINVAL; - - if (strstr(ucontrol->id.name, "ADC 22 Mux")) - mask_sft = 12; - else if (strstr(ucontrol->id.name, "ADC 24 Mux")) - mask_sft = 4; - else if (strstr(ucontrol->id.name, "ADC 25 Mux")) - mask_sft = 0; - else - return -EINVAL; - - val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; - - rt722_sdca_index_read(rt722, RT722_VENDOR_HDA_CTL, - RT722_HDA_LEGACY_MUX_CTL0, &val2); - val2 = (0x7 << mask_sft) & val2; - - if (val == val2) - change = 0; - else - change = 1; - - if (change) - rt722_sdca_index_update_bits(rt722, RT722_VENDOR_HDA_CTL, - RT722_HDA_LEGACY_MUX_CTL0, 0x7 << mask_sft, - val << mask_sft); - - snd_soc_dapm_mux_update_power(dapm, kcontrol, - item[0], e, NULL); - - return change; -} - static const char * const adc22_mux_text[] = { "MIC2", "LINE1", @@ -821,26 +752,26 @@ static const char * const adc07_10_mux_text[] = { "DMIC2", }; -static SOC_ENUM_SINGLE_DECL( - rt722_adc22_enum, SND_SOC_NOPM, 0, adc22_mux_text); +static SOC_ENUM_SINGLE_DECL(rt722_adc22_enum, + RT722_NID_ADDR(RT722_VENDOR_HDA_CTL, RT722_HDA_LEGACY_MUX_CTL0), + 12, adc22_mux_text); -static SOC_ENUM_SINGLE_DECL( - rt722_adc24_enum, SND_SOC_NOPM, 0, adc07_10_mux_text); +static SOC_ENUM_SINGLE_DECL(rt722_adc24_enum, + RT722_NID_ADDR(RT722_VENDOR_HDA_CTL, RT722_HDA_LEGACY_MUX_CTL0), + 4, adc07_10_mux_text); -static SOC_ENUM_SINGLE_DECL( - rt722_adc25_enum, SND_SOC_NOPM, 0, adc07_10_mux_text); +static SOC_ENUM_SINGLE_DECL(rt722_adc25_enum, + RT722_NID_ADDR(RT722_VENDOR_HDA_CTL, RT722_HDA_LEGACY_MUX_CTL0), + 0, adc07_10_mux_text); static const struct snd_kcontrol_new rt722_sdca_adc22_mux = - SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt722_adc22_enum, - rt722_sdca_adc_mux_get, rt722_sdca_adc_mux_put); + SOC_DAPM_ENUM("ADC 22 Mux", rt722_adc22_enum); static const struct snd_kcontrol_new rt722_sdca_adc24_mux = - SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt722_adc24_enum, - rt722_sdca_adc_mux_get, rt722_sdca_adc_mux_put); + SOC_DAPM_ENUM("ADC 24 Mux", rt722_adc24_enum); static const struct snd_kcontrol_new rt722_sdca_adc25_mux = - SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt722_adc25_enum, - rt722_sdca_adc_mux_get, rt722_sdca_adc_mux_put); + SOC_DAPM_ENUM("ADC 25 Mux", rt722_adc25_enum); static int rt722_sdca_fu42_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1335,8 +1266,7 @@ static struct snd_soc_dai_driver rt722_sdca_dai[] = { } }; -int rt722_sdca_init(struct device *dev, struct regmap *regmap, - struct regmap *mbq_regmap, struct sdw_slave *slave) +int rt722_sdca_init(struct device *dev, struct regmap *regmap, struct sdw_slave *slave) { struct rt722_sdca_priv *rt722; @@ -1347,7 +1277,6 @@ int rt722_sdca_init(struct device *dev, struct regmap *regmap, dev_set_drvdata(dev, rt722); rt722->slave = slave; rt722->regmap = regmap; - rt722->mbq_regmap = mbq_regmap; mutex_init(&rt722->calibrate_mutex); mutex_init(&rt722->disable_irq_lock); @@ -1521,8 +1450,6 @@ int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave) if (rt722->first_hw_init) { regcache_cache_only(rt722->regmap, false); regcache_cache_bypass(rt722->regmap, true); - regcache_cache_only(rt722->mbq_regmap, false); - regcache_cache_bypass(rt722->mbq_regmap, true); } else { /* * PM runtime is only enabled when a Slave reports as Attached @@ -1550,8 +1477,6 @@ int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave) if (rt722->first_hw_init) { regcache_cache_bypass(rt722->regmap, false); regcache_mark_dirty(rt722->regmap); - regcache_cache_bypass(rt722->mbq_regmap, false); - regcache_mark_dirty(rt722->mbq_regmap); } else rt722->first_hw_init = true; diff --git a/sound/soc/codecs/rt722-sdca.h b/sound/soc/codecs/rt722-sdca.h index 2464361a7958..04c3b4232ef3 100644 --- a/sound/soc/codecs/rt722-sdca.h +++ b/sound/soc/codecs/rt722-sdca.h @@ -17,7 +17,6 @@ struct rt722_sdca_priv { struct regmap *regmap; - struct regmap *mbq_regmap; struct snd_soc_component *component; struct sdw_slave *slave; struct sdw_bus_params params; @@ -229,8 +228,7 @@ enum rt722_sdca_jd_src { }; int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave); -int rt722_sdca_init(struct device *dev, struct regmap *regmap, - struct regmap *mbq_regmap, struct sdw_slave *slave); +int rt722_sdca_init(struct device *dev, struct regmap *regmap, struct sdw_slave *slave); int rt722_sdca_index_write(struct rt722_sdca_priv *rt722, unsigned int nid, unsigned int reg, unsigned int value); int rt722_sdca_index_read(struct rt722_sdca_priv *rt722, From 4a91fe4c0d683c56044579fb263c660f5d18efac Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 3 Feb 2025 10:53:04 +0000 Subject: [PATCH 007/651] ASoC: tegra: Add interconnect support Add interconnect framework support to set required audio bandwidth based on PCM device usage. The maximum bandwidth is determined by the number of APE PCM devices and maximum audio format supported. If interconnect property is not defined or INTERCONNECT config is not enabled then the audio usecase will still function. Validate bandwidth updates by reading the interconnect summary sysfs node during PCM device open and close operations. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250203105304.4155542-1-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/Makefile | 2 +- sound/soc/tegra/tegra210_admaif.c | 24 +++++- sound/soc/tegra/tegra210_admaif.h | 9 +- sound/soc/tegra/tegra_isomgr_bw.c | 132 ++++++++++++++++++++++++++++++ sound/soc/tegra/tegra_isomgr_bw.h | 31 +++++++ 5 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 sound/soc/tegra/tegra_isomgr_bw.c create mode 100644 sound/soc/tegra/tegra_isomgr_bw.h diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index cea4b0d54378..defea7f53f11 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -13,7 +13,7 @@ snd-soc-tegra210-dmic-y := tegra210_dmic.o snd-soc-tegra210-i2s-y := tegra210_i2s.o snd-soc-tegra186-asrc-y := tegra186_asrc.o snd-soc-tegra186-dspk-y := tegra186_dspk.o -snd-soc-tegra210-admaif-y := tegra210_admaif.o +snd-soc-tegra210-admaif-y := tegra210_admaif.o tegra_isomgr_bw.o snd-soc-tegra210-mvc-y := tegra210_mvc.o snd-soc-tegra210-sfc-y := tegra210_sfc.o snd-soc-tegra210-amx-y := tegra210_amx.o diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c index 58fdb0e79954..f56d1e03239d 100644 --- a/sound/soc/tegra/tegra210_admaif.c +++ b/sound/soc/tegra/tegra210_admaif.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -// SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES. +// SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. // All rights reserved. // // tegra210_admaif.c - Tegra ADMAIF driver @@ -13,6 +13,7 @@ #include #include #include +#include "tegra_isomgr_bw.h" #include "tegra210_admaif.h" #include "tegra_cif.h" #include "tegra_pcm.h" @@ -262,6 +263,18 @@ static int tegra_admaif_set_pack_mode(struct regmap *map, unsigned int reg, return 0; } +static int tegra_admaif_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return tegra_isomgr_adma_setbw(substream, dai, true); +} + +static void tegra_admaif_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + tegra_isomgr_adma_setbw(substream, dai, false); +} + static int tegra_admaif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -554,6 +567,8 @@ static const struct snd_soc_dai_ops tegra_admaif_dai_ops = { .probe = tegra_admaif_dai_probe, .hw_params = tegra_admaif_hw_params, .trigger = tegra_admaif_trigger, + .shutdown = tegra_admaif_shutdown, + .prepare = tegra_admaif_prepare, }; #define DAI(dai_name) \ @@ -800,6 +815,12 @@ static int tegra_admaif_probe(struct platform_device *pdev) regcache_cache_only(admaif->regmap, true); + err = tegra_isomgr_adma_register(&pdev->dev); + if (err) { + dev_err(&pdev->dev, "Failed to add interconnect path\n"); + return err; + } + regmap_update_bits(admaif->regmap, admaif->soc_data->global_base + TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1); @@ -851,6 +872,7 @@ static int tegra_admaif_probe(struct platform_device *pdev) static void tegra_admaif_remove(struct platform_device *pdev) { + tegra_isomgr_adma_unregister(&pdev->dev); pm_runtime_disable(&pdev->dev); } diff --git a/sound/soc/tegra/tegra210_admaif.h b/sound/soc/tegra/tegra210_admaif.h index 96686dc92081..748f886ee74e 100644 --- a/sound/soc/tegra/tegra210_admaif.h +++ b/sound/soc/tegra/tegra210_admaif.h @@ -1,8 +1,8 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * tegra210_admaif.h - Tegra ADMAIF registers +/* SPDX-License-Identifier: GPL-2.0-only + * SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. + * All rights reserved. * - * Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. + * tegra210_admaif.h - Tegra ADMAIF registers * */ @@ -157,6 +157,7 @@ struct tegra_admaif { unsigned int *mono_to_stereo[ADMAIF_PATHS]; unsigned int *stereo_to_mono[ADMAIF_PATHS]; struct regmap *regmap; + struct tegra_adma_isomgr *adma_isomgr; }; #endif diff --git a/sound/soc/tegra/tegra_isomgr_bw.c b/sound/soc/tegra/tegra_isomgr_bw.c new file mode 100644 index 000000000000..7789efe13873 --- /dev/null +++ b/sound/soc/tegra/tegra_isomgr_bw.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. +// All rights reserved. +// +// ADMA bandwidth calculation + +#include +#include +#include +#include +#include "tegra_isomgr_bw.h" +#include "tegra210_admaif.h" + +/* Max possible rate is 192KHz x 16channel x 4bytes */ +#define MAX_BW_PER_DEV 12288 + +int tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai, bool is_running) +{ + struct device *dev = dai->dev; + struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); + struct tegra_adma_isomgr *adma_isomgr = admaif->adma_isomgr; + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_pcm *pcm = substream->pcm; + u32 type = substream->stream, bandwidth = 0; + int sample_bytes; + + if (!adma_isomgr) + return 0; + + if (!runtime || !pcm) + return -EINVAL; + + if (pcm->device >= adma_isomgr->max_pcm_device) { + dev_err(dev, "%s: PCM device number %d is greater than %d\n", __func__, + pcm->device, adma_isomgr->max_pcm_device); + return -EINVAL; + } + + /* + * No action if stream is running and bandwidth is already set or + * stream is not running and bandwidth is already reset + */ + if ((adma_isomgr->bw_per_dev[type][pcm->device] && is_running) || + (!adma_isomgr->bw_per_dev[type][pcm->device] && !is_running)) + return 0; + + if (is_running) { + sample_bytes = snd_pcm_format_width(runtime->format) / 8; + if (sample_bytes < 0) + return sample_bytes; + + /* KB/s kilo bytes per sec */ + bandwidth = runtime->channels * (runtime->rate / 1000) * + sample_bytes; + } + + mutex_lock(&adma_isomgr->mutex); + + if (is_running) { + if (bandwidth + adma_isomgr->current_bandwidth > adma_isomgr->max_bw) + bandwidth = adma_isomgr->max_bw - adma_isomgr->current_bandwidth; + + adma_isomgr->current_bandwidth += bandwidth; + } else { + adma_isomgr->current_bandwidth -= adma_isomgr->bw_per_dev[type][pcm->device]; + } + + mutex_unlock(&adma_isomgr->mutex); + + adma_isomgr->bw_per_dev[type][pcm->device] = bandwidth; + + dev_dbg(dev, "Setting up bandwidth to %d KBps\n", adma_isomgr->current_bandwidth); + + 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) +{ + struct tegra_admaif *admaif = dev_get_drvdata(dev); + struct tegra_adma_isomgr *adma_isomgr; + int i; + + adma_isomgr = devm_kzalloc(dev, sizeof(struct tegra_adma_isomgr), GFP_KERNEL); + if (!adma_isomgr) + return -ENOMEM; + + adma_isomgr->icc_path_handle = devm_of_icc_get(dev, "write"); + if (IS_ERR(adma_isomgr->icc_path_handle)) + return dev_err_probe(dev, PTR_ERR(adma_isomgr->icc_path_handle), + "failed to acquire interconnect path\n"); + + /* Either INTERCONNECT config OR interconnect property is not defined */ + if (!adma_isomgr->icc_path_handle) { + devm_kfree(dev, adma_isomgr); + return 0; + } + + adma_isomgr->max_pcm_device = admaif->soc_data->num_ch; + adma_isomgr->max_bw = STREAM_TYPE * MAX_BW_PER_DEV * adma_isomgr->max_pcm_device; + + for (i = 0; i < STREAM_TYPE; i++) { + adma_isomgr->bw_per_dev[i] = devm_kzalloc(dev, adma_isomgr->max_pcm_device * + sizeof(u32), GFP_KERNEL); + if (!adma_isomgr->bw_per_dev[i]) + return -ENOMEM; + } + + adma_isomgr->current_bandwidth = 0; + mutex_init(&adma_isomgr->mutex); + admaif->adma_isomgr = adma_isomgr; + + return 0; +} +EXPORT_SYMBOL(tegra_isomgr_adma_register); + +void tegra_isomgr_adma_unregister(struct device *dev) +{ + struct tegra_admaif *admaif = dev_get_drvdata(dev); + + if (!admaif->adma_isomgr) + return; + + mutex_destroy(&admaif->adma_isomgr->mutex); +} +EXPORT_SYMBOL(tegra_isomgr_adma_unregister); + +MODULE_AUTHOR("Mohan Kumar "); +MODULE_DESCRIPTION("Tegra ADMA Bandwidth Request driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra/tegra_isomgr_bw.h b/sound/soc/tegra/tegra_isomgr_bw.h new file mode 100644 index 000000000000..86db3cfd4e43 --- /dev/null +++ b/sound/soc/tegra/tegra_isomgr_bw.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. + * All rights reserved. + * + * tegra_isomgr_bw.h - Definitions for ADMA bandwidth calculation + * + */ + +#ifndef __TEGRA_ISOMGR_BW_H__ +#define __TEGRA_ISOMGR_BW_H__ + +/* Playback and Capture streams */ +#define STREAM_TYPE 2 + +struct tegra_adma_isomgr { + /* Protect pcm devices bandwidth */ + struct mutex mutex; + /* interconnect path handle */ + struct icc_path *icc_path_handle; + u32 *bw_per_dev[STREAM_TYPE]; + u32 current_bandwidth; + u32 max_pcm_device; + u32 max_bw; +}; + +int tegra_isomgr_adma_register(struct device *dev); +void tegra_isomgr_adma_unregister(struct device *dev); +int tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai, bool is_running); + +#endif From a05143a8f713d9ae6abc41141dac52c66fca8b06 Mon Sep 17 00:00:00 2001 From: Zhang Heng Date: Fri, 17 Jan 2025 09:43:43 +0800 Subject: [PATCH 008/651] ASoC: SOF: topology: Use krealloc_array() to replace krealloc() Use krealloc_array() to replace krealloc() with multiplication. krealloc_array() has multiply overflow check, which will be safer. Signed-off-by: Zhang Heng Link: https://patch.msgid.link/20250117014343.451503-1-zhangheng@kylinos.cn Signed-off-by: Mark Brown --- sound/soc/sof/topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 688cc7ac1714..dc9cb8324067 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1273,8 +1273,8 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s struct snd_sof_tuple *new_tuples; num_tuples += token_list[object_token_list[i]].count * (num_sets - 1); - new_tuples = krealloc(swidget->tuples, - sizeof(*new_tuples) * num_tuples, GFP_KERNEL); + new_tuples = krealloc_array(swidget->tuples, + num_tuples, sizeof(*new_tuples), GFP_KERNEL); if (!new_tuples) { ret = -ENOMEM; goto err; From fb6ec1d27608c008bfe1ab0dfec3720990eb2451 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Tue, 28 Jan 2025 00:52:43 +0000 Subject: [PATCH 009/651] ASoC: mediatek: mt6358: Remove unused functions The functions: mt6358_mtkaif_calibration_disable() mt6358_mtkaif_calibration_enable() mt6358_set_mtkaif_calibration_phase() were added in the 2019 commit 6a8d4198ca80 ("ASoC: mediatek: mt6358: add codec driver") but never used. Remove them. This leaves mt6358_set_dcxo(), mt6358_set_clksq(), mt6358_set_aud_global_bias(), also unused. Remove them. Signed-off-by: Dr. David Alan Gilbert Link: https://patch.msgid.link/20250128005243.295977-1-linux@treblig.org Signed-off-by: Mark Brown --- sound/soc/codecs/mt6358.c | 104 -------------------------------------- sound/soc/codecs/mt6358.h | 4 -- 2 files changed, 108 deletions(-) diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index 9247b90d1b99..e033027fd4c7 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -162,47 +162,6 @@ static void capture_gpio_reset(struct mt6358_priv *priv) 0xf << 12, 0x0); } -/* use only when not govern by DAPM */ -static int mt6358_set_dcxo(struct mt6358_priv *priv, bool enable) -{ - regmap_update_bits(priv->regmap, MT6358_DCXO_CW14, - 0x1 << RG_XO_AUDIO_EN_M_SFT, - (enable ? 1 : 0) << RG_XO_AUDIO_EN_M_SFT); - return 0; -} - -/* use only when not govern by DAPM */ -static int mt6358_set_clksq(struct mt6358_priv *priv, bool enable) -{ - /* audio clk source from internal dcxo */ - regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON6, - RG_CLKSQ_IN_SEL_TEST_MASK_SFT, - 0x0); - - /* Enable/disable CLKSQ 26MHz */ - regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON6, - RG_CLKSQ_EN_MASK_SFT, - (enable ? 1 : 0) << RG_CLKSQ_EN_SFT); - return 0; -} - -/* use only when not govern by DAPM */ -static int mt6358_set_aud_global_bias(struct mt6358_priv *priv, bool enable) -{ - regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13, - RG_AUDGLB_PWRDN_VA28_MASK_SFT, - (enable ? 0 : 1) << RG_AUDGLB_PWRDN_VA28_SFT); - return 0; -} - -/* use only when not govern by DAPM */ -static int mt6358_set_topck(struct mt6358_priv *priv, bool enable) -{ - regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0, - 0x0066, enable ? 0x0 : 0x66); - return 0; -} - static int mt6358_mtkaif_tx_enable(struct mt6358_priv *priv) { switch (priv->mtkaif_protocol) { @@ -252,69 +211,6 @@ static int mt6358_mtkaif_tx_disable(struct mt6358_priv *priv) return 0; } -int mt6358_mtkaif_calibration_enable(struct snd_soc_component *cmpnt) -{ - struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - - playback_gpio_set(priv); - capture_gpio_set(priv); - mt6358_mtkaif_tx_enable(priv); - - mt6358_set_dcxo(priv, true); - mt6358_set_aud_global_bias(priv, true); - mt6358_set_clksq(priv, true); - mt6358_set_topck(priv, true); - - /* set dat_miso_loopback on */ - regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG, - RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT, - 1 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT); - regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG, - RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT, - 1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT); - return 0; -} -EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_enable); - -int mt6358_mtkaif_calibration_disable(struct snd_soc_component *cmpnt) -{ - struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - - /* set dat_miso_loopback off */ - regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG, - RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT, - 0 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT); - regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG, - RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT, - 0 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT); - - mt6358_set_topck(priv, false); - mt6358_set_clksq(priv, false); - mt6358_set_aud_global_bias(priv, false); - mt6358_set_dcxo(priv, false); - - mt6358_mtkaif_tx_disable(priv); - playback_gpio_reset(priv); - capture_gpio_reset(priv); - return 0; -} -EXPORT_SYMBOL_GPL(mt6358_mtkaif_calibration_disable); - -int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt, - int phase_1, int phase_2) -{ - struct mt6358_priv *priv = snd_soc_component_get_drvdata(cmpnt); - - regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG, - RG_AUD_PAD_TOP_PHASE_MODE_MASK_SFT, - phase_1 << RG_AUD_PAD_TOP_PHASE_MODE_SFT); - regmap_update_bits(priv->regmap, MT6358_AUDIO_DIG_CFG, - RG_AUD_PAD_TOP_PHASE_MODE2_MASK_SFT, - phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT); - return 0; -} -EXPORT_SYMBOL_GPL(mt6358_set_mtkaif_calibration_phase); - /* dl pga gain */ enum { DL_GAIN_8DB = 0, diff --git a/sound/soc/codecs/mt6358.h b/sound/soc/codecs/mt6358.h index a5953315eaa2..b729c3899b7e 100644 --- a/sound/soc/codecs/mt6358.h +++ b/sound/soc/codecs/mt6358.h @@ -2307,8 +2307,4 @@ enum { /* set only during init */ int mt6358_set_mtkaif_protocol(struct snd_soc_component *cmpnt, int mtkaif_protocol); -int mt6358_mtkaif_calibration_enable(struct snd_soc_component *cmpnt); -int mt6358_mtkaif_calibration_disable(struct snd_soc_component *cmpnt); -int mt6358_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt, - int phase_1, int phase_2); #endif /* __MT6358_H__ */ From 1a4a5a752fcd60797ed2cb7c06253c6433d13f63 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 3 Feb 2025 06:04:40 +0000 Subject: [PATCH 010/651] ASoC: soc-ops: remove soc-dpcm.h soc-ops is not using soc-dpcm.h. Remove it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/874j1bsgw7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 19928f098d8d..c6601ef16f84 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -24,7 +24,6 @@ #include #include #include -#include #include /** From 6eab7034579917f207ca6d8e3f4e11e85e0ab7d5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Jan 2025 09:21:27 +0100 Subject: [PATCH 011/651] ASoC: soc-core: Stop using of_property_read_bool() for non-boolean properties On R-Car: OF: /sound: Read of boolean property 'simple-audio-card,bitclock-master' with a value. OF: /sound: Read of boolean property 'simple-audio-card,frame-master' with a value. or: OF: /soc/sound@ec500000/ports/port@0/endpoint: Read of boolean property 'bitclock-master' with a value. OF: /soc/sound@ec500000/ports/port@0/endpoint: Read of boolean property 'frame-master' with a value. The use of of_property_read_bool() for non-boolean properties is deprecated in favor of of_property_present() when testing for property presence. Replace testing for presence before calling of_property_read_u32() by testing for an -EINVAL return value from the latter, to simplify the code. Signed-off-by: Geert Uytterhoeven Link: https://patch.msgid.link/db10e96fbda121e7456d70e97a013cbfc9755f4d.1737533954.git.geert+renesas@glider.be Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 3c6d8aef4130..26b34b688508 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3046,7 +3046,7 @@ int snd_soc_of_parse_pin_switches(struct snd_soc_card *card, const char *prop) unsigned int i, nb_controls; int ret; - if (!of_property_read_bool(dev->of_node, prop)) + if (!of_property_present(dev->of_node, prop)) return 0; strings = devm_kcalloc(dev, nb_controls_max, @@ -3120,23 +3120,17 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, if (rx_mask) snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask); - if (of_property_read_bool(np, "dai-tdm-slot-num")) { - ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); - if (ret) - return ret; + ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); + if (ret && ret != -EINVAL) + return ret; + if (!ret && slots) + *slots = val; - if (slots) - *slots = val; - } - - if (of_property_read_bool(np, "dai-tdm-slot-width")) { - ret = of_property_read_u32(np, "dai-tdm-slot-width", &val); - if (ret) - return ret; - - if (slot_width) - *slot_width = val; - } + ret = of_property_read_u32(np, "dai-tdm-slot-width", &val); + if (ret && ret != -EINVAL) + return ret; + if (!ret && slot_width) + *slot_width = val; return 0; } @@ -3403,12 +3397,12 @@ unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np, * check "[prefix]frame-master" */ snprintf(prop, sizeof(prop), "%sbitclock-master", prefix); - bit = of_property_read_bool(np, prop); + bit = of_property_present(np, prop); if (bit && bitclkmaster) *bitclkmaster = of_parse_phandle(np, prop, 0); snprintf(prop, sizeof(prop), "%sframe-master", prefix); - frame = of_property_read_bool(np, prop); + frame = of_property_present(np, prop); if (frame && framemaster) *framemaster = of_parse_phandle(np, prop, 0); From dc561ab16d8be9cbe8f07a49a7b2f5428fbcfeea Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:41 +0100 Subject: [PATCH 012/651] ASoC: codecs: pcm3168a: Add ACPI match table Support ACPI-based systems by adding relevant match table. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a-i2c.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/pcm3168a-i2c.c b/sound/soc/codecs/pcm3168a-i2c.c index 7052cc0c97d1..4da608ba514d 100644 --- a/sound/soc/codecs/pcm3168a-i2c.c +++ b/sound/soc/codecs/pcm3168a-i2c.c @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -37,6 +38,13 @@ static const struct i2c_device_id pcm3168a_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, pcm3168a_i2c_id); +static const struct acpi_device_id pcm3168a_acpi_match[] = { + { "PCM3168A" }, + { "104C3168" }, + {} +}; +MODULE_DEVICE_TABLE(acpi, pcm3168a_acpi_match); + static const struct of_device_id pcm3168a_of_match[] = { { .compatible = "ti,pcm3168a", }, { } @@ -49,6 +57,7 @@ static struct i2c_driver pcm3168a_i2c_driver = { .id_table = pcm3168a_i2c_id, .driver = { .name = "pcm3168a", + .acpi_match_table = pcm3168a_acpi_match, .of_match_table = pcm3168a_of_match, .pm = &pcm3168a_pm_ops, }, From e92f042642aed6f6206caace892d9df2d0166841 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:42 +0100 Subject: [PATCH 013/651] ASoC: codecs: pcm3168a: Relax probing conditions On ACPI-based systems with Intel MalibouLake there is no "scki" clock entry defined. Make that initialization part optional and default to 24.576 MHz rate if not set. The rate is the default for both TI and Intel devices. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index fac0617ab95b..43c0cb5e538e 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -743,7 +743,7 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap) return dev_err_probe(dev, PTR_ERR(pcm3168a->gpio_rst), "failed to acquire RST gpio\n"); - pcm3168a->scki = devm_clk_get(dev, "scki"); + pcm3168a->scki = devm_clk_get_optional(dev, "scki"); if (IS_ERR(pcm3168a->scki)) return dev_err_probe(dev, PTR_ERR(pcm3168a->scki), "failed to acquire clock 'scki'\n"); @@ -755,6 +755,9 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap) } pcm3168a->sysclk = clk_get_rate(pcm3168a->scki); + /* Fallback to the default if no clk entry available. */ + if (!pcm3168a->sysclk) + pcm3168a->sysclk = 24576000; for (i = 0; i < ARRAY_SIZE(pcm3168a->supplies); i++) pcm3168a->supplies[i].supply = pcm3168a_supply_names[i]; From 7d92a38d67e5d937b64b20aa4fd14451ee1772f3 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:43 +0100 Subject: [PATCH 014/651] ASoC: codecs: pcm3168a: Allow for 24-bit in provider mode As per codec device specification, 24-bit is allowed in provider mode. Update the code to reflect that. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 43c0cb5e538e..df6836a652ef 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -493,9 +493,9 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, } break; case 24: - if (provider_mode || (format == SND_SOC_DAIFMT_DSP_A) || - (format == SND_SOC_DAIFMT_DSP_B)) { - dev_err(component->dev, "24-bit slots not supported in provider mode, or consumer mode using DSP\n"); + if (!provider_mode && ((format == SND_SOC_DAIFMT_DSP_A) || + (format == SND_SOC_DAIFMT_DSP_B))) { + dev_err(component->dev, "24-bit slots not supported in consumer mode using DSP\n"); return -EINVAL; } break; From 79ebb596201c86712fe38b0ef73d25d07b932664 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:44 +0100 Subject: [PATCH 015/651] ASoC: Intel: avs: Add pcm3168a machine board To support AVS-pcm3168a configuration add machine board connecting AVS platform component driver with pcm3168a codec one. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 ++ sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/pcm3168a.c | 143 ++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 sound/soc/intel/avs/boards/pcm3168a.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 00b0f6c176d6..ba4bee42124c 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -87,6 +87,16 @@ config SND_SOC_INTEL_AVS_MACH_NAU8825 Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_PCM3168A + tristate "pcm3168a I2S board" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_PCM3168A_I2C + help + This adds support for AVS with PCM3168A I2C codec configuration. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_PROBE tristate "Probing (data) board" depends on DEBUG_FS diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 4fbd936ffb3e..a95256b94dc8 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -9,6 +9,7 @@ snd-soc-avs-max98927-y := max98927.o snd-soc-avs-max98357a-y := max98357a.o snd-soc-avs-max98373-y := max98373.o snd-soc-avs-nau8825-y := nau8825.o +snd-soc-avs-pcm3168a-y := pcm3168a.o snd-soc-avs-probe-y := probe.o snd-soc-avs-rt274-y := rt274.o snd-soc-avs-rt286-y := rt286.o @@ -27,6 +28,7 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927) += snd-soc-avs-max98927.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373) += snd-soc-avs-max98373.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_PCM3168A) += snd-soc-avs-pcm3168a.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE) += snd-soc-avs-probe.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o diff --git a/sound/soc/intel/avs/boards/pcm3168a.c b/sound/soc/intel/avs/boards/pcm3168a.c new file mode 100644 index 000000000000..5d0e7a5bdc74 --- /dev/null +++ b/sound/soc/intel/avs/boards/pcm3168a.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2024-2025 Intel Corporation +// +// Author: Cezary Rojewski +// + +#include +#include +#include +#include +#include +#include + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_HP("CPB Stereo HP 1", NULL), + SND_SOC_DAPM_HP("CPB Stereo HP 2", NULL), + SND_SOC_DAPM_HP("CPB Stereo HP 3", NULL), + SND_SOC_DAPM_LINE("CPB Line Out", NULL), + SND_SOC_DAPM_MIC("CPB Stereo Mic 1", NULL), + SND_SOC_DAPM_MIC("CPB Stereo Mic 2", NULL), + SND_SOC_DAPM_LINE("CPB Line In", NULL), +}; + +static const struct snd_soc_dapm_route card_routes[] = { + { "CPB Stereo HP 1", NULL, "AOUT1L" }, + { "CPB Stereo HP 1", NULL, "AOUT1R" }, + { "CPB Stereo HP 2", NULL, "AOUT2L" }, + { "CPB Stereo HP 2", NULL, "AOUT2R" }, + { "CPB Stereo HP 3", NULL, "AOUT3L" }, + { "CPB Stereo HP 3", NULL, "AOUT3R" }, + { "CPB Line Out", NULL, "AOUT4L" }, + { "CPB Line Out", NULL, "AOUT4R" }, + + { "AIN1L", NULL, "CPB Stereo Mic 1" }, + { "AIN1R", NULL, "CPB Stereo Mic 1" }, + { "AIN2L", NULL, "CPB Stereo Mic 2" }, + { "AIN2R", NULL, "CPB Stereo Mic 2" }, + { "AIN3L", NULL, "CPB Line In" }, + { "AIN3R", NULL, "CPB Line In" }, +}; + +static int avs_pcm3168a_be_fixup(struct snd_soc_pcm_runtime *runtime, + struct snd_pcm_hw_params *params) +{ + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* Set SSP to 24 bit. */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +SND_SOC_DAILINK_DEF(pcm3168a_dac, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-PCM3168A:00", "pcm3168a-dac"))); +SND_SOC_DAILINK_DEF(pcm3168a_adc, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-PCM3168A:00", "pcm3168a-adc"))); +SND_SOC_DAILINK_DEF(cpu_ssp0, DAILINK_COMP_ARRAY(COMP_CPU("SSP0 Pin"))); +SND_SOC_DAILINK_DEF(cpu_ssp2, DAILINK_COMP_ARRAY(COMP_CPU("SSP2 Pin"))); + +static int avs_create_dai_links(struct device *dev, struct snd_soc_dai_link **links, int *num_links) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + const int num_dl = 2; + + dl = devm_kcalloc(dev, num_dl, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = dev_name(dev); + dl[0].num_cpus = 1; + dl[0].num_codecs = 1; + dl[0].platforms = platform; + dl[0].num_platforms = 1; + dl[0].dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; + dl[0].be_hw_params_fixup = avs_pcm3168a_be_fixup; + dl[0].nonatomic = 1; + dl[0].no_pcm = 1; + memcpy(&dl[1], &dl[0], sizeof(*dl)); + + dl[0].name = "SSP0-Codec-dac"; + dl[0].cpus = cpu_ssp0; + dl[0].codecs = pcm3168a_dac; + dl[1].name = "SSP2-Codec-adc"; + dl[1].cpus = cpu_ssp2; + dl[1].codecs = pcm3168a_adc; + + *links = dl; + *num_links = num_dl; + return 0; +} + +static int avs_pcm3168a_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct snd_soc_card *card; + int ret; + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + ret = avs_create_dai_links(dev, &card->dai_link, &card->num_links); + if (ret) + return ret; + + card->name = "avs_pcm3168a"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = card_routes; + card->num_dapm_routes = ARRAY_SIZE(card_routes); + card->fully_routed = true; + + return devm_snd_soc_register_card(dev, card); +} + +static const struct platform_device_id avs_pcm3168a_driver_ids[] = { + { + .name = "avs_pcm3168a", + }, + {}, +}; +MODULE_DEVICE_TABLE(platform, avs_pcm3168a_driver_ids); + +static struct platform_driver avs_pcm3168a_driver = { + .probe = avs_pcm3168a_probe, + .driver = { + .name = "avs_pcm3168a", + .pm = &snd_soc_pm_ops, + }, + .id_table = avs_pcm3168a_driver_ids, +}; + +module_platform_driver(avs_pcm3168a_driver); + +MODULE_DESCRIPTION("Intel pcm3168a machine driver"); +MODULE_AUTHOR("Cezary Rojewski "); +MODULE_LICENSE("GPL"); From b9fb91692af881736f8fa1741fa0dbadf07d99ee Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:45 +0100 Subject: [PATCH 016/651] ASoC: Intel: avs: pcm3168a board selection Populate board table with avs_pcm3168a machine driver for RPL-M-based and ADL-N-based platforms with pcm3168a codec onboard to allow the sound card to enumerate. While at it, drop comma the terminator entries to align with the coding standard. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/board_selection.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index 0266edeafc19..2d706edcbf92 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -312,6 +312,18 @@ static struct snd_soc_acpi_mach avs_tgl_i2s_machines[] = { {}, }; +static struct snd_soc_acpi_mach avs_mbl_i2s_machines[] = { + { + .id = "PCM3168A", + .drv_name = "avs_pcm3168a", + .mach_params = { + .i2s_link_mask = AVS_SSP(0) | AVS_SSP(2), + }, + .tplg_filename = "pcm3168a-tplg.bin", + }, + {} +}; + static struct snd_soc_acpi_mach avs_test_i2s_machines[] = { { .drv_name = "avs_i2s_test", @@ -378,10 +390,11 @@ static const struct avs_acpi_boards i2s_boards[] = { AVS_MACH_ENTRY(HDA_ICL_LP, avs_icl_i2s_machines), AVS_MACH_ENTRY(HDA_TGL_LP, avs_tgl_i2s_machines), AVS_MACH_ENTRY(HDA_EHL_0, avs_tgl_i2s_machines), + AVS_MACH_ENTRY(HDA_ADL_N, avs_mbl_i2s_machines), AVS_MACH_ENTRY(HDA_ADL_P, avs_tgl_i2s_machines), AVS_MACH_ENTRY(HDA_RPL_P_0, avs_tgl_i2s_machines), - AVS_MACH_ENTRY(HDA_RPL_M, avs_tgl_i2s_machines), - {}, + AVS_MACH_ENTRY(HDA_RPL_M, avs_mbl_i2s_machines), + {} }; static const struct avs_acpi_boards *avs_get_i2s_boards(struct avs_dev *adev) From e995c51903384be1c7aead246dc30cb5244179ac Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:46 +0100 Subject: [PATCH 017/651] ASoC: Intel: avs: Move DSP-boot steps into individual functions To make DSP-boot code more readable, move each logical step into an individual function and add the configure step which will be utilized by follow up changes. To summarize, the steps are: loading the firmware code, configuring the base firmware and, allocating driver resources based on FW and HW capabilities. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/avs.h | 1 + sound/soc/intel/avs/loader.c | 74 +++++++++++++++++++++++++----------- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index eca6ec0428bb..585543f872fc 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -51,6 +51,7 @@ struct avs_dsp_ops { int (* const load_basefw)(struct avs_dev *, struct firmware *); int (* const load_lib)(struct avs_dev *, struct firmware *, u32); int (* const transfer_mods)(struct avs_dev *, bool, struct avs_module_entry *, u32); + int (* const config_basefw)(struct avs_dev *); int (* const enable_logs)(struct avs_dev *, enum avs_log_enable, u32, u32, unsigned long, u32 *); int (* const log_buffer_offset)(struct avs_dev *, u32); diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c index 9ff7818395cd..0b29941feb0e 100644 --- a/sound/soc/intel/avs/loader.c +++ b/sound/soc/intel/avs/loader.c @@ -603,7 +603,7 @@ release_fw: return ret; } -int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge) +static int avs_load_firmware(struct avs_dev *adev, bool purge) { struct avs_soc_component *acomp; int ret, i; @@ -657,29 +657,34 @@ reenable_gating: return 0; } -int avs_dsp_first_boot_firmware(struct avs_dev *adev) +static int avs_config_basefw(struct avs_dev *adev) +{ + int ret; + + if (adev->spec->dsp_ops->config_basefw) { + ret = avs_dsp_op(adev, config_basefw); + if (ret) + return ret; + } + + return 0; +} + +int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge) +{ + int ret; + + ret = avs_load_firmware(adev, purge); + if (ret) + return ret; + + return avs_config_basefw(adev); +} + +static int avs_dsp_alloc_resources(struct avs_dev *adev) { int ret, i; - if (avs_platattr_test(adev, CLDMA)) { - ret = hda_cldma_init(&code_loader, &adev->base.core, - adev->dsp_ba, AVS_CL_DEFAULT_BUFFER_SIZE); - if (ret < 0) { - dev_err(adev->dev, "cldma init failed: %d\n", ret); - return ret; - } - } - - ret = avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); - if (ret < 0) - return ret; - - ret = avs_dsp_boot_firmware(adev, true); - if (ret < 0) { - dev_err(adev->dev, "firmware boot failed: %d\n", ret); - return ret; - } - ret = avs_ipc_get_hw_config(adev, &adev->hw_cfg); if (ret) return AVS_IPC_RET(ret); @@ -705,6 +710,31 @@ int avs_dsp_first_boot_firmware(struct avs_dev *adev) strscpy(adev->lib_names[0], "BASEFW", AVS_LIB_NAME_SIZE); ida_init(&adev->ppl_ida); - return 0; } + +int avs_dsp_first_boot_firmware(struct avs_dev *adev) +{ + int ret; + + if (avs_platattr_test(adev, CLDMA)) { + ret = hda_cldma_init(&code_loader, &adev->base.core, + adev->dsp_ba, AVS_CL_DEFAULT_BUFFER_SIZE); + if (ret < 0) { + dev_err(adev->dev, "cldma init failed: %d\n", ret); + return ret; + } + } + + ret = avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); + if (ret < 0) + return ret; + + ret = avs_dsp_boot_firmware(adev, true); + if (ret < 0) { + dev_err(adev->dev, "firmware boot failed: %d\n", ret); + return ret; + } + + return avs_dsp_alloc_resources(adev); +} From cbe37a4d2b3c25d2e2a94097e09b6d87461b8833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Mon, 3 Feb 2025 15:10:47 +0100 Subject: [PATCH 018/651] ASoC: Intel: avs: Configure basefw on TGL-based platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AudioDSP firmware requires additional information about the configuration on selected devices. That information is unaccessible from the DSP side and shall be sent before any streaming starts. To achieve the goal, introduce FW_CONFIG_SET request. FW_CONFIG_SET message allows driver to modify firmware's configuration. Multiple parameters can be modified at once, thanks to payload being an array of TLVs. Signed-off-by: Amadeusz SÅ‚awiÅ„ski Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/messages.c | 38 ++++++++++++++++++++++++++++++++++ sound/soc/intel/avs/messages.h | 9 ++++++++ sound/soc/intel/avs/tgl.c | 33 +++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index 30b666f8909b..242a175381c2 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -510,6 +510,44 @@ err: return ret; } +int avs_ipc_set_fw_config(struct avs_dev *adev, size_t num_tlvs, ...) +{ + struct avs_tlv *tlv; + void *payload; + size_t offset; + va_list args; + int ret, i; + + payload = kzalloc(AVS_MAILBOX_SIZE, GFP_KERNEL); + if (!payload) + return -ENOMEM; + + va_start(args, num_tlvs); + for (offset = i = 0; i < num_tlvs && offset < AVS_MAILBOX_SIZE - sizeof(*tlv); i++) { + tlv = (struct avs_tlv *)(payload + offset); + tlv->type = va_arg(args, u32); + tlv->length = va_arg(args, u32); + + offset += sizeof(*tlv) + tlv->length; + if (offset > AVS_MAILBOX_SIZE) + break; + + memcpy(tlv->value, va_arg(args, u8*), tlv->length); + } + + if (i == num_tlvs) + ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, + AVS_BASEFW_FIRMWARE_CONFIG, payload, offset); + else + ret = -ERANGE; + + va_end(args); + kfree(payload); + if (ret) + dev_err(adev->dev, "set fw cfg failed: %d\n", ret); + return ret; +} + int avs_ipc_get_hw_config(struct avs_dev *adev, struct avs_hw_cfg *cfg) { struct avs_tlv *tlv; diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h index 0378633c7f96..84b0d4b69ecb 100644 --- a/sound/soc/intel/avs/messages.h +++ b/sound/soc/intel/avs/messages.h @@ -451,6 +451,8 @@ enum avs_fw_cfg_params { AVS_FW_CFG_RESERVED, AVS_FW_CFG_POWER_GATING_POLICY, AVS_FW_CFG_ASSERT_MODE, + AVS_FW_CFG_RESERVED2, + AVS_FW_CFG_BUS_HARDWARE_ID, }; struct avs_fw_cfg { @@ -475,7 +477,14 @@ struct avs_fw_cfg { u32 power_gating_policy; }; +struct avs_bus_hwid { + u32 device; + u32 subsystem; + u8 revision; +}; + int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg); +int avs_ipc_set_fw_config(struct avs_dev *adev, size_t num_tlvs, ...); enum avs_hw_cfg_params { AVS_HW_CFG_AVS_VER, diff --git a/sound/soc/intel/avs/tgl.c b/sound/soc/intel/avs/tgl.c index a9019ff5e3af..56905f2b9eb2 100644 --- a/sound/soc/intel/avs/tgl.c +++ b/sound/soc/intel/avs/tgl.c @@ -6,7 +6,11 @@ // Amadeusz Slawinski // +#include #include "avs.h" +#include "messages.h" + +#define CPUID_TSC_LEAF 0x15 static int avs_tgl_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power) { @@ -35,6 +39,34 @@ static int avs_tgl_dsp_core_stall(struct avs_dev *adev, u32 core_mask, bool stal return avs_dsp_core_stall(adev, core_mask, stall); } +static int avs_tgl_config_basefw(struct avs_dev *adev) +{ + struct pci_dev *pci = adev->base.pci; + struct avs_bus_hwid hwid; + int ret; +#ifdef CONFIG_X86 + unsigned int ecx; + +#include + ecx = cpuid_ecx(CPUID_TSC_LEAF); + if (ecx) { + ret = avs_ipc_set_fw_config(adev, 1, AVS_FW_CFG_XTAL_FREQ_HZ, sizeof(ecx), &ecx); + if (ret) + return AVS_IPC_RET(ret); + } +#endif + + hwid.device = pci->device; + hwid.subsystem = pci->subsystem_vendor | (pci->subsystem_device << 16); + hwid.revision = pci->revision; + + ret = avs_ipc_set_fw_config(adev, 1, AVS_FW_CFG_BUS_HARDWARE_ID, sizeof(hwid), &hwid); + if (ret) + return AVS_IPC_RET(ret); + + return 0; +} + const struct avs_dsp_ops avs_tgl_dsp_ops = { .power = avs_tgl_dsp_core_power, .reset = avs_tgl_dsp_core_reset, @@ -44,6 +76,7 @@ const struct avs_dsp_ops avs_tgl_dsp_ops = { .load_basefw = avs_icl_load_basefw, .load_lib = avs_hda_load_library, .transfer_mods = avs_hda_transfer_modules, + .config_basefw = avs_tgl_config_basefw, .log_buffer_offset = avs_icl_log_buffer_offset, .log_buffer_status = avs_apl_log_buffer_status, .coredump = avs_apl_coredump, From f0173cbe7fa79eafbdf32eed32337209f84ddacd Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:48 +0100 Subject: [PATCH 019/651] ASoC: Intel: avs: New gateway configuration mechanism Creation of a module which contains gateway configuration consists of few additional steps, namely: - assigning ID (node_id) for the gateway - attaching hardware configuration from the NHLT table (optional) By splitting the steps into separate functions code becomes easier to read and understand. Any redundancy created by this patch will be addressed by follow up changes. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/path.c | 150 +++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index f31d5e2caa7b..698a3d542244 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -115,6 +115,156 @@ avs_path_find_variant(struct avs_dev *adev, return NULL; } +static void avs_init_node_id(union avs_connector_node_id *node_id, + struct avs_tplg_modcfg_ext *te, u32 dma_id) +{ + node_id->val = 0; + node_id->dma_type = te->copier.dma_type; + + switch (node_id->dma_type) { + case AVS_DMA_DMIC_LINK_INPUT: + case AVS_DMA_I2S_LINK_OUTPUT: + case AVS_DMA_I2S_LINK_INPUT: + /* Gateway's virtual index is statically assigned in the topology. */ + node_id->vindex = te->copier.vindex.val; + break; + + case AVS_DMA_HDA_HOST_OUTPUT: + case AVS_DMA_HDA_HOST_INPUT: + /* Gateway's virtual index is dynamically assigned with DMA ID */ + node_id->vindex = dma_id; + break; + + case AVS_DMA_HDA_LINK_OUTPUT: + case AVS_DMA_HDA_LINK_INPUT: + node_id->vindex = te->copier.vindex.val | dma_id; + break; + + default: + *node_id = INVALID_NODE_ID; + break; + } +} + +/* Every BLOB contains at least gateway attributes. */ +static struct acpi_nhlt_config *default_blob = (struct acpi_nhlt_config *)&(u32[2]) {4}; + +static struct acpi_nhlt_config * +avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t) +{ + struct acpi_nhlt_format_config *fmtcfg; + struct avs_tplg_modcfg_ext *te; + struct avs_audio_format *fmt; + int link_type, dev_type; + int bus_id, dir; + + te = t->cfg_ext; + + switch (te->copier.dma_type) { + case AVS_DMA_I2S_LINK_OUTPUT: + link_type = ACPI_NHLT_LINKTYPE_SSP; + dev_type = ACPI_NHLT_DEVICETYPE_CODEC; + bus_id = te->copier.vindex.i2s.instance; + dir = SNDRV_PCM_STREAM_PLAYBACK; + fmt = te->copier.out_fmt; + break; + + case AVS_DMA_I2S_LINK_INPUT: + link_type = ACPI_NHLT_LINKTYPE_SSP; + dev_type = ACPI_NHLT_DEVICETYPE_CODEC; + bus_id = te->copier.vindex.i2s.instance; + dir = SNDRV_PCM_STREAM_CAPTURE; + fmt = t->in_fmt; + break; + + case AVS_DMA_DMIC_LINK_INPUT: + link_type = ACPI_NHLT_LINKTYPE_PDM; + dev_type = -1; /* ignored */ + bus_id = 0; + dir = SNDRV_PCM_STREAM_CAPTURE; + fmt = t->in_fmt; + break; + + default: + return default_blob; + } + + /* Override format selection if necessary. */ + if (te->copier.blob_fmt) + fmt = te->copier.blob_fmt; + + fmtcfg = acpi_nhlt_find_fmtcfg(link_type, dev_type, dir, bus_id, + fmt->num_channels, fmt->sampling_freq, fmt->valid_bit_depth, + fmt->bit_depth); + if (!fmtcfg) { + dev_warn(adev->dev, "Endpoint format configuration not found.\n"); + return ERR_PTR(-ENOENT); + } + + if (fmtcfg->config.capabilities_size < default_blob->capabilities_size) + return ERR_PTR(-ETOOSMALL); + /* The firmware expects the payload to be DWORD-aligned. */ + if (fmtcfg->config.capabilities_size % sizeof(u32)) + return ERR_PTR(-EINVAL); + + return &fmtcfg->config; +} + +static int avs_fill_gtw_config(struct avs_dev *adev, struct avs_copier_gtw_cfg *gtw, + struct avs_tplg_module *t, size_t *cfg_size) +{ + struct acpi_nhlt_config *blob; + size_t gtw_size; + + blob = avs_nhlt_config_or_default(adev, t); + if (IS_ERR(blob)) + return PTR_ERR(blob); + + gtw_size = blob->capabilities_size; + if (*cfg_size + gtw_size > AVS_MAILBOX_SIZE) + return -E2BIG; + + gtw->config_length = gtw_size / sizeof(u32); + memcpy(gtw->config.blob, blob->capabilities, blob->capabilities_size); + *cfg_size += gtw_size; + + return 0; +} + +static __maybe_unused int avs_copier_create2(struct avs_dev *adev, struct avs_path_module *mod) +{ + struct avs_tplg_module *t = mod->template; + struct avs_tplg_modcfg_ext *te; + struct avs_copier_cfg *cfg; + size_t cfg_size; + u32 dma_id; + int ret; + + te = t->cfg_ext; + cfg = adev->modcfg_buf; + dma_id = mod->owner->owner->dma_id; + cfg_size = offsetof(struct avs_copier_cfg, gtw_cfg.config); + + ret = avs_fill_gtw_config(adev, &cfg->gtw_cfg, t, &cfg_size); + if (ret) + return ret; + + cfg->base.cpc = t->cfg_base->cpc; + cfg->base.ibs = t->cfg_base->ibs; + cfg->base.obs = t->cfg_base->obs; + cfg->base.is_pages = t->cfg_base->is_pages; + cfg->base.audio_fmt = *t->in_fmt; + cfg->out_fmt = *te->copier.out_fmt; + cfg->feature_mask = te->copier.feature_mask; + avs_init_node_id(&cfg->gtw_cfg.node_id, te, dma_id); + cfg->gtw_cfg.dma_buffer_size = te->copier.dma_buffer_size; + mod->gtw_attrs = cfg->gtw_cfg.config.attrs; + + ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id, + t->domain, cfg, cfg_size, &mod->instance_id); + return ret; +} + __maybe_unused static bool avs_dma_type_is_host(u32 dma_type) { From 320155a61f7fc810a915644e9e2a451bdcea90b1 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:49 +0100 Subject: [PATCH 020/651] ASoC: Intel: avs: Remove unused gateway configuration code Switch to new copier module constructor and remove code that becomes unused because of that. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/path.c | 149 +-------------------------------- sound/soc/intel/avs/topology.h | 2 - 2 files changed, 1 insertion(+), 150 deletions(-) diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index 698a3d542244..cfa19e4820d2 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -231,7 +231,7 @@ static int avs_fill_gtw_config(struct avs_dev *adev, struct avs_copier_gtw_cfg * return 0; } -static __maybe_unused int avs_copier_create2(struct avs_dev *adev, struct avs_path_module *mod) +static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod) { struct avs_tplg_module *t = mod->template; struct avs_tplg_modcfg_ext *te; @@ -265,153 +265,6 @@ static __maybe_unused int avs_copier_create2(struct avs_dev *adev, struct avs_pa return ret; } -__maybe_unused -static bool avs_dma_type_is_host(u32 dma_type) -{ - return dma_type == AVS_DMA_HDA_HOST_OUTPUT || - dma_type == AVS_DMA_HDA_HOST_INPUT; -} - -__maybe_unused -static bool avs_dma_type_is_link(u32 dma_type) -{ - return !avs_dma_type_is_host(dma_type); -} - -__maybe_unused -static bool avs_dma_type_is_output(u32 dma_type) -{ - return dma_type == AVS_DMA_HDA_HOST_OUTPUT || - dma_type == AVS_DMA_HDA_LINK_OUTPUT || - dma_type == AVS_DMA_I2S_LINK_OUTPUT; -} - -__maybe_unused -static bool avs_dma_type_is_input(u32 dma_type) -{ - return !avs_dma_type_is_output(dma_type); -} - -static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod) -{ - struct avs_tplg_module *t = mod->template; - struct avs_copier_cfg *cfg; - struct acpi_nhlt_format_config *ep_blob; - struct acpi_nhlt_endpoint *ep; - union avs_connector_node_id node_id = {0}; - size_t cfg_size, data_size; - void *data = NULL; - u32 dma_type; - int ret; - - data_size = sizeof(cfg->gtw_cfg.config); - dma_type = t->cfg_ext->copier.dma_type; - node_id.dma_type = dma_type; - - switch (dma_type) { - struct avs_audio_format *fmt; - int direction; - - case AVS_DMA_I2S_LINK_OUTPUT: - case AVS_DMA_I2S_LINK_INPUT: - if (avs_dma_type_is_input(dma_type)) - direction = SNDRV_PCM_STREAM_CAPTURE; - else - direction = SNDRV_PCM_STREAM_PLAYBACK; - - if (t->cfg_ext->copier.blob_fmt) - fmt = t->cfg_ext->copier.blob_fmt; - else if (direction == SNDRV_PCM_STREAM_CAPTURE) - fmt = t->in_fmt; - else - fmt = t->cfg_ext->copier.out_fmt; - - ep = acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_SSP, - ACPI_NHLT_DEVICETYPE_CODEC, direction, - t->cfg_ext->copier.vindex.i2s.instance); - ep_blob = acpi_nhlt_endpoint_find_fmtcfg(ep, fmt->num_channels, fmt->sampling_freq, - fmt->valid_bit_depth, fmt->bit_depth); - if (!ep_blob) { - dev_err(adev->dev, "no I2S ep_blob found\n"); - return -ENOENT; - } - - data = ep_blob->config.capabilities; - data_size = ep_blob->config.capabilities_size; - /* I2S gateway's vindex is statically assigned in topology */ - node_id.vindex = t->cfg_ext->copier.vindex.val; - - break; - - case AVS_DMA_DMIC_LINK_INPUT: - direction = SNDRV_PCM_STREAM_CAPTURE; - - if (t->cfg_ext->copier.blob_fmt) - fmt = t->cfg_ext->copier.blob_fmt; - else - fmt = t->in_fmt; - - ep = acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, direction, 0); - ep_blob = acpi_nhlt_endpoint_find_fmtcfg(ep, fmt->num_channels, fmt->sampling_freq, - fmt->valid_bit_depth, fmt->bit_depth); - if (!ep_blob) { - dev_err(adev->dev, "no DMIC ep_blob found\n"); - return -ENOENT; - } - - data = ep_blob->config.capabilities; - data_size = ep_blob->config.capabilities_size; - /* DMIC gateway's vindex is statically assigned in topology */ - node_id.vindex = t->cfg_ext->copier.vindex.val; - - break; - - case AVS_DMA_HDA_HOST_OUTPUT: - case AVS_DMA_HDA_HOST_INPUT: - /* HOST gateway's vindex is dynamically assigned with DMA id */ - node_id.vindex = mod->owner->owner->dma_id; - break; - - case AVS_DMA_HDA_LINK_OUTPUT: - case AVS_DMA_HDA_LINK_INPUT: - node_id.vindex = t->cfg_ext->copier.vindex.val | - mod->owner->owner->dma_id; - break; - - case INVALID_OBJECT_ID: - default: - node_id = INVALID_NODE_ID; - break; - } - - cfg_size = offsetof(struct avs_copier_cfg, gtw_cfg.config) + data_size; - if (cfg_size > AVS_MAILBOX_SIZE) - return -EINVAL; - - cfg = adev->modcfg_buf; - memset(cfg, 0, cfg_size); - cfg->base.cpc = t->cfg_base->cpc; - cfg->base.ibs = t->cfg_base->ibs; - cfg->base.obs = t->cfg_base->obs; - cfg->base.is_pages = t->cfg_base->is_pages; - cfg->base.audio_fmt = *t->in_fmt; - cfg->out_fmt = *t->cfg_ext->copier.out_fmt; - cfg->feature_mask = t->cfg_ext->copier.feature_mask; - cfg->gtw_cfg.node_id = node_id; - cfg->gtw_cfg.dma_buffer_size = t->cfg_ext->copier.dma_buffer_size; - /* config_length in DWORDs */ - cfg->gtw_cfg.config_length = DIV_ROUND_UP(data_size, 4); - if (data) - memcpy(&cfg->gtw_cfg.config.blob, data, data_size); - - mod->gtw_attrs = cfg->gtw_cfg.config.attrs; - - ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, - t->core_id, t->domain, cfg, cfg_size, - &mod->instance_id); - return ret; -} - static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod) { struct avs_tplg_module *t = mod->template; diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h index 7892e3797f63..dcfc568081a3 100644 --- a/sound/soc/intel/avs/topology.h +++ b/sound/soc/intel/avs/topology.h @@ -74,8 +74,6 @@ struct avs_tplg_modcfg_ext { union avs_virtual_index vindex; u32 dma_type; u32 dma_buffer_size; - u32 config_length; - /* config_data part of priv data */ } copier; struct { u32 out_channel_config; From 4343af66b8e1df1d3a2e6f1f8612506cb45b2afd Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:50 +0100 Subject: [PATCH 021/651] ASoC: Intel: avs: Add WHM module support WovHostModule (WHM) is used in wake-on-voice scenarios to optimize power consumption. It combines capabilities of Copier, KeyPhraseBuffer, WakeOnVoice and Muxer modules. Signed-off-by: Piotr Maziarz Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- include/uapi/sound/intel/avs/tokens.h | 7 +++++ sound/soc/intel/avs/messages.h | 13 +++++++++ sound/soc/intel/avs/path.c | 36 +++++++++++++++++++++++ sound/soc/intel/avs/topology.c | 42 +++++++++++++++++++++++++++ sound/soc/intel/avs/topology.h | 9 ++++++ 5 files changed, 107 insertions(+) diff --git a/include/uapi/sound/intel/avs/tokens.h b/include/uapi/sound/intel/avs/tokens.h index 3e3fb258dd54..06ff30537f47 100644 --- a/include/uapi/sound/intel/avs/tokens.h +++ b/include/uapi/sound/intel/avs/tokens.h @@ -77,6 +77,13 @@ enum avs_tplg_token { AVS_TKN_MODCFG_UPDOWN_MIX_CHAN_MAP_U32 = 430, AVS_TKN_MODCFG_EXT_NUM_INPUT_PINS_U16 = 431, AVS_TKN_MODCFG_EXT_NUM_OUTPUT_PINS_U16 = 432, + AVS_TKN_MODCFG_WHM_REF_AFMT_ID_U32 = 433, + AVS_TKN_MODCFG_WHM_OUT_AFMT_ID_U32 = 434, + AVS_TKN_MODCFG_WHM_WAKE_TICK_PERIOD_U32 = 435, + AVS_TKN_MODCFG_WHM_VINDEX_U8 = 436, + AVS_TKN_MODCFG_WHM_DMA_TYPE_U32 = 437, + AVS_TKN_MODCFG_WHM_DMABUFF_SIZE_U32 = 438, + AVS_TKN_MODCFG_WHM_BLOB_AFMT_ID_U32 = 439, /* struct avs_tplg_pplcfg */ AVS_TKN_PPLCFG_ID_U32 = 1401, diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h index 84b0d4b69ecb..f44fcfc81de7 100644 --- a/sound/soc/intel/avs/messages.h +++ b/sound/soc/intel/avs/messages.h @@ -652,6 +652,9 @@ int avs_ipc_set_system_time(struct avs_dev *adev); #define AVS_INTELWOV_MOD_UUID \ GUID_INIT(0xEC774FA9, 0x28D3, 0x424A, 0x90, 0xE4, 0x69, 0xF9, 0x84, 0xF1, 0xEE, 0xB7) +#define AVS_WOVHOSTM_MOD_UUID \ + GUID_INIT(0xF9ED62B7, 0x092E, 0x4A90, 0x8F, 0x4D, 0x82, 0xDA, 0xA8, 0xB3, 0x8F, 0x3B) + /* channel map */ enum avs_channel_index { AVS_CHANNEL_LEFT = 0, @@ -881,6 +884,16 @@ struct avs_wov_cfg { } __packed; static_assert(sizeof(struct avs_wov_cfg) == 44); +struct avs_whm_cfg { + struct avs_modcfg_base base; + /* Audio format for output pin 0 */ + struct avs_audio_format ref_fmt; + struct avs_audio_format out_fmt; + u32 wake_tick_period; + struct avs_copier_gtw_cfg gtw_cfg; +} __packed; +static_assert(sizeof(struct avs_whm_cfg) == 108); + /* Module runtime parameters */ enum avs_copier_runtime_param { diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index cfa19e4820d2..dfb85bd2b665 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -265,6 +265,41 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod) return ret; } +static int avs_whm_create(struct avs_dev *adev, struct avs_path_module *mod) +{ + struct avs_tplg_module *t = mod->template; + struct avs_tplg_modcfg_ext *te; + struct avs_whm_cfg *cfg; + size_t cfg_size; + u32 dma_id; + int ret; + + te = t->cfg_ext; + cfg = adev->modcfg_buf; + dma_id = mod->owner->owner->dma_id; + cfg_size = offsetof(struct avs_whm_cfg, gtw_cfg.config); + + ret = avs_fill_gtw_config(adev, &cfg->gtw_cfg, t, &cfg_size); + if (ret) + return ret; + + cfg->base.cpc = t->cfg_base->cpc; + cfg->base.ibs = t->cfg_base->ibs; + cfg->base.obs = t->cfg_base->obs; + cfg->base.is_pages = t->cfg_base->is_pages; + cfg->base.audio_fmt = *t->in_fmt; + cfg->ref_fmt = *te->whm.ref_fmt; + cfg->out_fmt = *te->whm.out_fmt; + cfg->wake_tick_period = te->whm.wake_tick_period; + avs_init_node_id(&cfg->gtw_cfg.node_id, te, dma_id); + cfg->gtw_cfg.dma_buffer_size = te->whm.dma_buffer_size; + mod->gtw_attrs = cfg->gtw_cfg.config.attrs; + + ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id, + t->domain, cfg, cfg_size, &mod->instance_id); + return ret; +} + static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod) { struct avs_tplg_module *t = mod->template; @@ -536,6 +571,7 @@ static struct avs_module_create avs_module_create[] = { { &AVS_ASRC_MOD_UUID, avs_asrc_create }, { &AVS_INTELWOV_MOD_UUID, avs_wov_create }, { &AVS_PROBE_MOD_UUID, avs_probe_create }, + { &AVS_WOVHOSTM_MOD_UUID, avs_whm_create }, }; static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_module *mod) diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index d612f20ed989..471b00b9a149 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -815,6 +815,48 @@ static const struct avs_tplg_token_parser modcfg_ext_parsers[] = { .offset = offsetof(struct avs_tplg_modcfg_ext, generic.num_output_pins), .parse = avs_parse_short_token, }, + { + .token = AVS_TKN_MODCFG_WHM_REF_AFMT_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, whm.ref_fmt), + .parse = avs_parse_audio_format_ptr, + }, + { + .token = AVS_TKN_MODCFG_WHM_OUT_AFMT_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, whm.out_fmt), + .parse = avs_parse_audio_format_ptr, + }, + { + .token = AVS_TKN_MODCFG_WHM_WAKE_TICK_PERIOD_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, whm.wake_tick_period), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_MODCFG_WHM_VINDEX_U8, + .type = SND_SOC_TPLG_TUPLE_TYPE_BYTE, + .offset = offsetof(struct avs_tplg_modcfg_ext, whm.vindex), + .parse = avs_parse_byte_token, + }, + { + .token = AVS_TKN_MODCFG_WHM_DMA_TYPE_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, whm.dma_type), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_MODCFG_WHM_DMABUFF_SIZE_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, whm.dma_buffer_size), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_MODCFG_WHM_BLOB_AFMT_ID_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, whm.blob_fmt), + .parse = avs_parse_audio_format_ptr, + }, }; static const struct avs_tplg_token_parser pin_format_parsers[] = { diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h index dcfc568081a3..23d5ccd19959 100644 --- a/sound/soc/intel/avs/topology.h +++ b/sound/soc/intel/avs/topology.h @@ -75,6 +75,15 @@ struct avs_tplg_modcfg_ext { u32 dma_type; u32 dma_buffer_size; } copier; + struct { + struct avs_audio_format *ref_fmt; + struct avs_audio_format *out_fmt; + u32 wake_tick_period; + union avs_virtual_index vindex; + u32 dma_type; + u32 dma_buffer_size; + struct avs_audio_format *blob_fmt; /* optional override */ + } whm; struct { u32 out_channel_config; u32 coefficients_select; From 856366dc924a9561dae39f252b45dfd6cc6895ce Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 3 Feb 2025 15:10:51 +0100 Subject: [PATCH 022/651] ALSA: hda: Select avs-driver by default on MBL The avs-driver is the recommended solution for MalibouLake (MBL, also known as RPL-M) platform. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250203141051.2361323-12-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/hda/intel-dsp-config.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c index f564ec7af194..9a8ead75be17 100644 --- a/sound/hda/intel-dsp-config.c +++ b/sound/hda/intel-dsp-config.c @@ -108,6 +108,10 @@ static const struct config_entry config_table[] = { {} } }, + { + .flags = FLAG_SST, + .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M, + }, #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) { From b2f10aa2eb18d289e48097e0ed973e714322175b Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 10 Dec 2024 16:16:50 +0100 Subject: [PATCH 023/651] x86/entry: Add __init to ia32_emulation_override_cmdline() ia32_emulation_override_cmdline() is an early_param() arg and these are only needed at boot time. In fact, all other early_param() functions in arch/x86 seem to have '__init' annotation and ia32_emulation_override_cmdline() is the only exception. Fixes: a11e097504ac ("x86: Make IA32_EMULATION boot time configurable") Signed-off-by: Vitaly Kuznetsov Signed-off-by: Dave Hansen Reviewed-by: Nikolay Borisov Link: https://lore.kernel.org/all/20241210151650.1746022-1-vkuznets%40redhat.com --- arch/x86/entry/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 94941c5a10ac..51efd2da4d7f 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -142,7 +142,7 @@ static __always_inline int syscall_32_enter(struct pt_regs *regs) #ifdef CONFIG_IA32_EMULATION bool __ia32_enabled __ro_after_init = !IS_ENABLED(CONFIG_IA32_EMULATION_DEFAULT_DISABLED); -static int ia32_emulation_override_cmdline(char *arg) +static int __init ia32_emulation_override_cmdline(char *arg) { return kstrtobool(arg, &__ia32_enabled); } From 8478dadc8148af311c3d43d4867cfb6632686ede Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Mon, 9 Dec 2024 15:09:05 +0300 Subject: [PATCH 024/651] ASoC: dt-bindings: Add bindings for WCD934x DAIs Add bindings for the DAIs available in WCD934x to avoid having to use unclear number indices in device trees. Signed-off-by: Dzmitry Sankouski Acked-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20241209-starqltechn_integration_upstream-v8-1-ec604481d691@gmail.com Signed-off-by: Mark Brown --- MAINTAINERS | 1 + include/dt-bindings/sound/qcom,wcd934x.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 include/dt-bindings/sound/qcom,wcd934x.h diff --git a/MAINTAINERS b/MAINTAINERS index 896a307fa065..28bf01c466d3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19149,6 +19149,7 @@ F: Documentation/devicetree/bindings/soc/qcom/qcom,apr* F: Documentation/devicetree/bindings/sound/qcom,* F: drivers/soc/qcom/apr.c F: include/dt-bindings/sound/qcom,wcd9335.h +F: include/dt-bindings/sound/qcom,wcd934x.h F: sound/soc/codecs/lpass-rx-macro.* F: sound/soc/codecs/lpass-tx-macro.* F: sound/soc/codecs/lpass-va-macro.c diff --git a/include/dt-bindings/sound/qcom,wcd934x.h b/include/dt-bindings/sound/qcom,wcd934x.h new file mode 100644 index 000000000000..8b30d34fcc87 --- /dev/null +++ b/include/dt-bindings/sound/qcom,wcd934x.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef __DT_SOUND_QCOM_WCD934x_H +#define __DT_SOUND_QCOM_WCD934x_H + +#define AIF1_PB 0 +#define AIF1_CAP 1 +#define AIF2_PB 2 +#define AIF2_CAP 3 +#define AIF3_PB 4 +#define AIF3_CAP 5 +#define AIF4_PB 6 +#define AIF4_VIFEED 7 +#define AIF4_MAD_TX 8 + +#endif From e27c125040b1e1f26d910b46daabbe55e67fdf3b Mon Sep 17 00:00:00 2001 From: Dzmitry Sankouski Date: Mon, 9 Dec 2024 15:09:06 +0300 Subject: [PATCH 025/651] ASoC: codecs: wcd934x: use wcd934x binding header Replace AIF* enum with binding header include. This allow to get rid of mysterious indeces in dts. Signed-off-by: Dzmitry Sankouski Link: https://patch.msgid.link/20241209-starqltechn_integration_upstream-v8-2-ec604481d691@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd934x.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index 910852eb9698..dd0cda394bf1 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -23,6 +23,8 @@ #include "wcd-clsh-v2.h" #include "wcd-mbhc-v2.h" +#include + #define WCD934X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) @@ -307,6 +309,7 @@ {"SLIM TX" #id, NULL, "CDC_IF TX" #id " MUX"} #define WCD934X_MAX_MICBIAS MIC_BIAS_4 +#define NUM_CODEC_DAIS 9 enum { SIDO_SOURCE_INTERNAL, @@ -434,19 +437,6 @@ enum { COMPANDER_MAX, }; -enum { - AIF1_PB = 0, - AIF1_CAP, - AIF2_PB, - AIF2_CAP, - AIF3_PB, - AIF3_CAP, - AIF4_PB, - AIF4_VIFEED, - AIF4_MAD_TX, - NUM_CODEC_DAIS, -}; - enum { INTn_1_INP_SEL_ZERO = 0, INTn_1_INP_SEL_DEC0, From e3cd85963a20d2b92e77046a8d9f0777815f1f71 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Fri, 17 Jan 2025 15:48:59 +0100 Subject: [PATCH 026/651] x86/mtrr: Use str_enabled_disabled() helper in print_mtrr_state() Remove hard-coded strings by using the str_enabled_disabled() helper function. Suggested-by: Christophe JAILLET Signed-off-by: Thorsten Blum Signed-off-by: Dave Hansen Link: https://lore.kernel.org/all/20250117144900.171684-2-thorsten.blum%40linux.dev --- arch/x86/kernel/cpu/mtrr/generic.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 2fdfda2b60e4..6be3cade4134 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -646,10 +647,10 @@ static void __init print_mtrr_state(void) pr_info("MTRR default type: %s\n", mtrr_attrib_to_str(mtrr_state.def_type)); if (mtrr_state.have_fixed) { - pr_info("MTRR fixed ranges %sabled:\n", - ((mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) && - (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED)) ? - "en" : "dis"); + pr_info("MTRR fixed ranges %s:\n", + str_enabled_disabled( + (mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED) && + (mtrr_state.enabled & MTRR_STATE_MTRR_FIXED_ENABLED))); print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); for (i = 0; i < 2; ++i) print_fixed(0x80000 + i * 0x20000, 0x04000, @@ -661,8 +662,8 @@ static void __init print_mtrr_state(void) /* tail */ print_fixed_last(); } - pr_info("MTRR variable ranges %sabled:\n", - mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED ? "en" : "dis"); + pr_info("MTRR variable ranges %s:\n", + str_enabled_disabled(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED)); high_width = (boot_cpu_data.x86_phys_bits - (32 - PAGE_SHIFT) + 3) / 4; for (i = 0; i < num_var_ranges; ++i) { From e8d04a92484e6504bb0c98426db54bfc82a6934f Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Wed, 22 Jan 2025 02:20:59 +0000 Subject: [PATCH 027/651] ALSA: lola: Remove unused lola_(save|restore)_mixer lola_restore_mixer() and lola_save_mixer() were added in 2011 by commit d43f3010b8fa ("ALSA: Add the driver for Digigram Lola PCI-e boards") but have remain unused. Remove them. Signed-off-by: Dr. David Alan Gilbert Link: https://patch.msgid.link/20250122022059.456068-1-linux@treblig.org Signed-off-by: Takashi Iwai --- sound/pci/lola/lola.h | 2 -- sound/pci/lola/lola_mixer.c | 43 ------------------------------------- 2 files changed, 45 deletions(-) diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h index 0ff772cf66e6..25f72f9e3f9b 100644 --- a/sound/pci/lola/lola.h +++ b/sound/pci/lola/lola.h @@ -499,8 +499,6 @@ int lola_init_mixer_widget(struct lola *chip, int nid); void lola_free_mixer(struct lola *chip); int lola_create_mixer(struct lola *chip); int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute); -void lola_save_mixer(struct lola *chip); -void lola_restore_mixer(struct lola *chip); int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update); /* proc */ diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c index 6b162489cb5f..9cb26a8a4e1a 100644 --- a/sound/pci/lola/lola_mixer.c +++ b/sound/pci/lola/lola_mixer.c @@ -336,49 +336,6 @@ int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute) return lola_codec_flush(chip); } -void lola_save_mixer(struct lola *chip) -{ - /* mute analog output */ - if (chip->mixer.array_saved) { - /* store contents of mixer array */ - memcpy_fromio(chip->mixer.array_saved, chip->mixer.array, - sizeof(*chip->mixer.array)); - } - lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */ -} - -void lola_restore_mixer(struct lola *chip) -{ - int i; - - /*lola_reset_setups(chip);*/ - if (chip->mixer.array_saved) { - /* restore contents of mixer array */ - memcpy_toio(chip->mixer.array, chip->mixer.array_saved, - sizeof(*chip->mixer.array)); - /* inform micro-controller about all restored values - * and ignore return values - */ - for (i = 0; i < chip->mixer.src_phys_ins; i++) - lola_codec_write(chip, chip->mixer.nid, - LOLA_VERB_SET_SOURCE_GAIN, - i, 0); - for (i = 0; i < chip->mixer.src_stream_outs; i++) - lola_codec_write(chip, chip->mixer.nid, - LOLA_VERB_SET_SOURCE_GAIN, - chip->mixer.src_stream_out_ofs + i, 0); - for (i = 0; i < chip->mixer.dest_stream_ins; i++) - lola_codec_write(chip, chip->mixer.nid, - LOLA_VERB_SET_DESTINATION_GAIN, - i, 0); - for (i = 0; i < chip->mixer.dest_phys_outs; i++) - lola_codec_write(chip, chip->mixer.nid, - LOLA_VERB_SET_DESTINATION_GAIN, - chip->mixer.dest_phys_out_ofs + i, 0); - lola_codec_flush(chip); - } -} - /* */ From 1b0e9d7f76c9bb6bd1a345ef033ae7fe5e77649c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 24 Jan 2025 23:14:30 +0200 Subject: [PATCH 028/651] ALSA: hda/hdmi: extract common interface for ELD handling Other HDMI-related cards (e.g. hdmi-codec) are also using the ELD. Exrtact common set of interfaces for handling the ELD. Signed-off-by: Dmitry Baryshkov Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250124-alsa-hdmi-codec-eld-v1-1-bad045cfaeac@linaro.org --- include/sound/pcm_drm_eld.h | 91 +++++++++ sound/core/pcm_drm_eld.c | 387 ++++++++++++++++++++++++++++++++++++ sound/pci/hda/Kconfig | 1 + sound/pci/hda/hda_eld.c | 383 +---------------------------------- sound/pci/hda/hda_local.h | 49 +---- sound/pci/hda/patch_hdmi.c | 6 +- 6 files changed, 493 insertions(+), 424 deletions(-) diff --git a/include/sound/pcm_drm_eld.h b/include/sound/pcm_drm_eld.h index 28a55a8beb28..5a38413ada91 100644 --- a/include/sound/pcm_drm_eld.h +++ b/include/sound/pcm_drm_eld.h @@ -2,6 +2,97 @@ #ifndef __SOUND_PCM_DRM_ELD_H #define __SOUND_PCM_DRM_ELD_H +enum eld_versions { + ELD_VER_CEA_861D = 2, + ELD_VER_PARTIAL = 31, +}; + +enum cea_audio_coding_types { + AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, + AUDIO_CODING_TYPE_LPCM = 1, + AUDIO_CODING_TYPE_AC3 = 2, + AUDIO_CODING_TYPE_MPEG1 = 3, + AUDIO_CODING_TYPE_MP3 = 4, + AUDIO_CODING_TYPE_MPEG2 = 5, + AUDIO_CODING_TYPE_AACLC = 6, + AUDIO_CODING_TYPE_DTS = 7, + AUDIO_CODING_TYPE_ATRAC = 8, + AUDIO_CODING_TYPE_SACD = 9, + AUDIO_CODING_TYPE_EAC3 = 10, + AUDIO_CODING_TYPE_DTS_HD = 11, + AUDIO_CODING_TYPE_MLP = 12, + AUDIO_CODING_TYPE_DST = 13, + AUDIO_CODING_TYPE_WMAPRO = 14, + AUDIO_CODING_TYPE_REF_CXT = 15, + /* also include valid xtypes below */ + AUDIO_CODING_TYPE_HE_AAC = 15, + AUDIO_CODING_TYPE_HE_AAC2 = 16, + AUDIO_CODING_TYPE_MPEG_SURROUND = 17, +}; + +enum cea_audio_coding_xtypes { + AUDIO_CODING_XTYPE_HE_REF_CT = 0, + AUDIO_CODING_XTYPE_HE_AAC = 1, + AUDIO_CODING_XTYPE_HE_AAC2 = 2, + AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, + AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, +}; + +/* + * CEA Short Audio Descriptor data + */ +struct snd_cea_sad { + int channels; + int format; /* (format == 0) indicates invalid SAD */ + int rates; + int sample_bits; /* for LPCM */ + int max_bitrate; /* for AC3...ATRAC */ + int profile; /* for WMAPRO */ +}; + +#define ELD_FIXED_BYTES 20 +#define ELD_MAX_SIZE 256 +#define ELD_MAX_MNL 16 +#define ELD_MAX_SAD 16 + +#define ELD_PCM_BITS_8 BIT(0) +#define ELD_PCM_BITS_16 BIT(1) +#define ELD_PCM_BITS_20 BIT(2) +#define ELD_PCM_BITS_24 BIT(3) +#define ELD_PCM_BITS_32 BIT(4) + +/* + * ELD: EDID Like Data + */ +struct snd_parsed_hdmi_eld { + /* + * all fields will be cleared before updating ELD + */ + int baseline_len; + int eld_ver; + int cea_edid_ver; + char monitor_name[ELD_MAX_MNL + 1]; + int manufacture_id; + int product_id; + u64 port_id; + int support_hdcp; + int support_ai; + int conn_type; + int aud_synch_delay; + int spk_alloc; + int sad_count; + struct snd_cea_sad sad[ELD_MAX_SAD]; +}; + int snd_pcm_hw_constraint_eld(struct snd_pcm_runtime *runtime, void *eld); +int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e, + const unsigned char *buf, int size); +void snd_show_eld(struct device *dev, struct snd_parsed_hdmi_eld *e); + +#ifdef CONFIG_SND_PROC_FS +void snd_print_eld_info(struct snd_parsed_hdmi_eld *eld, + struct snd_info_buffer *buffer); +#endif + #endif diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c index 1cdca4d4fc9c..688eefce82fa 100644 --- a/sound/core/pcm_drm_eld.c +++ b/sound/core/pcm_drm_eld.c @@ -5,8 +5,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -162,3 +164,388 @@ int snd_pcm_hw_constraint_eld(struct snd_pcm_runtime *runtime, void *eld) return ret; } EXPORT_SYMBOL_GPL(snd_pcm_hw_constraint_eld); + +#define SND_PRINT_RATES_ADVISED_BUFSIZE 80 +#define SND_PRINT_BITS_ADVISED_BUFSIZE 16 +#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 + +static const char * const eld_connection_type_names[4] = { + "HDMI", + "DisplayPort", + "2-reserved", + "3-reserved" +}; + +static const char * const cea_audio_coding_type_names[] = { + /* 0 */ "undefined", + /* 1 */ "LPCM", + /* 2 */ "AC-3", + /* 3 */ "MPEG1", + /* 4 */ "MP3", + /* 5 */ "MPEG2", + /* 6 */ "AAC-LC", + /* 7 */ "DTS", + /* 8 */ "ATRAC", + /* 9 */ "DSD (One Bit Audio)", + /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)", + /* 11 */ "DTS-HD", + /* 12 */ "MLP (Dolby TrueHD)", + /* 13 */ "DST", + /* 14 */ "WMAPro", + /* 15 */ "HE-AAC", + /* 16 */ "HE-AACv2", + /* 17 */ "MPEG Surround", +}; + +static const char * const cea_speaker_allocation_names[] = { + /* 0 */ "FL/FR", + /* 1 */ "LFE", + /* 2 */ "FC", + /* 3 */ "RL/RR", + /* 4 */ "RC", + /* 5 */ "FLC/FRC", + /* 6 */ "RLC/RRC", + /* 7 */ "FLW/FRW", + /* 8 */ "FLH/FRH", + /* 9 */ "TC", + /* 10 */ "FCH", +}; + +/* + * SS1:SS0 index => sample size + */ +static const int cea_sample_sizes[4] = { + 0, /* 0: Refer to Stream Header */ + ELD_PCM_BITS_16, /* 1: 16 bits */ + ELD_PCM_BITS_20, /* 2: 20 bits */ + ELD_PCM_BITS_24, /* 3: 24 bits */ +}; + +/* + * SF2:SF1:SF0 index => sampling frequency + */ +static const int cea_sampling_frequencies[8] = { + 0, /* 0: Refer to Stream Header */ + SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ + SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ + SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ + SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ + SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ + SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ + SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ +}; + +#define GRAB_BITS(buf, byte, lowbit, bits) \ +({ \ + BUILD_BUG_ON(lowbit > 7); \ + BUILD_BUG_ON(bits > 8); \ + BUILD_BUG_ON(bits <= 0); \ + \ + (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \ +}) + +static void hdmi_update_short_audio_desc(struct device *dev, + struct snd_cea_sad *a, + const unsigned char *buf) +{ + int i; + int val; + + val = GRAB_BITS(buf, 1, 0, 7); + a->rates = 0; + for (i = 0; i < 7; i++) + if (val & (1 << i)) + a->rates |= cea_sampling_frequencies[i + 1]; + + a->channels = GRAB_BITS(buf, 0, 0, 3); + a->channels++; + + a->sample_bits = 0; + a->max_bitrate = 0; + + a->format = GRAB_BITS(buf, 0, 3, 4); + switch (a->format) { + case AUDIO_CODING_TYPE_REF_STREAM_HEADER: + dev_info(dev, "HDMI: audio coding type 0 not expected\n"); + break; + + case AUDIO_CODING_TYPE_LPCM: + val = GRAB_BITS(buf, 2, 0, 3); + for (i = 0; i < 3; i++) + if (val & (1 << i)) + a->sample_bits |= cea_sample_sizes[i + 1]; + break; + + case AUDIO_CODING_TYPE_AC3: + case AUDIO_CODING_TYPE_MPEG1: + case AUDIO_CODING_TYPE_MP3: + case AUDIO_CODING_TYPE_MPEG2: + case AUDIO_CODING_TYPE_AACLC: + case AUDIO_CODING_TYPE_DTS: + case AUDIO_CODING_TYPE_ATRAC: + a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); + a->max_bitrate *= 8000; + break; + + case AUDIO_CODING_TYPE_SACD: + break; + + case AUDIO_CODING_TYPE_EAC3: + break; + + case AUDIO_CODING_TYPE_DTS_HD: + break; + + case AUDIO_CODING_TYPE_MLP: + break; + + case AUDIO_CODING_TYPE_DST: + break; + + case AUDIO_CODING_TYPE_WMAPRO: + a->profile = GRAB_BITS(buf, 2, 0, 3); + break; + + case AUDIO_CODING_TYPE_REF_CXT: + a->format = GRAB_BITS(buf, 2, 3, 5); + if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || + a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { + dev_info(dev, + "HDMI: audio coding xtype %d not expected\n", + a->format); + a->format = 0; + } else + a->format += AUDIO_CODING_TYPE_HE_AAC - + AUDIO_CODING_XTYPE_HE_AAC; + break; + } +} + +/* + * Be careful, ELD buf could be totally rubbish! + */ +int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e, + const unsigned char *buf, int size) +{ + int mnl; + int i; + + memset(e, 0, sizeof(*e)); + e->eld_ver = GRAB_BITS(buf, 0, 3, 5); + if (e->eld_ver != ELD_VER_CEA_861D && + e->eld_ver != ELD_VER_PARTIAL) { + dev_info(dev, "HDMI: Unknown ELD version %d\n", e->eld_ver); + goto out_fail; + } + + e->baseline_len = GRAB_BITS(buf, 2, 0, 8); + mnl = GRAB_BITS(buf, 4, 0, 5); + e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); + + e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); + e->support_ai = GRAB_BITS(buf, 5, 1, 1); + e->conn_type = GRAB_BITS(buf, 5, 2, 2); + e->sad_count = GRAB_BITS(buf, 5, 4, 4); + + e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; + e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); + + e->port_id = get_unaligned_le64(buf + 8); + + /* not specified, but the spec's tendency is little endian */ + e->manufacture_id = get_unaligned_le16(buf + 16); + e->product_id = get_unaligned_le16(buf + 18); + + if (mnl > ELD_MAX_MNL) { + dev_info(dev, "HDMI: MNL is reserved value %d\n", mnl); + goto out_fail; + } else if (ELD_FIXED_BYTES + mnl > size) { + dev_info(dev, "HDMI: out of range MNL %d\n", mnl); + goto out_fail; + } else + strscpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1); + + for (i = 0; i < e->sad_count; i++) { + if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { + dev_info(dev, "HDMI: out of range SAD %d\n", i); + goto out_fail; + } + hdmi_update_short_audio_desc(dev, e->sad + i, + buf + ELD_FIXED_BYTES + mnl + 3 * i); + } + + /* + * HDMI sink's ELD info cannot always be retrieved for now, e.g. + * in console or for audio devices. Assume the highest speakers + * configuration, to _not_ prohibit multi-channel audio playback. + */ + if (!e->spk_alloc) + e->spk_alloc = 0xffff; + + return 0; + +out_fail: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_parse_eld); + +/* + * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with + * hdmi-specific routine. + */ +static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) +{ + static const unsigned int alsa_rates[] = { + 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, + 88200, 96000, 176400, 192000, 384000 + }; + int i, j; + + for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++) + if (pcm & (1 << i)) + j += scnprintf(buf + j, buflen - j, " %d", + alsa_rates[i]); + + buf[j] = '\0'; /* necessary when j == 0 */ +} + +static void eld_print_pcm_bits(int pcm, char *buf, int buflen) +{ + static const unsigned int bits[] = { 8, 16, 20, 24, 32 }; + int i, j; + + for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++) + if (pcm & (ELD_PCM_BITS_8 << i)) + j += scnprintf(buf + j, buflen - j, " %d", bits[i]); + + buf[j] = '\0'; /* necessary when j == 0 */ +} + +static void hdmi_show_short_audio_desc(struct device *dev, + struct snd_cea_sad *a) +{ + char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; + char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits ="; + + if (!a->format) + return; + + hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); + + if (a->format == AUDIO_CODING_TYPE_LPCM) + eld_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); + else if (a->max_bitrate) + snprintf(buf2, sizeof(buf2), + ", max bitrate = %d", a->max_bitrate); + else + buf2[0] = '\0'; + + dev_dbg(dev, + "HDMI: supports coding type %s: channels = %d, rates =%s%s\n", + cea_audio_coding_type_names[a->format], + a->channels, buf, buf2); +} + +static void snd_eld_print_channel_allocation(int spk_alloc, char *buf, int buflen) +{ + int i, j; + + for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) { + if (spk_alloc & (1 << i)) + j += scnprintf(buf + j, buflen - j, " %s", + cea_speaker_allocation_names[i]); + } + buf[j] = '\0'; /* necessary when j == 0 */ +} + +void snd_show_eld(struct device *dev, struct snd_parsed_hdmi_eld *e) +{ + int i; + + dev_dbg(dev, "HDMI: detected monitor %s at connection type %s\n", + e->monitor_name, + eld_connection_type_names[e->conn_type]); + + if (e->spk_alloc) { + char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; + + snd_eld_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); + dev_dbg(dev, "HDMI: available speakers:%s\n", buf); + } + + for (i = 0; i < e->sad_count; i++) + hdmi_show_short_audio_desc(dev, e->sad + i); +} +EXPORT_SYMBOL_GPL(snd_show_eld); + +#ifdef CONFIG_SND_PROC_FS +static void hdmi_print_sad_info(int i, struct snd_cea_sad *a, + struct snd_info_buffer *buffer) +{ + char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; + + snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n", + i, a->format, cea_audio_coding_type_names[a->format]); + snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); + + hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); + snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); + + if (a->format == AUDIO_CODING_TYPE_LPCM) { + eld_print_pcm_bits(a->sample_bits, buf, sizeof(buf)); + snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n", + i, a->sample_bits, buf); + } + + if (a->max_bitrate) + snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n", + i, a->max_bitrate); + + if (a->profile) + snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); +} + +void snd_print_eld_info(struct snd_parsed_hdmi_eld *e, + struct snd_info_buffer *buffer) +{ + char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; + int i; + static const char * const eld_version_names[32] = { + "reserved", + "reserved", + "CEA-861D or below", + [3 ... 30] = "reserved", + [31] = "partial" + }; + static const char * const cea_edid_version_names[8] = { + "no CEA EDID Timing Extension block present", + "CEA-861", + "CEA-861-A", + "CEA-861-B, C or D", + [4 ... 7] = "reserved" + }; + + snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); + snd_iprintf(buffer, "connection_type\t\t%s\n", + eld_connection_type_names[e->conn_type]); + snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, + eld_version_names[e->eld_ver]); + snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, + cea_edid_version_names[e->cea_edid_ver]); + snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); + snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id); + snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id); + snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp); + snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai); + snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay); + + snd_eld_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); + snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf); + + snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count); + + for (i = 0; i < e->sad_count; i++) + hdmi_print_sad_info(i, e->sad + i, buffer); +} +EXPORT_SYMBOL_GPL(snd_print_eld_info); +#endif /* CONFIG_SND_PROC_FS */ diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index e393578cbe68..9f68cb73b54f 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -266,6 +266,7 @@ comment "Set to Y if you want auto-loading the codec driver" config SND_HDA_CODEC_HDMI tristate "Build HDMI/DisplayPort HD-audio codec support" select SND_DYNAMIC_MINORS + select SND_PCM_ELD help Say Y or M here to include HDMI and DisplayPort HD-audio codec support in snd-hda-intel driver. This includes all AMD/ATI, diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 301730432375..d3e87b9c1a4f 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -17,11 +17,6 @@ #include #include "hda_local.h" -enum eld_versions { - ELD_VER_CEA_861D = 2, - ELD_VER_PARTIAL = 31, -}; - enum cea_edid_versions { CEA_EDID_VER_NONE = 0, CEA_EDID_VER_CEA861 = 1, @@ -30,95 +25,12 @@ enum cea_edid_versions { CEA_EDID_VER_RESERVED = 4, }; -static const char * const eld_connection_type_names[4] = { - "HDMI", - "DisplayPort", - "2-reserved", - "3-reserved" -}; - -enum cea_audio_coding_types { - AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, - AUDIO_CODING_TYPE_LPCM = 1, - AUDIO_CODING_TYPE_AC3 = 2, - AUDIO_CODING_TYPE_MPEG1 = 3, - AUDIO_CODING_TYPE_MP3 = 4, - AUDIO_CODING_TYPE_MPEG2 = 5, - AUDIO_CODING_TYPE_AACLC = 6, - AUDIO_CODING_TYPE_DTS = 7, - AUDIO_CODING_TYPE_ATRAC = 8, - AUDIO_CODING_TYPE_SACD = 9, - AUDIO_CODING_TYPE_EAC3 = 10, - AUDIO_CODING_TYPE_DTS_HD = 11, - AUDIO_CODING_TYPE_MLP = 12, - AUDIO_CODING_TYPE_DST = 13, - AUDIO_CODING_TYPE_WMAPRO = 14, - AUDIO_CODING_TYPE_REF_CXT = 15, - /* also include valid xtypes below */ - AUDIO_CODING_TYPE_HE_AAC = 15, - AUDIO_CODING_TYPE_HE_AAC2 = 16, - AUDIO_CODING_TYPE_MPEG_SURROUND = 17, -}; - -enum cea_audio_coding_xtypes { - AUDIO_CODING_XTYPE_HE_REF_CT = 0, - AUDIO_CODING_XTYPE_HE_AAC = 1, - AUDIO_CODING_XTYPE_HE_AAC2 = 2, - AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, - AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, -}; - -static const char * const cea_audio_coding_type_names[] = { - /* 0 */ "undefined", - /* 1 */ "LPCM", - /* 2 */ "AC-3", - /* 3 */ "MPEG1", - /* 4 */ "MP3", - /* 5 */ "MPEG2", - /* 6 */ "AAC-LC", - /* 7 */ "DTS", - /* 8 */ "ATRAC", - /* 9 */ "DSD (One Bit Audio)", - /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)", - /* 11 */ "DTS-HD", - /* 12 */ "MLP (Dolby TrueHD)", - /* 13 */ "DST", - /* 14 */ "WMAPro", - /* 15 */ "HE-AAC", - /* 16 */ "HE-AACv2", - /* 17 */ "MPEG Surround", -}; - /* * The following two lists are shared between * - HDMI audio InfoFrame (source to sink) * - CEA E-EDID Extension (sink to source) */ -/* - * SS1:SS0 index => sample size - */ -static const int cea_sample_sizes[4] = { - 0, /* 0: Refer to Stream Header */ - AC_SUPPCM_BITS_16, /* 1: 16 bits */ - AC_SUPPCM_BITS_20, /* 2: 20 bits */ - AC_SUPPCM_BITS_24, /* 3: 24 bits */ -}; - -/* - * SF2:SF1:SF0 index => sampling frequency - */ -static const int cea_sampling_frequencies[8] = { - 0, /* 0: Refer to Stream Header */ - SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ - SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ - SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ - SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ - SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ - SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ - SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ -}; - static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid, int byte_index) { @@ -132,159 +44,6 @@ static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid, return val; } -#define GRAB_BITS(buf, byte, lowbit, bits) \ -({ \ - BUILD_BUG_ON(lowbit > 7); \ - BUILD_BUG_ON(bits > 8); \ - BUILD_BUG_ON(bits <= 0); \ - \ - (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \ -}) - -static void hdmi_update_short_audio_desc(struct hda_codec *codec, - struct cea_sad *a, - const unsigned char *buf) -{ - int i; - int val; - - val = GRAB_BITS(buf, 1, 0, 7); - a->rates = 0; - for (i = 0; i < 7; i++) - if (val & (1 << i)) - a->rates |= cea_sampling_frequencies[i + 1]; - - a->channels = GRAB_BITS(buf, 0, 0, 3); - a->channels++; - - a->sample_bits = 0; - a->max_bitrate = 0; - - a->format = GRAB_BITS(buf, 0, 3, 4); - switch (a->format) { - case AUDIO_CODING_TYPE_REF_STREAM_HEADER: - codec_info(codec, "HDMI: audio coding type 0 not expected\n"); - break; - - case AUDIO_CODING_TYPE_LPCM: - val = GRAB_BITS(buf, 2, 0, 3); - for (i = 0; i < 3; i++) - if (val & (1 << i)) - a->sample_bits |= cea_sample_sizes[i + 1]; - break; - - case AUDIO_CODING_TYPE_AC3: - case AUDIO_CODING_TYPE_MPEG1: - case AUDIO_CODING_TYPE_MP3: - case AUDIO_CODING_TYPE_MPEG2: - case AUDIO_CODING_TYPE_AACLC: - case AUDIO_CODING_TYPE_DTS: - case AUDIO_CODING_TYPE_ATRAC: - a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); - a->max_bitrate *= 8000; - break; - - case AUDIO_CODING_TYPE_SACD: - break; - - case AUDIO_CODING_TYPE_EAC3: - break; - - case AUDIO_CODING_TYPE_DTS_HD: - break; - - case AUDIO_CODING_TYPE_MLP: - break; - - case AUDIO_CODING_TYPE_DST: - break; - - case AUDIO_CODING_TYPE_WMAPRO: - a->profile = GRAB_BITS(buf, 2, 0, 3); - break; - - case AUDIO_CODING_TYPE_REF_CXT: - a->format = GRAB_BITS(buf, 2, 3, 5); - if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || - a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { - codec_info(codec, - "HDMI: audio coding xtype %d not expected\n", - a->format); - a->format = 0; - } else - a->format += AUDIO_CODING_TYPE_HE_AAC - - AUDIO_CODING_XTYPE_HE_AAC; - break; - } -} - -/* - * Be careful, ELD buf could be totally rubbish! - */ -int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e, - const unsigned char *buf, int size) -{ - int mnl; - int i; - - memset(e, 0, sizeof(*e)); - e->eld_ver = GRAB_BITS(buf, 0, 3, 5); - if (e->eld_ver != ELD_VER_CEA_861D && - e->eld_ver != ELD_VER_PARTIAL) { - codec_info(codec, "HDMI: Unknown ELD version %d\n", e->eld_ver); - goto out_fail; - } - - e->baseline_len = GRAB_BITS(buf, 2, 0, 8); - mnl = GRAB_BITS(buf, 4, 0, 5); - e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); - - e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); - e->support_ai = GRAB_BITS(buf, 5, 1, 1); - e->conn_type = GRAB_BITS(buf, 5, 2, 2); - e->sad_count = GRAB_BITS(buf, 5, 4, 4); - - e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; - e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); - - e->port_id = get_unaligned_le64(buf + 8); - - /* not specified, but the spec's tendency is little endian */ - e->manufacture_id = get_unaligned_le16(buf + 16); - e->product_id = get_unaligned_le16(buf + 18); - - if (mnl > ELD_MAX_MNL) { - codec_info(codec, "HDMI: MNL is reserved value %d\n", mnl); - goto out_fail; - } else if (ELD_FIXED_BYTES + mnl > size) { - codec_info(codec, "HDMI: out of range MNL %d\n", mnl); - goto out_fail; - } else - strscpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1); - - for (i = 0; i < e->sad_count; i++) { - if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { - codec_info(codec, "HDMI: out of range SAD %d\n", i); - goto out_fail; - } - hdmi_update_short_audio_desc(codec, e->sad + i, - buf + ELD_FIXED_BYTES + mnl + 3 * i); - } - - /* - * HDMI sink's ELD info cannot always be retrieved for now, e.g. - * in console or for audio devices. Assume the highest speakers - * configuration, to _not_ prohibit multi-channel audio playback. - */ - if (!e->spk_alloc) - e->spk_alloc = 0xffff; - - return 0; - -out_fail: - return -EINVAL; -} - int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) { return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, @@ -346,155 +105,27 @@ error: return ret; } -/* - * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with - * hdmi-specific routine. - */ -static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) -{ - static const unsigned int alsa_rates[] = { - 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, - 88200, 96000, 176400, 192000, 384000 - }; - int i, j; - - for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++) - if (pcm & (1 << i)) - j += scnprintf(buf + j, buflen - j, " %d", - alsa_rates[i]); - - buf[j] = '\0'; /* necessary when j == 0 */ -} - -#define SND_PRINT_RATES_ADVISED_BUFSIZE 80 - -static void hdmi_show_short_audio_desc(struct hda_codec *codec, - struct cea_sad *a) -{ - char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; - char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits ="; - - if (!a->format) - return; - - hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); - - if (a->format == AUDIO_CODING_TYPE_LPCM) - snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); - else if (a->max_bitrate) - snprintf(buf2, sizeof(buf2), - ", max bitrate = %d", a->max_bitrate); - else - buf2[0] = '\0'; - - codec_dbg(codec, - "HDMI: supports coding type %s: channels = %d, rates =%s%s\n", - cea_audio_coding_type_names[a->format], - a->channels, buf, buf2); -} - -void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e) -{ - int i; - - codec_dbg(codec, "HDMI: detected monitor %s at connection type %s\n", - e->monitor_name, - eld_connection_type_names[e->conn_type]); - - if (e->spk_alloc) { - char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; - snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); - codec_dbg(codec, "HDMI: available speakers:%s\n", buf); - } - - for (i = 0; i < e->sad_count; i++) - hdmi_show_short_audio_desc(codec, e->sad + i); -} - #ifdef CONFIG_SND_PROC_FS - -static void hdmi_print_sad_info(int i, struct cea_sad *a, - struct snd_info_buffer *buffer) -{ - char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; - - snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n", - i, a->format, cea_audio_coding_type_names[a->format]); - snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); - - hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); - snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); - - if (a->format == AUDIO_CODING_TYPE_LPCM) { - snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf)); - snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n", - i, a->sample_bits, buf); - } - - if (a->max_bitrate) - snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n", - i, a->max_bitrate); - - if (a->profile) - snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); -} - void snd_hdmi_print_eld_info(struct hdmi_eld *eld, struct snd_info_buffer *buffer, hda_nid_t pin_nid, int dev_id, hda_nid_t cvt_nid) { - struct parsed_hdmi_eld *e = &eld->info; - char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; - int i; - static const char * const eld_version_names[32] = { - "reserved", - "reserved", - "CEA-861D or below", - [3 ... 30] = "reserved", - [31] = "partial" - }; - static const char * const cea_edid_version_names[8] = { - "no CEA EDID Timing Extension block present", - "CEA-861", - "CEA-861-A", - "CEA-861-B, C or D", - [4 ... 7] = "reserved" - }; - snd_iprintf(buffer, "monitor_present\t\t%d\n", eld->monitor_present); snd_iprintf(buffer, "eld_valid\t\t%d\n", eld->eld_valid); snd_iprintf(buffer, "codec_pin_nid\t\t0x%x\n", pin_nid); snd_iprintf(buffer, "codec_dev_id\t\t0x%x\n", dev_id); snd_iprintf(buffer, "codec_cvt_nid\t\t0x%x\n", cvt_nid); + if (!eld->eld_valid) return; - snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); - snd_iprintf(buffer, "connection_type\t\t%s\n", - eld_connection_type_names[e->conn_type]); - snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, - eld_version_names[e->eld_ver]); - snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, - cea_edid_version_names[e->cea_edid_ver]); - snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); - snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id); - snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id); - snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp); - snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai); - snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay); - snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); - snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf); - - snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count); - - for (i = 0; i < e->sad_count; i++) - hdmi_print_sad_info(i, e->sad + i, buffer); + snd_print_eld_info(&eld->info, buffer); } void snd_hdmi_write_eld_info(struct hdmi_eld *eld, struct snd_info_buffer *buffer) { - struct parsed_hdmi_eld *e = &eld->info; + struct snd_parsed_hdmi_eld *e = &eld->info; char line[64]; char name[64]; char *sname; @@ -556,7 +187,7 @@ void snd_hdmi_write_eld_info(struct hdmi_eld *eld, #endif /* CONFIG_SND_PROC_FS */ /* update PCM info based on ELD */ -void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, +void snd_hdmi_eld_update_pcm_info(struct snd_parsed_hdmi_eld *e, struct hda_pcm_stream *hinfo) { u32 rates; @@ -574,17 +205,17 @@ void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, maxbps = 16; channels_max = 2; for (i = 0; i < e->sad_count; i++) { - struct cea_sad *a = &e->sad[i]; + struct snd_cea_sad *a = &e->sad[i]; rates |= a->rates; if (a->channels > channels_max) channels_max = a->channels; if (a->format == AUDIO_CODING_TYPE_LPCM) { - if (a->sample_bits & AC_SUPPCM_BITS_20) { + if (a->sample_bits & ELD_PCM_BITS_20) { formats |= SNDRV_PCM_FMTBIT_S32_LE; if (maxbps < 20) maxbps = 20; } - if (a->sample_bits & AC_SUPPCM_BITS_24) { + if (a->sample_bits & ELD_PCM_BITS_24) { formats |= SNDRV_PCM_FMTBIT_S32_LE; if (maxbps < 24) maxbps = 24; diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 763f79f6f32e..4714057dba85 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -10,6 +10,8 @@ #ifndef __SOUND_HDA_LOCAL_H #define __SOUND_HDA_LOCAL_H +#include + /* We abuse kcontrol_new.subdev field to pass the NID corresponding to * the given new control. If id.subdev has a bit flag HDA_SUBDEV_NID_FLAG, * snd_hda_ctl_add() takes the lower-bit subdev value as a valid NID. @@ -675,61 +677,18 @@ int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol, #define snd_hda_enum_bool_helper_info(kcontrol, uinfo) \ snd_hda_enum_helper_info(kcontrol, uinfo, 0, NULL) -/* - * CEA Short Audio Descriptor data - */ -struct cea_sad { - int channels; - int format; /* (format == 0) indicates invalid SAD */ - int rates; - int sample_bits; /* for LPCM */ - int max_bitrate; /* for AC3...ATRAC */ - int profile; /* for WMAPRO */ -}; - -#define ELD_FIXED_BYTES 20 -#define ELD_MAX_SIZE 256 -#define ELD_MAX_MNL 16 -#define ELD_MAX_SAD 16 - -/* - * ELD: EDID Like Data - */ -struct parsed_hdmi_eld { - /* - * all fields will be cleared before updating ELD - */ - int baseline_len; - int eld_ver; - int cea_edid_ver; - char monitor_name[ELD_MAX_MNL + 1]; - int manufacture_id; - int product_id; - u64 port_id; - int support_hdcp; - int support_ai; - int conn_type; - int aud_synch_delay; - int spk_alloc; - int sad_count; - struct cea_sad sad[ELD_MAX_SAD]; -}; - struct hdmi_eld { bool monitor_present; bool eld_valid; int eld_size; char eld_buffer[ELD_MAX_SIZE]; - struct parsed_hdmi_eld info; + struct snd_parsed_hdmi_eld info; }; int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid, unsigned char *buf, int *eld_size); -int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e, - const unsigned char *buf, int size); -void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e); -void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e, +void snd_hdmi_eld_update_pcm_info(struct snd_parsed_hdmi_eld *e, struct hda_pcm_stream *hinfo); int snd_hdmi_get_eld_ati(struct hda_codec *codec, hda_nid_t nid, diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 643e0496b093..7167989a8d86 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1511,8 +1511,8 @@ static void update_eld(struct hda_codec *codec, if (eld->eld_valid) { if (eld->eld_size <= 0 || - snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer, - eld->eld_size) < 0) { + snd_parse_eld(hda_codec_dev(codec), &eld->info, + eld->eld_buffer, eld->eld_size) < 0) { eld->eld_valid = false; if (repoll) { schedule_delayed_work(&per_pin->work, @@ -1555,7 +1555,7 @@ static void update_eld(struct hda_codec *codec, pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); if (eld->eld_valid) - snd_hdmi_show_eld(codec, &eld->info); + snd_show_eld(hda_codec_dev(codec), &eld->info); eld_changed = (pin_eld->eld_valid != eld->eld_valid); eld_changed |= (pin_eld->monitor_present != eld->monitor_present); From 0ecd24a6d8b251ebd5c8f3a5cb7a9f07f989b132 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 24 Jan 2025 23:14:31 +0200 Subject: [PATCH 029/651] ASoC: hdmi-codec: dump ELD through procfs Use freshly added API and add eld#n files to procfs for the ASoC cards utilizing HDMI codec. This simplifies debugging of the possible ASoC / HDMI / DisplayPort audio issues. Signed-off-by: Dmitry Baryshkov Reviewed-by: Mark Brown Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250124-alsa-hdmi-codec-eld-v1-2-bad045cfaeac@linaro.org --- sound/soc/codecs/hdmi-codec.c | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 69f98975e14a..497376bcd3ff 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -281,6 +281,7 @@ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { struct hdmi_codec_priv { struct hdmi_codec_pdata hcd; uint8_t eld[MAX_ELD_BYTES]; + struct snd_parsed_hdmi_eld eld_parsed; struct snd_pcm_chmap *chmap_info; unsigned int chmap_idx; struct mutex lock; @@ -288,6 +289,7 @@ struct hdmi_codec_priv { struct snd_soc_jack *jack; unsigned int jack_status; u8 iec_status[AES_IEC958_STATUS_SIZE]; + struct snd_info_entry *proc_entry; }; static const struct snd_soc_dapm_widget hdmi_widgets[] = { @@ -469,6 +471,9 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream, if (ret) goto err; + snd_parse_eld(dai->dev, &hcp->eld_parsed, + hcp->eld, sizeof(hcp->eld)); + ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld); if (ret) goto err; @@ -825,8 +830,54 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, return 0; } +#ifdef CONFIG_SND_PROC_FS +static void print_eld_info(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct hdmi_codec_priv *hcp = entry->private_data; + + snd_print_eld_info(&hcp->eld_parsed, buffer); +} + +static int hdmi_dai_proc_new(struct hdmi_codec_priv *hcp, + struct snd_soc_dai *dai) +{ + struct snd_info_entry *entry; + char name[32]; + int err; + + snprintf(name, sizeof(name), "eld#%d", dai->id); + err = snd_card_proc_new(dai->component->card->snd_card, name, &entry); + if (err < 0) + return err; + + snd_info_set_text_ops(entry, hcp, print_eld_info); + hcp->proc_entry = entry; + + return 0; +} + +static void hdmi_dai_proc_free(struct hdmi_codec_priv *hcp) +{ + snd_info_free_entry(hcp->proc_entry); + hcp->proc_entry = NULL; +} +#else +static int hdmi_dai_proc_new(struct hdmi_codec_priv *hcp, + struct snd_soc_dai *dai) +{ + return 0; +} + +static void hdmi_dai_proc_free(struct hdmi_codec_priv *hcp) +{ +} +#endif + static int hdmi_dai_probe(struct snd_soc_dai *dai) { + struct hdmi_codec_priv *hcp = + snd_soc_component_get_drvdata(dai->component); struct snd_soc_dapm_context *dapm; struct hdmi_codec_daifmt *daifmt; struct snd_soc_dapm_route route[] = { @@ -859,6 +910,15 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai) snd_soc_dai_dma_data_set_playback(dai, daifmt); + return hdmi_dai_proc_new(hcp, dai); +} + +static int hdmi_dai_remove(struct snd_soc_dai *dai) +{ + struct hdmi_codec_priv *hcp = + snd_soc_component_get_drvdata(dai->component); + + hdmi_dai_proc_free(hcp); return 0; } @@ -875,11 +935,18 @@ static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp, static void plugged_cb(struct device *dev, bool plugged) { struct hdmi_codec_priv *hcp = dev_get_drvdata(dev); + int ret; if (plugged) { if (hcp->hcd.ops->get_eld) { hcp->hcd.ops->get_eld(dev->parent, hcp->hcd.data, hcp->eld, sizeof(hcp->eld)); + ret = snd_parse_eld(dev, &hcp->eld_parsed, + hcp->eld, sizeof(hcp->eld)); + if (ret < 0) + dev_dbg(dev, "Failed to parse ELD: %d\n", ret); + else + snd_show_eld(dev, &hcp->eld_parsed); } hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT); } else { @@ -926,6 +993,7 @@ static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = { .probe = hdmi_dai_probe, + .remove = hdmi_dai_remove, .startup = hdmi_codec_startup, .shutdown = hdmi_codec_shutdown, .hw_params = hdmi_codec_hw_params, From 1d5efdd4e76e8e81f150c243f6a663e60e091597 Mon Sep 17 00:00:00 2001 From: Jakub Wilk Date: Thu, 30 Jan 2025 19:08:22 +0100 Subject: [PATCH 030/651] ALSA: docs: Fix typo Signed-off-by: Jakub Wilk Link: https://patch.msgid.link/20250130180823.1864-1-jwilk@jwilk.net Signed-off-by: Takashi Iwai --- Documentation/sound/designs/powersave.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/sound/designs/powersave.rst b/Documentation/sound/designs/powersave.rst index 138157452eb9..96f618b3f0b6 100644 --- a/Documentation/sound/designs/powersave.rst +++ b/Documentation/sound/designs/powersave.rst @@ -33,7 +33,7 @@ automatic power-save mode with 10 seconds, write to Note that you might hear click noise/pop when changing the power state. Also, it often takes certain time to wake up from the -power-down to the active state. These are often hardly to fix, so +power-down to the active state. These are often hard to fix, so don't report extra bug reports unless you have a fix patch ;-) For HD-audio interface, there is another module option, From de7d2a70707ef991b8a2996ef1588f1e8b9aba95 Mon Sep 17 00:00:00 2001 From: Jakub Wilk Date: Thu, 30 Jan 2025 19:08:23 +0100 Subject: [PATCH 031/651] ALSA: docs: Fix module paths in /sys It's /sys/module/ (singular), not /sys/modules/. Signed-off-by: Jakub Wilk Link: https://patch.msgid.link/20250130180823.1864-2-jwilk@jwilk.net Signed-off-by: Takashi Iwai --- Documentation/sound/alsa-configuration.rst | 2 +- Documentation/sound/designs/powersave.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sound/alsa-configuration.rst index 04254474fa04..a45174d165eb 100644 --- a/Documentation/sound/alsa-configuration.rst +++ b/Documentation/sound/alsa-configuration.rst @@ -58,7 +58,7 @@ debug 2 = verbose debug messages); This option appears only when ``CONFIG_SND_DEBUG=y``. This option can be dynamically changed via sysfs - /sys/modules/snd/parameters/debug file. + /sys/module/snd/parameters/debug file. Module snd-pcm-oss ------------------ diff --git a/Documentation/sound/designs/powersave.rst b/Documentation/sound/designs/powersave.rst index 96f618b3f0b6..ca7d1e838b4d 100644 --- a/Documentation/sound/designs/powersave.rst +++ b/Documentation/sound/designs/powersave.rst @@ -25,10 +25,10 @@ operations. The ``power_save`` option is exported as writable. This means you can adjust the value via sysfs on the fly. For example, to turn on the automatic power-save mode with 10 seconds, write to -``/sys/modules/snd_ac97_codec/parameters/power_save`` (usually as root): +``/sys/module/snd_ac97_codec/parameters/power_save`` (usually as root): :: - # echo 10 > /sys/modules/snd_ac97_codec/parameters/power_save + # echo 10 > /sys/module/snd_ac97_codec/parameters/power_save Note that you might hear click noise/pop when changing the power From 678681828bf4abfd3c31f36390d2097682141d11 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 5 Feb 2025 14:24:44 +0800 Subject: [PATCH 032/651] ASoC: dmic: Add DSD big endian format support Add DSD big endian format support in this generic dmic driver: DSD_U16_BE and DSD_U32_BE. Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20250205062444.1694810-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/codecs/dmic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 4fd6f97e5a49..0388f115470c 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -85,7 +85,9 @@ static struct snd_soc_dai_driver dmic_dai = { | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_DSD_U8 | SNDRV_PCM_FMTBIT_DSD_U16_LE - | SNDRV_PCM_FMTBIT_DSD_U32_LE, + | SNDRV_PCM_FMTBIT_DSD_U32_LE + | SNDRV_PCM_FMTBIT_DSD_U16_BE + | SNDRV_PCM_FMTBIT_DSD_U32_BE, }, .ops = &dmic_dai_ops, }; From b3d993c7566fed1c027c5c18f3ef482ba8e6307a Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Tue, 4 Feb 2025 16:33:32 +0100 Subject: [PATCH 033/651] ASoC: amd: acp: Use str_low_high() helper function Remove hard-coded strings by using the str_low_high() helper function. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250204153333.3045-3-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c b/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c index 2b0aa270a3e9..eb5d4a5baef2 100644 --- a/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c +++ b/sound/soc/amd/acp/acp3x-es83xx/acp3x-es83xx.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "../acp-mach.h" #include "acp3x-es83xx.h" @@ -241,9 +242,9 @@ static int acp3x_es83xx_configure_gpios(struct acp3x_es83xx_private *priv) dev_info(priv->codec_dev, "speaker gpio %d active %s, headphone gpio %d active %s\n", priv->enable_spk_gpio.crs_entry_index, - priv->enable_spk_gpio.active_low ? "low" : "high", + str_low_high(priv->enable_spk_gpio.active_low), priv->enable_hp_gpio.crs_entry_index, - priv->enable_hp_gpio.active_low ? "low" : "high"); + str_low_high(priv->enable_hp_gpio.active_low)); return 0; } From 3f75771987f32a9f512c8944e70e343f8c6d71c1 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Tue, 4 Feb 2025 16:38:04 +0100 Subject: [PATCH 034/651] ASoC: SOF: mediatek: Use str_on_off() helper function Remove hard-coded strings by using the str_on_off() helper function. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250204153806.3587-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8195/mt8195-clk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-clk.c b/sound/soc/sof/mediatek/mt8195/mt8195-clk.c index 7cffcad00f9b..2c2c4cd323fc 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195-clk.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195-clk.c @@ -8,6 +8,7 @@ #include #include +#include #include "mt8195.h" #include "mt8195-clk.h" #include "../adsp_helper.h" @@ -114,7 +115,7 @@ static int adsp_default_clk_init(struct snd_sof_dev *sdev, bool enable) struct adsp_priv *priv = sdev->pdata->hw_pdata; int ret; - dev_dbg(dev, "%s: %s\n", __func__, enable ? "on" : "off"); + dev_dbg(dev, "%s: %s\n", __func__, str_on_off(enable)); if (enable) { ret = clk_set_parent(priv->clk[CLK_TOP_ADSP], From 185ac20a7b055e025027d303b63dab456b4f5d5e Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 4 Feb 2025 15:52:24 +0800 Subject: [PATCH 035/651] ASoC: rt722: get lane mapping property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rt722 supports multi-lane and the driver doesn't call sdw_slave_read_prop() to get all properties. Add sdw_slave_read_lane_mapping() to get the required lane mapping property. Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250204075224.162661-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt722-sdca-sdw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c index 2b0f82697b47..7a38fcf63143 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.c +++ b/sound/soc/codecs/rt722-sdca-sdw.c @@ -224,6 +224,8 @@ static int rt722_sdca_read_prop(struct sdw_slave *slave) unsigned long addr; struct sdw_dpn_prop *dpn; + sdw_slave_read_lane_mapping(slave); + prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; From 6603c5133daadbb3277fbd93be0d0d5b8ec928e8 Mon Sep 17 00:00:00 2001 From: Andrei Simion Date: Mon, 3 Feb 2025 11:11:12 +0200 Subject: [PATCH 036/651] ASoC: dt-bindings: atmel,at91-ssc: Convert to YAML format Convert devicetree binding atmel-ssc.txt to YAML format. Update the documentation supported file for MICROCHIP SSC DRIVER. Signed-off-by: Andrei Simion Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250203091111.21667-1-andrei.simion@microchip.com Signed-off-by: Mark Brown --- .../devicetree/bindings/misc/atmel-ssc.txt | 50 --------- .../bindings/sound/atmel,at91-ssc.yaml | 104 ++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 105 insertions(+), 51 deletions(-) delete mode 100644 Documentation/devicetree/bindings/misc/atmel-ssc.txt create mode 100644 Documentation/devicetree/bindings/sound/atmel,at91-ssc.yaml diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt deleted file mode 100644 index f9fb412642fe..000000000000 --- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt +++ /dev/null @@ -1,50 +0,0 @@ -* Atmel SSC driver. - -Required properties: -- compatible: "atmel,at91rm9200-ssc" or "atmel,at91sam9g45-ssc" - - atmel,at91rm9200-ssc: support pdc transfer - - atmel,at91sam9g45-ssc: support dma transfer -- reg: Should contain SSC registers location and length -- interrupts: Should contain SSC interrupt -- clock-names: tuple listing input clock names. - Required elements: "pclk" -- clocks: phandles to input clocks. - - -Required properties for devices compatible with "atmel,at91sam9g45-ssc": -- dmas: DMA specifier, consisting of a phandle to DMA controller node, - the memory interface and SSC DMA channel ID (for tx and rx). - See Documentation/devicetree/bindings/dma/atmel-dma.txt for details. -- dma-names: Must be "tx", "rx". - -Optional properties: - - atmel,clk-from-rk-pin: bool property. - - When SSC works in slave mode, according to the hardware design, the - clock can get from TK pin, and also can get from RK pin. So, add - this parameter to choose where the clock from. - - By default the clock is from TK pin, if the clock from RK pin, this - property is needed. - - #sound-dai-cells: Should contain <0>. - - This property makes the SSC into an automatically registered DAI. - -Examples: -- PDC transfer: -ssc0: ssc@fffbc000 { - compatible = "atmel,at91rm9200-ssc"; - reg = <0xfffbc000 0x4000>; - interrupts = <14 4 5>; - clocks = <&ssc0_clk>; - clock-names = "pclk"; -}; - -- DMA transfer: -ssc0: ssc@f0010000 { - compatible = "atmel,at91sam9g45-ssc"; - reg = <0xf0010000 0x4000>; - interrupts = <28 4 5>; - dmas = <&dma0 1 13>, - <&dma0 1 14>; - dma-names = "tx", "rx"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>; -}; diff --git a/Documentation/devicetree/bindings/sound/atmel,at91-ssc.yaml b/Documentation/devicetree/bindings/sound/atmel,at91-ssc.yaml new file mode 100644 index 000000000000..a05e61431824 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/atmel,at91-ssc.yaml @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/atmel,at91-ssc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Atmel Serial Synchronous Serial (SSC) + +maintainers: + - Andrei Simion + +description: + The Atmel Synchronous Serial Controller (SSC) provides a versatile + synchronous communication link for audio and telecom applications, + supporting protocols like I2S, Short Frame Sync, and Long Frame Sync. + +properties: + compatible: + enum: + - atmel,at91rm9200-ssc + - atmel,at91sam9g45-ssc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: pclk + + dmas: + items: + - description: TX DMA Channel + - description: RX DMA Channel + + dma-names: + items: + - const: tx + - const: rx + + atmel,clk-from-rk-pin: + description: + Specify the clock source for the SSC (Synchronous Serial Controller) + when operating in slave mode. By default, the clock is sourced from + the TK pin. + type: boolean + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +allOf: + - $ref: dai-common.yaml# + - if: + properties: + compatible: + contains: + enum: + - atmel,at91sam9g45-ssc + then: + required: + - dmas + - dma-names + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + ssc@100000 { + compatible = "atmel,at91sam9g45-ssc"; + reg = <0x100000 0x4000>; + interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>; + dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(38))>, + <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(39))>; + dma-names = "tx", "rx"; + clocks = <&pmc PMC_TYPE_PERIPHERAL 28>; + clock-names = "pclk"; + #sound-dai-cells = <0>; + }; + + ssc@c00000 { + compatible = "atmel,at91rm9200-ssc"; + reg = <0xc00000 0x4000>; + interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 14>; + clock-names = "pclk"; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 896a307fa065..02f694180faa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15632,7 +15632,7 @@ M: Claudiu Beznea M: Andrei Simion L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported -F: Documentation/devicetree/bindings/misc/atmel-ssc.txt +F: Documentation/devicetree/bindings/sound/atmel,at91-ssc.yaml F: drivers/misc/atmel-ssc.c F: include/linux/atmel-ssc.h From 169ec0a541aac8afb215ab591b0fd53276686014 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 6 Feb 2025 11:28:25 +0200 Subject: [PATCH 037/651] ASoC: SOF: Relocate and rework functionality for PCM stream freeing Move the sof_pcm_stream_free() from sof-audio.c to pcm.c as static function and add wrapper to free all active stream, which is going to be used in ipc3/4 topology code (removes duplicated code). With this change most of the PCM stream related code is located in one source file for easier lookup and simplified flow. Signed-off-by: Peter Ujfalusi Reviewed-by: Liam Girdwood Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20250206092828.7569-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 20 ++------- sound/soc/sof/ipc4-topology.c | 18 +------- sound/soc/sof/pcm.c | 78 +++++++++++++++++++++++++++++++++++ sound/soc/sof/sof-audio.c | 49 ---------------------- sound/soc/sof/sof-audio.h | 3 +- 5 files changed, 84 insertions(+), 84 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index e98b53b67d12..473d416bc910 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -2386,28 +2386,16 @@ static int sof_ipc3_set_up_all_pipelines(struct snd_sof_dev *sdev, bool verify) static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev) { struct snd_sof_widget *swidget; - struct snd_sof_pcm *spcm; - int dir, ret; + int ret; /* * free all PCMs and their associated DAPM widgets if their connected DAPM widget * list is not NULL. This should only be true for paused streams at this point. * This is equivalent to the handling of FE DAI suspend trigger for running streams. */ - list_for_each_entry(spcm, &sdev->pcm_list, list) { - for_each_pcm_streams(dir) { - struct snd_pcm_substream *substream = spcm->stream[dir].substream; - - if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) - continue; - - if (spcm->stream[dir].list) { - ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true); - if (ret < 0) - return ret; - } - } - } + ret = sof_pcm_free_all_streams(sdev); + if (ret) + return ret; /* * free any left over DAI widgets. This is equivalent to the handling of suspend trigger diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index c04c62478827..21e29bfd4b22 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -3401,9 +3401,6 @@ static int sof_ipc4_dai_get_param(struct snd_sof_dev *sdev, struct snd_sof_dai * static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify) { - struct snd_sof_pcm *spcm; - int dir, ret; - /* * This function is called during system suspend, we need to make sure * that all streams have been freed up. @@ -3415,21 +3412,8 @@ static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif * * This will also make sure that paused streams handled correctly. */ - list_for_each_entry(spcm, &sdev->pcm_list, list) { - for_each_pcm_streams(dir) { - struct snd_pcm_substream *substream = spcm->stream[dir].substream; - if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored) - continue; - - if (spcm->stream[dir].list) { - ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true); - if (ret < 0) - return ret; - } - } - } - return 0; + return sof_pcm_free_all_streams(sdev); } static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 35a7462d8b69..709baa1b0bd6 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -191,6 +191,84 @@ static int sof_pcm_hw_params(struct snd_soc_component *component, return 0; } +static int sof_pcm_stream_free(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + struct snd_sof_pcm *spcm, int dir, + bool free_widget_list) +{ + const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); + int ret; + int err = 0; + + if (spcm->prepared[substream->stream]) { + /* stop DMA first if needed */ + if (pcm_ops && pcm_ops->platform_stop_during_hw_free) + snd_sof_pcm_platform_trigger(sdev, substream, + SNDRV_PCM_TRIGGER_STOP); + + /* free PCM in the DSP */ + if (pcm_ops && pcm_ops->hw_free) { + ret = pcm_ops->hw_free(sdev->component, substream); + if (ret < 0) { + dev_err(sdev->dev, "%s: pcm_ops hw_free failed %d\n", + __func__, ret); + err = ret; + } + } + + spcm->prepared[substream->stream] = false; + spcm->pending_stop[substream->stream] = false; + } + + /* reset the DMA */ + ret = snd_sof_pcm_platform_hw_free(sdev, substream); + if (ret < 0) { + dev_err(sdev->dev, "%s: platform hw free failed %d\n", + __func__, ret); + if (!err) + err = ret; + } + + /* free widget list */ + if (free_widget_list) { + ret = sof_widget_list_free(sdev, spcm, dir); + if (ret < 0) { + dev_err(sdev->dev, "%s: sof_widget_list_free failed %d\n", + __func__, ret); + if (!err) + err = ret; + } + } + + return err; +} + +int sof_pcm_free_all_streams(struct snd_sof_dev *sdev) +{ + struct snd_pcm_substream *substream; + struct snd_sof_pcm *spcm; + int dir, ret; + + list_for_each_entry(spcm, &sdev->pcm_list, list) { + for_each_pcm_streams(dir) { + substream = spcm->stream[dir].substream; + + if (!substream || !substream->runtime || + spcm->stream[dir].suspend_ignored) + continue; + + if (spcm->stream[dir].list) { + ret = sof_pcm_stream_free(sdev, substream, spcm, + dir, true); + if (ret < 0) + return ret; + } + } + } + + return 0; +} + static int sof_pcm_hw_free(struct snd_soc_component *component, struct snd_pcm_substream *substream) { diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 9a52781bf8d8..a9664b4cf43f 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -829,55 +829,6 @@ bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev) return false; } -int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, - struct snd_sof_pcm *spcm, int dir, bool free_widget_list) -{ - const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm); - int ret; - int err = 0; - - if (spcm->prepared[substream->stream]) { - /* stop DMA first if needed */ - if (pcm_ops && pcm_ops->platform_stop_during_hw_free) - snd_sof_pcm_platform_trigger(sdev, substream, SNDRV_PCM_TRIGGER_STOP); - - /* free PCM in the DSP */ - if (pcm_ops && pcm_ops->hw_free) { - ret = pcm_ops->hw_free(sdev->component, substream); - if (ret < 0) { - dev_err(sdev->dev, "%s: pcm_ops hw_free failed %d\n", - __func__, ret); - err = ret; - } - } - - spcm->prepared[substream->stream] = false; - spcm->pending_stop[substream->stream] = false; - } - - /* reset the DMA */ - ret = snd_sof_pcm_platform_hw_free(sdev, substream); - if (ret < 0) { - dev_err(sdev->dev, "%s: platform hw free failed %d\n", - __func__, ret); - if (!err) - err = ret; - } - - /* free widget list */ - if (free_widget_list) { - ret = sof_widget_list_free(sdev, spcm, dir); - if (ret < 0) { - dev_err(sdev->dev, "%s: sof_widget_list_free failed %d\n", - __func__, ret); - if (!err) - err = ret; - } - } - - return err; -} - /* * Generic object lookup APIs. */ diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 62f3c11a9216..7d4810924682 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -649,8 +649,7 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int dir); int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm); -int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, - struct snd_sof_pcm *spcm, int dir, bool free_widget_list); +int sof_pcm_free_all_streams(struct snd_sof_dev *sdev); int get_token_u32(void *elem, void *object, u32 offset); int get_token_u16(void *elem, void *object, u32 offset); int get_token_comp_format(void *elem, void *object, u32 offset); From 4d2ea16576c8aa1437048cf436bff85653f139fe Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 6 Feb 2025 11:28:26 +0200 Subject: [PATCH 038/651] ASoC: SOF: pcm: Move period/buffer configuration print after platform open The platform specific pcm_open call via snd_sof_pcm_platform_open() can modify the initial buffer configuration via constraints. Move the prints as last step in the sof_pcm_open() function to reflect the final setup. Signed-off-by: Peter Ujfalusi Reviewed-by: Liam Girdwood Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20250206092828.7569-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pcm.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 709baa1b0bd6..d09be241e95e 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -536,15 +536,6 @@ static int sof_pcm_open(struct snd_soc_component *component, */ runtime->hw.buffer_bytes_max = le32_to_cpu(caps->buffer_size_max); - dev_dbg(component->dev, "period min %zd max %zd bytes\n", - runtime->hw.period_bytes_min, - runtime->hw.period_bytes_max); - dev_dbg(component->dev, "period count %d max %d\n", - runtime->hw.periods_min, - runtime->hw.periods_max); - dev_dbg(component->dev, "buffer max %zd bytes\n", - runtime->hw.buffer_bytes_max); - /* set wait time - TODO: come from topology */ substream->wait_time = 500; @@ -554,10 +545,21 @@ static int sof_pcm_open(struct snd_soc_component *component, spcm->prepared[substream->stream] = false; ret = snd_sof_pcm_platform_open(sdev, substream); - if (ret < 0) + if (ret < 0) { dev_err(component->dev, "error: pcm open failed %d\n", ret); + return ret; + } - return ret; + dev_dbg(component->dev, "period bytes min %zd, max %zd\n", + runtime->hw.period_bytes_min, + runtime->hw.period_bytes_max); + dev_dbg(component->dev, "period count min %d, max %d\n", + runtime->hw.periods_min, + runtime->hw.periods_max); + dev_dbg(component->dev, "buffer bytes max %zd\n", + runtime->hw.buffer_bytes_max); + + return 0; } static int sof_pcm_close(struct snd_soc_component *component, From 860693187c597645b28a421d8acb26428b8afd3f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 6 Feb 2025 11:28:27 +0200 Subject: [PATCH 039/651] ASoC: SOF: pcm: Add snd_sof_pcm specific wrappers for dev_dbg() and dev_err() Introduce spcm_dbg() and spcm_err() macros to provide consistent printing for debug and error messages which includes usable information in the print's prefix. Update the prints in pcm.c, ipc3-pcm.c and ipc4-pcm.c to take advantage of the features provided by the macros. Signed-off-by: Peter Ujfalusi Reviewed-by: Liam Girdwood Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20250206092828.7569-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-pcm.c | 13 +++--- sound/soc/sof/ipc4-pcm.c | 16 ++++--- sound/soc/sof/pcm.c | 95 +++++++++++++++++---------------------- sound/soc/sof/sof-audio.h | 14 ++++++ 4 files changed, 72 insertions(+), 66 deletions(-) diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index 1c1b8f595367..90ef5d99f626 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -117,22 +117,23 @@ static int sof_ipc3_pcm_hw_params(struct snd_soc_component *component, if (platform_params->cont_update_posn) pcm.params.cont_update_posn = 1; - dev_dbg(component->dev, "stream_tag %d", pcm.params.stream_tag); + spcm_dbg(spcm, substream->stream, "stream_tag %d\n", + pcm.params.stream_tag); /* send hw_params IPC to the DSP */ ret = sof_ipc_tx_message(sdev->ipc, &pcm, sizeof(pcm), &ipc_params_reply, sizeof(ipc_params_reply)); if (ret < 0) { - dev_err(component->dev, "HW params ipc failed for stream %d\n", - pcm.params.stream_tag); + spcm_err(spcm, substream->stream, + "STREAM_PCM_PARAMS ipc failed for stream_tag %d\n", + pcm.params.stream_tag); return ret; } ret = snd_sof_set_stream_data_offset(sdev, &spcm->stream[substream->stream], ipc_params_reply.posn_offset); if (ret < 0) { - dev_err(component->dev, "%s: invalid stream data offset for PCM %d\n", - __func__, spcm->pcm.pcm_id); + spcm_err(spcm, substream->stream, "invalid stream data offset\n"); return ret; } @@ -171,7 +172,7 @@ static int sof_ipc3_pcm_trigger(struct snd_soc_component *component, stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; break; default: - dev_err(component->dev, "Unhandled trigger cmd %d\n", cmd); + spcm_err(spcm, substream->stream, "Unhandled trigger cmd %d\n", cmd); return -EINVAL; } diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 18fff2df76f9..5ec109094031 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -313,7 +313,7 @@ static int sof_ipc4_chain_dma_trigger(struct snd_sof_dev *sdev, set_fifo_size = false; break; default: - dev_err(sdev->dev, "Unexpected state %d", state); + spcm_err(spcm, direction, "Unexpected pipeline state %d\n", state); return -EINVAL; } @@ -333,8 +333,8 @@ static int sof_ipc4_chain_dma_trigger(struct snd_sof_dev *sdev, struct sof_ipc4_pipeline *pipeline = pipe_widget->private; if (!pipeline->use_chain_dma) { - dev_err(sdev->dev, - "All pipelines in chained DMA stream should have use_chain_dma attribute set."); + spcm_err(spcm, direction, + "All pipelines in chained DMA path should have use_chain_dma attribute set."); return -EINVAL; } @@ -389,12 +389,12 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, int ret; int i; - dev_dbg(sdev->dev, "trigger cmd: %d state: %d\n", cmd, state); - spcm = snd_sof_find_spcm_dai(component, rtd); if (!spcm) return -EINVAL; + spcm_dbg(spcm, substream->stream, "cmd: %d, state: %d\n", cmd, state); + pipeline_list = &spcm->stream[substream->stream].pipeline_list; /* nothing to trigger if the list is empty */ @@ -465,7 +465,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, */ ret = sof_ipc4_set_multi_pipeline_state(sdev, SOF_IPC4_PIPE_PAUSED, trigger_list); if (ret < 0) { - dev_err(sdev->dev, "failed to pause all pipelines\n"); + spcm_err(spcm, substream->stream, "failed to pause all pipelines\n"); goto free; } @@ -494,7 +494,9 @@ skip_pause_transition: /* else set the RUNNING/RESET state in the DSP */ ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list); if (ret < 0) { - dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state); + spcm_err(spcm, substream->stream, + "failed to set final state %d for all pipelines\n", + state); /* * workaround: if the firmware is crashed while setting the * pipelines to reset state we must ignore the error code and diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index d09be241e95e..372ed71a17aa 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -99,8 +99,8 @@ sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_run ret = snd_soc_dapm_dai_get_connected_widgets(dai, dir, &list, dpcm_end_walk_at_be); if (ret < 0) { - dev_err(sdev->dev, "error: dai %s has no valid %s path\n", dai->name, - snd_pcm_direction_name(dir)); + spcm_err(spcm, dir, "dai %s has no valid %s path\n", + dai->name, snd_pcm_direction_name(dir)); return ret; } @@ -108,8 +108,7 @@ sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_run ret = sof_widget_list_setup(sdev, spcm, params, platform_params, dir); if (ret < 0) { - dev_err(sdev->dev, "error: failed widget list set up for pcm %d dir %d\n", - spcm->pcm.pcm_id, dir); + spcm_err(spcm, dir, "Widget list set up failed\n"); spcm->stream[dir].list = NULL; snd_soc_dapm_dai_free_widgets(&list); return ret; @@ -139,6 +138,8 @@ static int sof_pcm_hw_params(struct snd_soc_component *component, if (!spcm) return -EINVAL; + spcm_dbg(spcm, substream->stream, "Entry: hw_params\n"); + /* * Handle repeated calls to hw_params() without free_pcm() in * between. At least ALSA OSS emulation depends on this. @@ -151,12 +152,9 @@ static int sof_pcm_hw_params(struct snd_soc_component *component, spcm->prepared[substream->stream] = false; } - dev_dbg(component->dev, "pcm: hw params stream %d dir %d\n", - spcm->pcm.pcm_id, substream->stream); - ret = snd_sof_pcm_platform_hw_params(sdev, substream, params, &platform_params); if (ret < 0) { - dev_err(component->dev, "platform hw params failed\n"); + spcm_err(spcm, substream->stream, "platform hw params failed\n"); return ret; } @@ -210,8 +208,8 @@ static int sof_pcm_stream_free(struct snd_sof_dev *sdev, if (pcm_ops && pcm_ops->hw_free) { ret = pcm_ops->hw_free(sdev->component, substream); if (ret < 0) { - dev_err(sdev->dev, "%s: pcm_ops hw_free failed %d\n", - __func__, ret); + spcm_err(spcm, substream->stream, + "pcm_ops->hw_free failed %d\n", ret); err = ret; } } @@ -223,8 +221,8 @@ static int sof_pcm_stream_free(struct snd_sof_dev *sdev, /* reset the DMA */ ret = snd_sof_pcm_platform_hw_free(sdev, substream); if (ret < 0) { - dev_err(sdev->dev, "%s: platform hw free failed %d\n", - __func__, ret); + spcm_err(spcm, substream->stream, + "platform hw free failed %d\n", ret); if (!err) err = ret; } @@ -233,8 +231,8 @@ static int sof_pcm_stream_free(struct snd_sof_dev *sdev, if (free_widget_list) { ret = sof_widget_list_free(sdev, spcm, dir); if (ret < 0) { - dev_err(sdev->dev, "%s: sof_widget_list_free failed %d\n", - __func__, ret); + spcm_err(spcm, substream->stream, + "sof_widget_list_free failed %d\n", ret); if (!err) err = ret; } @@ -285,8 +283,7 @@ static int sof_pcm_hw_free(struct snd_soc_component *component, if (!spcm) return -EINVAL; - dev_dbg(component->dev, "pcm: free stream %d dir %d\n", - spcm->pcm.pcm_id, substream->stream); + spcm_dbg(spcm, substream->stream, "Entry: hw_free\n"); ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream, true); @@ -311,6 +308,8 @@ static int sof_pcm_prepare(struct snd_soc_component *component, if (!spcm) return -EINVAL; + spcm_dbg(spcm, substream->stream, "Entry: prepare\n"); + if (spcm->prepared[substream->stream]) { if (!spcm->pending_stop[substream->stream]) return 0; @@ -324,15 +323,12 @@ static int sof_pcm_prepare(struct snd_soc_component *component, return ret; } - dev_dbg(component->dev, "pcm: prepare stream %d dir %d\n", - spcm->pcm.pcm_id, substream->stream); - /* set hw_params */ ret = sof_pcm_hw_params(component, substream, &spcm->params[substream->stream]); if (ret < 0) { - dev_err(component->dev, - "error: set pcm hw_params after resume\n"); + spcm_err(spcm, substream->stream, + "failed to set hw_params after resume\n"); return ret; } @@ -362,8 +358,7 @@ static int sof_pcm_trigger(struct snd_soc_component *component, if (!spcm) return -EINVAL; - dev_dbg(component->dev, "pcm: trigger stream %d dir %d cmd %d\n", - spcm->pcm.pcm_id, substream->stream, cmd); + spcm_dbg(spcm, substream->stream, "Entry: trigger (cmd: %d)\n", cmd); spcm->pending_stop[substream->stream] = false; @@ -412,7 +407,7 @@ static int sof_pcm_trigger(struct snd_soc_component *component, reset_hw_params = true; break; default: - dev_err(component->dev, "Unhandled trigger cmd %d\n", cmd); + spcm_err(spcm, substream->stream, "Unhandled trigger cmd %d\n", cmd); return -EINVAL; } @@ -514,9 +509,7 @@ static int sof_pcm_open(struct snd_soc_component *component, if (!spcm) return -EINVAL; - dev_dbg(component->dev, "pcm: open stream %d dir %d\n", - spcm->pcm.pcm_id, substream->stream); - + spcm_dbg(spcm, substream->stream, "Entry: open\n"); caps = &spcm->pcm.caps[substream->stream]; @@ -546,18 +539,16 @@ static int sof_pcm_open(struct snd_soc_component *component, ret = snd_sof_pcm_platform_open(sdev, substream); if (ret < 0) { - dev_err(component->dev, "error: pcm open failed %d\n", ret); + spcm_err(spcm, substream->stream, + "platform pcm open failed %d\n", ret); return ret; } - dev_dbg(component->dev, "period bytes min %zd, max %zd\n", - runtime->hw.period_bytes_min, - runtime->hw.period_bytes_max); - dev_dbg(component->dev, "period count min %d, max %d\n", - runtime->hw.periods_min, - runtime->hw.periods_max); - dev_dbg(component->dev, "buffer bytes max %zd\n", - runtime->hw.buffer_bytes_max); + spcm_dbg(spcm, substream->stream, "period bytes min %zd, max %zd\n", + runtime->hw.period_bytes_min, runtime->hw.period_bytes_max); + spcm_dbg(spcm, substream->stream, "period count min %d, max %d\n", + runtime->hw.periods_min, runtime->hw.periods_max); + spcm_dbg(spcm, substream->stream, "buffer bytes max %zd\n", runtime->hw.buffer_bytes_max); return 0; } @@ -578,13 +569,12 @@ static int sof_pcm_close(struct snd_soc_component *component, if (!spcm) return -EINVAL; - dev_dbg(component->dev, "pcm: close stream %d dir %d\n", - spcm->pcm.pcm_id, substream->stream); + spcm_dbg(spcm, substream->stream, "Entry: close\n"); err = snd_sof_pcm_platform_close(sdev, substream); if (err < 0) { - dev_err(component->dev, "error: pcm close failed %d\n", - err); + spcm_err(spcm, substream->stream, + "platform pcm close failed %d\n", err); /* * keep going, no point in preventing the close * from happening @@ -616,7 +606,8 @@ static int sof_pcm_new(struct snd_soc_component *component, return 0; } - dev_dbg(component->dev, "creating new PCM %s\n", spcm->pcm.pcm_name); + dev_dbg(spcm->scomp->dev, "pcm%u (%s): Entry: pcm_construct\n", + spcm->pcm.pcm_id, spcm->pcm.pcm_name); /* do we need to pre-allocate playback audio buffer pages */ if (!spcm->pcm.playback) @@ -624,16 +615,15 @@ static int sof_pcm_new(struct snd_soc_component *component, caps = &spcm->pcm.caps[stream]; - /* pre-allocate playback audio buffer pages */ - dev_dbg(component->dev, - "spcm: allocate %s playback DMA buffer size 0x%x max 0x%x\n", - caps->name, caps->buffer_size_min, caps->buffer_size_max); - if (!pcm->streams[stream].substream) { - dev_err(component->dev, "error: NULL playback substream!\n"); + spcm_err(spcm, stream, "NULL playback substream!\n"); return -EINVAL; } + /* pre-allocate playback audio buffer pages */ + spcm_dbg(spcm, stream, "allocate %s playback DMA buffer size 0x%x max 0x%x\n", + caps->name, caps->buffer_size_min, caps->buffer_size_max); + snd_pcm_set_managed_buffer(pcm->streams[stream].substream, SNDRV_DMA_TYPE_DEV_SG, sdev->dev, 0, le32_to_cpu(caps->buffer_size_max)); @@ -646,16 +636,15 @@ capture: caps = &spcm->pcm.caps[stream]; - /* pre-allocate capture audio buffer pages */ - dev_dbg(component->dev, - "spcm: allocate %s capture DMA buffer size 0x%x max 0x%x\n", - caps->name, caps->buffer_size_min, caps->buffer_size_max); - if (!pcm->streams[stream].substream) { - dev_err(component->dev, "error: NULL capture substream!\n"); + spcm_err(spcm, stream, "NULL capture substream!\n"); return -EINVAL; } + /* pre-allocate capture audio buffer pages */ + spcm_dbg(spcm, stream, "allocate %s capture DMA buffer size 0x%x max 0x%x\n", + caps->name, caps->buffer_size_min, caps->buffer_size_max); + snd_pcm_set_managed_buffer(pcm->streams[stream].substream, SNDRV_DMA_TYPE_DEV_SG, sdev->dev, 0, le32_to_cpu(caps->buffer_size_max)); diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 7d4810924682..36ab75e11779 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -617,6 +617,20 @@ struct snd_sof_pcm *snd_sof_find_spcm_comp(struct snd_soc_component *scomp, void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream); void snd_sof_pcm_init_elapsed_work(struct work_struct *work); +/* + * snd_sof_pcm specific wrappers for dev_dbg() and dev_err() to provide + * consistent and useful prints. + */ +#define spcm_dbg(__spcm, __dir, __fmt, ...) \ + dev_dbg((__spcm)->scomp->dev, "pcm%u (%s), dir %d: " __fmt, \ + (__spcm)->pcm.pcm_id, (__spcm)->pcm.pcm_name, __dir, \ + ##__VA_ARGS__) + +#define spcm_err(__spcm, __dir, __fmt, ...) \ + dev_err((__spcm)->scomp->dev, "%s: pcm%u (%s), dir %d: " __fmt, \ + __func__, (__spcm)->pcm.pcm_id, (__spcm)->pcm.pcm_name, __dir, \ + ##__VA_ARGS__) + #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS) void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream); void snd_sof_compr_init_elapsed_work(struct work_struct *work); From 583348bd65ceaf4a5067a6267dd236929e1b4b37 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 6 Feb 2025 11:28:28 +0200 Subject: [PATCH 040/651] ASoC: SOF: ipc4-topology: Improve the information in prepare_copier prints It is useful to know the explicit type and if the copier (host/dai) is configured to use ChainDMA or not and also the stream_tag for the host copier. Change the prints to carry more information for debugging purposes. Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Reviewed-by: Liam Girdwood Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20250206092828.7569-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 21e29bfd4b22..a23f55ed5696 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1815,15 +1815,19 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, bool single_output_bitdepth; int i; - dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); - switch (swidget->id) { case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: { + struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; struct sof_ipc4_gtw_attributes *gtw_attr; - struct snd_sof_widget *pipe_widget; - struct sof_ipc4_pipeline *pipeline; + + dev_dbg(sdev->dev, + "Host copier %s, type %d, ChainDMA: %s, stream_tag: %d\n", + swidget->widget->name, swidget->id, + str_yes_no(pipeline->use_chain_dma), + platform_params->stream_tag); /* parse the deep buffer dma size */ ret = sof_update_ipc_object(scomp, &deep_buffer_dma_ms, @@ -1840,9 +1844,6 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, copier_data = &ipc4_copier->data; available_fmt = &ipc4_copier->available_fmt; - pipe_widget = swidget->spipe->pipe_widget; - pipeline = pipe_widget->private; - if (pipeline->use_chain_dma) { u32 host_dma_id; u32 fifo_size; @@ -1896,6 +1897,10 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + dev_dbg(sdev->dev, "Dai copier %s, type %d, ChainDMA: %s\n", + swidget->widget->name, swidget->id, + str_yes_no(pipeline->use_chain_dma)); + if (pipeline->use_chain_dma) return 0; @@ -1929,6 +1934,9 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, } case snd_soc_dapm_buffer: { + dev_dbg(sdev->dev, "Module copier %s, type %d\n", + swidget->widget->name, swidget->id); + ipc4_copier = (struct sof_ipc4_copier *)swidget->private; copier_data = &ipc4_copier->data; available_fmt = &ipc4_copier->available_fmt; From 72826381215e2f9d2bd2f32f63f76a80942b7fdf Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Thu, 6 Feb 2025 16:52:22 +0530 Subject: [PATCH 041/651] ASoC: dt-bindings: wcd937x-sdw: Add static channel mapping support Add static channel mapping between master and slave rx/tx ports for Qualcomm wcd937x soundwire codec. Currently, the channel map index value for each soundwire port is hardcoded in the wcd937x-sdw driver, and the same channel map index value is configured in the soundwire master. The Qualcomm board like the QCM6490-IDP require static channel map settings for the soundwire master and slave ports. If another boards which are using enable wcd937x, the channel mapping index values between master and slave may be different depending on the board hw design and requirements. If the above properties are not used in a SoC specific device tree, the channel mapping index values are set to default. With the introduction of the following channel mapping properties, it is now possible to configure the master channel mapping directly from the device tree. The qcom,tx-channel-mapping property specifies the static channel mapping between the slave and master tx ports in the order of slave port channels which is adc1, adc2, adc3, adc4, dmic0, dmic1, mbhc, dmic2, dmic3, dmci4, dmic5, dmic6, dmic7. The qcom,rx-channel-mapping property specifies the static channel mapping between the slave and master rx ports in the order of slave port channels which is hph_l, hph_r, clsh, comp_l, comp_r, lo, dsd_r, dsd_l. Signed-off-by: Mohammad Rafi Shaik Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250206112225.3270400-2-quic_mohs@quicinc.com Signed-off-by: Mark Brown --- .../bindings/sound/qcom,wcd937x-sdw.yaml | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd937x-sdw.yaml b/Documentation/devicetree/bindings/sound/qcom,wcd937x-sdw.yaml index d3cf8f59cb23..c8543f969ebb 100644 --- a/Documentation/devicetree/bindings/sound/qcom,wcd937x-sdw.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,wcd937x-sdw.yaml @@ -58,6 +58,40 @@ properties: items: enum: [1, 2, 3, 4, 5] + qcom,tx-channel-mapping: + description: | + Specifies static channel mapping between slave and master tx port + channels. + In the order of slave port channels which is adc1, adc2, adc3, + dmic0, dmic1, mbhc, dmic2, dmic3, dmci4, dmic5, dmic6, dmic7. + $ref: /schemas/types.yaml#/definitions/uint8-array + minItems: 12 + maxItems: 12 + additionalItems: false + items: + enum: + - 1 # WCD9370_SWRM_CH1 + - 2 # WCD9370_SWRM_CH2 + - 3 # WCD9370_SWRM_CH3 + - 4 # WCD9370_SWRM_CH4 + + qcom,rx-channel-mapping: + description: | + Specifies static channels mapping between slave and master rx port + channels. + In the order of slave port channels, which is + hph_l, hph_r, clsh, comp_l, comp_r, lo, dsd_r, dsd_l. + $ref: /schemas/types.yaml#/definitions/uint8-array + minItems: 8 + maxItems: 8 + additionalItems: false + items: + enum: + - 1 # WCD9370_SWRM_CH1 + - 2 # WCD9370_SWRM_CH2 + - 3 # WCD9370_SWRM_CH3 + - 4 # WCD9370_SWRM_CH4 + required: - compatible - reg @@ -74,6 +108,7 @@ examples: compatible = "sdw20217010a00"; reg = <0 4>; qcom,rx-port-mapping = <1 2 3 4 5>; + qcom,rx-channel-mapping = /bits/ 8 <1 2 1 1 2 1 1 2>; }; }; @@ -85,6 +120,7 @@ examples: compatible = "sdw20217010a00"; reg = <0 3>; qcom,tx-port-mapping = <2 2 3 4>; + qcom,tx-channel-mapping = /bits/ 8 <1 2 1 1 2 3 3 4 1 2 3 4>; }; }; From c06c4f7cbea1d8dc71485bfddef2849a1b721e67 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Thu, 6 Feb 2025 16:52:23 +0530 Subject: [PATCH 042/651] ASoC: codecs: wcd937x: Add static channel mapping support in wcd937x-sdw Add static channel mapping between master and slave ports in wcd937x-sdw driver. Currently, the channel mask for each soundwire port is hardcoded in the wcd937x-sdw driver, and the same channel mask value is configured in the soundwire master. The Qualcomm boards like the QCM6490-IDP require different channel mask settings for the soundwire master and slave ports. Implemented logic to read TX/RX channel mappings from device tree properties (qcom,tx-channel-mapping and qcom,rx-channel-mapping). Modified the wcd937x_connect_port to handle master channel masks during port enable/disable operations. Added wcd937x_get_channel_map api to retrieve the current master channel map for TX and RX paths. Signed-off-by: Mohammad Rafi Shaik Link: https://patch.msgid.link/20250206112225.3270400-3-quic_mohs@quicinc.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd937x-sdw.c | 39 ++++++++++++++++++++++--- sound/soc/codecs/wcd937x.c | 53 ++++++++++++++++++++++++++++++++-- sound/soc/codecs/wcd937x.h | 7 ++++- 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wcd937x-sdw.c b/sound/soc/codecs/wcd937x-sdw.c index 0c33f7f3dc25..1fbff313b965 100644 --- a/sound/soc/codecs/wcd937x-sdw.c +++ b/sound/soc/codecs/wcd937x-sdw.c @@ -19,7 +19,7 @@ #include #include "wcd937x.h" -static const struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = { +static struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = { WCD_SDW_CH(WCD937X_HPH_L, WCD937X_HPH_PORT, BIT(0)), WCD_SDW_CH(WCD937X_HPH_R, WCD937X_HPH_PORT, BIT(1)), WCD_SDW_CH(WCD937X_CLSH, WCD937X_CLSH_PORT, BIT(0)), @@ -30,7 +30,7 @@ static const struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = { WCD_SDW_CH(WCD937X_DSD_R, WCD937X_DSD_PORT, BIT(1)), }; -static const struct wcd937x_sdw_ch_info wcd937x_sdw_tx_ch_info[] = { +static struct wcd937x_sdw_ch_info wcd937x_sdw_tx_ch_info[] = { WCD_SDW_CH(WCD937X_ADC1, WCD937X_ADC_1_PORT, BIT(0)), WCD_SDW_CH(WCD937X_ADC2, WCD937X_ADC_2_3_PORT, BIT(0)), WCD_SDW_CH(WCD937X_ADC3, WCD937X_ADC_2_3_PORT, BIT(0)), @@ -1019,7 +1019,9 @@ static int wcd9370_probe(struct sdw_slave *pdev, { struct device *dev = &pdev->dev; struct wcd937x_sdw_priv *wcd; - int ret; + u8 master_ch_mask[WCD937X_MAX_SWR_CH_IDS]; + int master_ch_mask_size = 0; + int ret, i; wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL); if (!wcd) @@ -1048,10 +1050,36 @@ static int wcd9370_probe(struct sdw_slave *pdev, SDW_SCP_INT1_PARITY; pdev->prop.lane_control_support = true; pdev->prop.simple_clk_stop_capable = true; + + memset(master_ch_mask, 0, WCD937X_MAX_SWR_CH_IDS); + if (wcd->is_tx) { - pdev->prop.source_ports = GENMASK(WCD937X_MAX_TX_SWR_PORTS - 1, 0); + master_ch_mask_size = of_property_count_u8_elems(dev->of_node, + "qcom,tx-channel-mapping"); + + if (master_ch_mask_size) + ret = of_property_read_u8_array(dev->of_node, "qcom,tx-channel-mapping", + master_ch_mask, master_ch_mask_size); + } else { + master_ch_mask_size = of_property_count_u8_elems(dev->of_node, + "qcom,rx-channel-mapping"); + + if (master_ch_mask_size) + ret = of_property_read_u8_array(dev->of_node, "qcom,rx-channel-mapping", + master_ch_mask, master_ch_mask_size); + } + + if (ret < 0) + dev_info(dev, "Static channel mapping not specified using device channel maps\n"); + + if (wcd->is_tx) { + pdev->prop.source_ports = GENMASK(WCD937X_MAX_TX_SWR_PORTS, 0); pdev->prop.src_dpn_prop = wcd937x_dpn_prop; wcd->ch_info = &wcd937x_sdw_tx_ch_info[0]; + + for (i = 0; i < master_ch_mask_size; i++) + wcd->ch_info[i].master_ch_mask = WCD937X_SWRM_CH_MASK(master_ch_mask[i]); + pdev->prop.wake_capable = true; wcd->regmap = devm_regmap_init_sdw(pdev, &wcd937x_regmap_config); @@ -1065,6 +1093,9 @@ static int wcd9370_probe(struct sdw_slave *pdev, pdev->prop.sink_ports = GENMASK(WCD937X_MAX_SWR_PORTS - 1, 0); pdev->prop.sink_dpn_prop = wcd937x_dpn_prop; wcd->ch_info = &wcd937x_sdw_rx_ch_info[0]; + + for (i = 0; i < master_ch_mask_size; i++) + wcd->ch_info[i].master_ch_mask = WCD937X_SWRM_CH_MASK(master_ch_mask[i]); } diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c index c9d5e67bf66e..e8d3fddbc7b1 100644 --- a/sound/soc/codecs/wcd937x.c +++ b/sound/soc/codecs/wcd937x.c @@ -1197,13 +1197,21 @@ static int wcd937x_connect_port(struct wcd937x_sdw_priv *wcd, u8 port_idx, u8 ch const struct wcd937x_sdw_ch_info *ch_info = &wcd->ch_info[ch_id]; u8 port_num = ch_info->port_num; u8 ch_mask = ch_info->ch_mask; + u8 mstr_port_num, mstr_ch_mask; + struct sdw_slave *sdev = wcd->sdev; port_config->num = port_num; - if (enable) + mstr_port_num = sdev->m_port_map[port_num]; + mstr_ch_mask = ch_info->master_ch_mask; + + if (enable) { port_config->ch_mask |= ch_mask; - else + wcd->master_channel_map[mstr_port_num] |= mstr_ch_mask; + } else { port_config->ch_mask &= ~ch_mask; + wcd->master_channel_map[mstr_port_num] &= ~mstr_ch_mask; + } return 0; } @@ -2689,10 +2697,51 @@ static int wcd937x_codec_set_sdw_stream(struct snd_soc_dai *dai, return 0; } +static int wcd937x_get_channel_map(const struct snd_soc_dai *dai, + unsigned int *tx_num, unsigned int *tx_slot, + unsigned int *rx_num, unsigned int *rx_slot) +{ + struct wcd937x_priv *wcd937x = dev_get_drvdata(dai->dev); + struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[dai->id]; + int i; + + switch (dai->id) { + case AIF1_PB: + if (!rx_slot || !rx_num) { + dev_err(dai->dev, "Invalid rx_slot %p or rx_num %p\n", + rx_slot, rx_num); + return -EINVAL; + } + + for (i = 0; i < SDW_MAX_PORTS; i++) + rx_slot[i] = wcd->master_channel_map[i]; + + *rx_num = i; + break; + case AIF1_CAP: + if (!tx_slot || !tx_num) { + dev_err(dai->dev, "Invalid tx_slot %p or tx_num %p\n", + tx_slot, tx_num); + return -EINVAL; + } + + for (i = 0; i < SDW_MAX_PORTS; i++) + tx_slot[i] = wcd->master_channel_map[i]; + + *tx_num = i; + break; + default: + break; + } + + return 0; +} + static const struct snd_soc_dai_ops wcd937x_sdw_dai_ops = { .hw_params = wcd937x_codec_hw_params, .hw_free = wcd937x_codec_free, .set_stream = wcd937x_codec_set_sdw_stream, + .get_channel_map = wcd937x_get_channel_map, }; static struct snd_soc_dai_driver wcd937x_dais[] = { diff --git a/sound/soc/codecs/wcd937x.h b/sound/soc/codecs/wcd937x.h index 4afa48dcaf74..4ef57c496c37 100644 --- a/sound/soc/codecs/wcd937x.h +++ b/sound/soc/codecs/wcd937x.h @@ -489,6 +489,7 @@ #define WCD937X_MAX_MICBIAS 3 #define WCD937X_MAX_BULK_SUPPLY 4 #define WCD937X_MAX_SWR_CH_IDS 15 +#define WCD937X_SWRM_CH_MASK(ch_idx) BIT(ch_idx - 1) enum wcd937x_tx_sdw_ports { WCD937X_ADC_1_PORT = 1, @@ -510,12 +511,14 @@ enum wcd937x_rx_sdw_ports { struct wcd937x_sdw_ch_info { int port_num; unsigned int ch_mask; + unsigned int master_ch_mask; }; #define WCD_SDW_CH(id, pn, cmask) \ [id] = { \ .port_num = pn, \ .ch_mask = cmask, \ + .master_ch_mask = cmask, \ } struct wcd937x_priv; @@ -524,9 +527,11 @@ struct wcd937x_sdw_priv { struct sdw_stream_config sconfig; struct sdw_stream_runtime *sruntime; struct sdw_port_config port_config[WCD937X_MAX_SWR_PORTS]; - const struct wcd937x_sdw_ch_info *ch_info; + struct wcd937x_sdw_ch_info *ch_info; bool port_enable[WCD937X_MAX_SWR_CH_IDS]; + unsigned int master_channel_map[SDW_MAX_PORTS]; int active_ports; + int num_ports; bool is_tx; struct wcd937x_priv *wcd937x; struct irq_domain *slave_irq; From 7796c97df6b1b2206681a07f3c80f6023a6593d5 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Thu, 6 Feb 2025 16:52:24 +0530 Subject: [PATCH 043/651] soundwire: qcom: Add set_channel_map api support Added qcom_swrm_set_channel_map api to set the master channel mask for TX and RX paths based on the provided slots. Added a new field ch_mask to the qcom_swrm_port_config structure. This field is used to store the master channel mask, which allows more flexible to configure channel mask in runtime for specific active soundwire ports. Modified the qcom_swrm_port_enable function to configure master channel mask. If the ch_mask is set to SWR_INVALID_PARAM or is zero, the function will use the default channel mask. Signed-off-by: Mohammad Rafi Shaik Acked-by: Vinod Koul Link: https://patch.msgid.link/20250206112225.3270400-4-quic_mohs@quicinc.com Signed-off-by: Mark Brown --- drivers/soundwire/qcom.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 0f45e3404756..295a46dc2be7 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -156,6 +156,7 @@ struct qcom_swrm_port_config { u8 word_length; u8 blk_group_count; u8 lane_control; + u8 ch_mask; }; /* @@ -1048,9 +1049,13 @@ static int qcom_swrm_port_enable(struct sdw_bus *bus, { u32 reg = SWRM_DP_PORT_CTRL_BANK(enable_ch->port_num, bank); struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus); + struct qcom_swrm_port_config *pcfg; u32 val; + pcfg = &ctrl->pconfig[enable_ch->port_num]; ctrl->reg_read(ctrl, reg, &val); + if (pcfg->ch_mask != SWR_INVALID_PARAM && pcfg->ch_mask != 0) + enable_ch->ch_mask = pcfg->ch_mask; if (enable_ch->enable) val |= (enable_ch->ch_mask << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT); @@ -1270,6 +1275,26 @@ static void *qcom_swrm_get_sdw_stream(struct snd_soc_dai *dai, int direction) return ctrl->sruntime[dai->id]; } +static int qcom_swrm_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, const unsigned int *tx_slot, + unsigned int rx_num, const unsigned int *rx_slot) +{ + struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev); + int i; + + if (tx_slot) { + for (i = 0; i < tx_num; i++) + ctrl->pconfig[i].ch_mask = tx_slot[i]; + } + + if (rx_slot) { + for (i = 0; i < rx_num; i++) + ctrl->pconfig[i].ch_mask = rx_slot[i]; + } + + return 0; +} + static int qcom_swrm_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1306,6 +1331,7 @@ static const struct snd_soc_dai_ops qcom_swrm_pdm_dai_ops = { .shutdown = qcom_swrm_shutdown, .set_stream = qcom_swrm_set_sdw_stream, .get_stream = qcom_swrm_get_sdw_stream, + .set_channel_map = qcom_swrm_set_channel_map, }; static const struct snd_soc_component_driver qcom_swrm_dai_component = { From 0e9a970d7b2cb98d741bc0e32ad8c8f30c009c63 Mon Sep 17 00:00:00 2001 From: Mohammad Rafi Shaik Date: Thu, 6 Feb 2025 16:52:25 +0530 Subject: [PATCH 044/651] ASoC: qcom: sdw: Add get and set channel maps support from codec to cpu dais Add get and set channel maps support from codec to cpu dais. Implemented logic to get the channel map in case of only sdw stream and set channel map only for specific cpu dais. Signed-off-by: Mohammad Rafi Shaik Link: https://patch.msgid.link/20250206112225.3270400-5-quic_mohs@quicinc.com Signed-off-by: Mark Brown --- sound/soc/qcom/sdw.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c index f2eda2ff46c0..1d01b9329e08 100644 --- a/sound/soc/qcom/sdw.c +++ b/sound/soc/qcom/sdw.c @@ -23,9 +23,11 @@ int qcom_snd_sdw_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + u32 rx_ch[SDW_MAX_PORTS], tx_ch[SDW_MAX_PORTS]; struct sdw_stream_runtime *sruntime; struct snd_soc_dai *codec_dai; - int ret, i; + u32 rx_ch_cnt = 0, tx_ch_cnt = 0; + int ret, i, j; sruntime = sdw_alloc_stream(cpu_dai->name); if (!sruntime) @@ -35,9 +37,35 @@ int qcom_snd_sdw_startup(struct snd_pcm_substream *substream) ret = snd_soc_dai_set_stream(codec_dai, sruntime, substream->stream); if (ret < 0 && ret != -ENOTSUPP) { - dev_err(rtd->dev, "Failed to set sdw stream on %s\n", - codec_dai->name); + dev_err(rtd->dev, "Failed to set sdw stream on %s\n", codec_dai->name); goto err_set_stream; + } else if (ret == -ENOTSUPP) { + /* Ignore unsupported */ + continue; + } + + ret = snd_soc_dai_get_channel_map(codec_dai, &tx_ch_cnt, tx_ch, + &rx_ch_cnt, rx_ch); + if (ret != 0 && ret != -ENOTSUPP) { + dev_err(rtd->dev, "Failed to get codec chan map %s\n", codec_dai->name); + goto err_set_stream; + } else if (ret == -ENOTSUPP) { + /* Ignore unsupported */ + continue; + } + } + + switch (cpu_dai->id) { + case RX_CODEC_DMA_RX_0: + case TX_CODEC_DMA_TX_3: + if (tx_ch_cnt || rx_ch_cnt) { + for_each_rtd_codec_dais(rtd, j, codec_dai) { + ret = snd_soc_dai_set_channel_map(codec_dai, + tx_ch_cnt, tx_ch, + rx_ch_cnt, rx_ch); + if (ret != 0 && ret != -ENOTSUPP) + goto err_set_stream; + } } } From 78e66dd5f32a1a8e5ee6decadd4e4dffa7d2c40d Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 6 Feb 2025 01:40:28 +0000 Subject: [PATCH 045/651] ASoC: mediatek: mt8186: Remove unused mt8186_afe_(suspend|resume)_clock mt8186_afe_resume_clock() and mt8186_afe_suspend_clock() were added in 2022 by commit 55b423d5623c ("ASoC: mediatek: mt8186: support audio clock control in platform driver") but have remained unused. Remove them. Signed-off-by: Dr. David Alan Gilbert Link: https://patch.msgid.link/20250206014028.237423-1-linux@treblig.org Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-afe-clk.c | 55 ---------------------- sound/soc/mediatek/mt8186/mt8186-afe-clk.h | 2 - 2 files changed, 57 deletions(-) diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.c b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c index 70ec101890d3..daaca36a2d08 100644 --- a/sound/soc/mediatek/mt8186/mt8186-afe-clk.c +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c @@ -329,61 +329,6 @@ void mt8186_afe_disable_clock(struct mtk_base_afe *afe) clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]); } -int mt8186_afe_suspend_clock(struct mtk_base_afe *afe) -{ - struct mt8186_afe_private *afe_priv = afe->platform_priv; - int ret; - - /* set audio int bus to 26M */ - ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); - if (ret) { - dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret); - goto clk_mux_audio_intbus_err; - } - ret = mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M); - if (ret) - goto clk_mux_audio_intbus_parent_err; - - clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); - - return 0; - -clk_mux_audio_intbus_parent_err: - mt8186_set_audio_int_bus_parent(afe, CLK_TOP_MAINPLL_D2_D4); -clk_mux_audio_intbus_err: - clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); - return ret; -} - -int mt8186_afe_resume_clock(struct mtk_base_afe *afe) -{ - struct mt8186_afe_private *afe_priv = afe->platform_priv; - int ret; - - /* set audio int bus to normal working clock */ - ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); - if (ret) { - dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret); - goto clk_mux_audio_intbus_err; - } - ret = mt8186_set_audio_int_bus_parent(afe, - CLK_TOP_MAINPLL_D2_D4); - if (ret) - goto clk_mux_audio_intbus_parent_err; - - clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); - - return 0; - -clk_mux_audio_intbus_parent_err: - mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M); -clk_mux_audio_intbus_err: - clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); - return ret; -} - int mt8186_apll1_enable(struct mtk_base_afe *afe) { struct mt8186_afe_private *afe_priv = afe->platform_priv; diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.h b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h index a9d59e506d9a..e524833ce780 100644 --- a/sound/soc/mediatek/mt8186/mt8186-afe-clk.h +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h @@ -85,8 +85,6 @@ int mt8186_afe_enable_cgs(struct mtk_base_afe *afe); void mt8186_afe_disable_cgs(struct mtk_base_afe *afe); int mt8186_afe_enable_clock(struct mtk_base_afe *afe); void mt8186_afe_disable_clock(struct mtk_base_afe *afe); -int mt8186_afe_suspend_clock(struct mtk_base_afe *afe); -int mt8186_afe_resume_clock(struct mtk_base_afe *afe); int mt8186_apll1_enable(struct mtk_base_afe *afe); void mt8186_apll1_disable(struct mtk_base_afe *afe); From ecfcee245cc99def0f6bf84ac75ac372f8ab65eb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 6 Feb 2025 01:52:16 +0900 Subject: [PATCH 046/651] ASoC: dapm: unexport snd_soc_dapm_init() The symbol provider (sound/soc/soc-dapm.c) and the symbol consumer (sound/soc/soc-core.c) belong to the same module, snd-soc-core.ko. There is no need to export it. Signed-off-by: Masahiro Yamada Link: https://patch.msgid.link/20250205165226.3466137-1-masahiroy@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index b5116b700d73..3fa53ce80189 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -4865,7 +4865,6 @@ void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm, /* see for_each_card_dapms */ list_add(&dapm->list, &card->dapm_list); } -EXPORT_SYMBOL_GPL(snd_soc_dapm_init); static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) { From 3f78762d17701f0435ad958b2821dc3243ff34b3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 6 Feb 2025 01:53:34 +0900 Subject: [PATCH 047/651] ASoC: dapm: unexport snd_soc_dapm_update_dai() The symbol provider (sound/soc/soc-dapm.c) and the symbol consumer (sound/soc/soc-pcm.c) belong to the same module, snd-soc-core.ko. There is no need to export it. Signed-off-by: Masahiro Yamada Link: https://patch.msgid.link/20250205165337.3466336-1-masahiroy@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 3fa53ce80189..a4d78af45e4b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2783,7 +2783,6 @@ int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream, return ret; } -EXPORT_SYMBOL_GPL(snd_soc_dapm_update_dai); int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s) { From 5ea46b4360791345bd0bf4c7bf8fff5151374ea1 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 6 Feb 2025 11:49:14 +0200 Subject: [PATCH 048/651] ASoC: SOF: ipc4-pcm: Move out be_rate initialization from for loop in fixup Instead of initializing the be_rate within the loop by checking i == 0 at each iteration, move the be_rate reference initialization from the loop. For BE single rate check we will have single comparison done at each iteration compared to two in case the num_input_formats were higher than 1. We still need to run the loop from index 0 to check for FE-BE rate match. The patch also fixes bogus reports from gcc static analyzer thinking that be_rate is used uninitialized later in the function (which was not true). Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20250206094914.21135-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-pcm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 18fff2df76f9..dc05e7490e6d 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -610,12 +610,11 @@ static int sof_ipc4_pcm_dai_link_fixup_rate(struct snd_sof_dev *sdev, * Copier does not change sampling rate, so we * need to only consider the input pin information. */ + be_rate = pin_fmts[0].audio_fmt.sampling_frequency; for (i = 0; i < num_input_formats; i++) { unsigned int val = pin_fmts[i].audio_fmt.sampling_frequency; - if (i == 0) - be_rate = val; - else if (val != be_rate) + if (val != be_rate) single_be_rate = false; if (val == fe_rate) { From 2466b62268c020606d20b45e007c166399e639ee Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 6 Feb 2025 01:53:08 +0900 Subject: [PATCH 049/651] ASoC: dapm: unexport dapm_mark_endpoints_dirty() The symbol provider (sound/soc/soc-dapm.c) and the symbol consumer (sound/soc/soc-core.c) belong to the same module, snd-soc-core.ko. There is no need to export it. I deleted the comment, as other modules cannot use it any more. Signed-off-by: Masahiro Yamada Link: https://patch.msgid.link/20250205165310.3466254-1-masahiroy@kernel.org Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 2 -- sound/soc/soc-dapm.c | 1 - 2 files changed, 3 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 12cd7b5a2202..7cf52c8c9cf3 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -514,8 +514,6 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin); int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, const char *pin); unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol); - -/* Mostly internal - should not normally be used */ void dapm_mark_endpoints_dirty(struct snd_soc_card *card); /* dapm path query */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a4d78af45e4b..420fe7dea31e 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -317,7 +317,6 @@ void dapm_mark_endpoints_dirty(struct snd_soc_card *card) snd_soc_dapm_mutex_unlock(card); } -EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty); /* create a new dapm widget */ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( From 4c7518062d638837cea915e0ffe30f846780639a Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 6 Feb 2025 10:52:37 +0200 Subject: [PATCH 050/651] ASoC: SOF: ipc4: Add support for split firmware releases A split SOF release consists of a base firmware and two libraries: -openmodules.ri for processing (audio) modules -debug.ri for debug and developer modules To handle this new release model add infrastructure to try to load the two library after boot optionally. This approach will allow flexibility on handling platforms in sof-bin with single or split configuration: single release: base firmware only split release: base firmware + openmodules + debug The files for the split firmware are located at the firmware directory. Signed-off-by: Peter Ujfalusi Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Link: https://patch.msgid.link/20250206085237.19214-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-loader.c | 143 +++++++++++++++++++++++++++++------- sound/soc/sof/ipc4-priv.h | 1 + sound/soc/sof/ipc4.c | 8 +- 3 files changed, 126 insertions(+), 26 deletions(-) diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c index bcdb33d03682..6ad1ef0e53e8 100644 --- a/sound/soc/sof/ipc4-loader.c +++ b/sound/soc/sof/ipc4-loader.c @@ -169,21 +169,14 @@ static size_t sof_ipc4_fw_parse_basefw_ext_man(struct snd_sof_dev *sdev) return payload_offset; } -static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev, - unsigned long lib_id, const guid_t *uuid) +static int sof_ipc4_load_library(struct snd_sof_dev *sdev, unsigned long lib_id, + const char *lib_filename, bool optional) { struct sof_ipc4_fw_data *ipc4_data = sdev->private; struct sof_ipc4_fw_library *fw_lib; - const char *fw_filename; ssize_t payload_offset; int ret, i, err; - if (!sdev->pdata->fw_lib_prefix) { - dev_err(sdev->dev, - "Library loading is not supported due to not set library path\n"); - return -EINVAL; - } - if (!ipc4_data->load_library) { dev_err(sdev->dev, "Library loading is not supported on this platform\n"); return -EOPNOTSUPP; @@ -193,20 +186,25 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev, if (!fw_lib) return -ENOMEM; - fw_filename = kasprintf(GFP_KERNEL, "%s/%pUL.bin", - sdev->pdata->fw_lib_prefix, uuid); - if (!fw_filename) { - ret = -ENOMEM; - goto free_fw_lib; + if (optional) { + ret = firmware_request_nowarn(&fw_lib->sof_fw.fw, lib_filename, + sdev->dev); + if (ret < 0) { + /* optional library, override the error */ + ret = 0; + goto free_fw_lib; + } + } else { + ret = request_firmware(&fw_lib->sof_fw.fw, lib_filename, + sdev->dev); + if (ret < 0) { + dev_err(sdev->dev, "Library file '%s' is missing\n", + lib_filename); + goto free_fw_lib; + } } - ret = request_firmware(&fw_lib->sof_fw.fw, fw_filename, sdev->dev); - if (ret < 0) { - dev_err(sdev->dev, "Library file '%s' is missing\n", fw_filename); - goto free_filename; - } else { - dev_dbg(sdev->dev, "Library file '%s' loaded\n", fw_filename); - } + dev_dbg(sdev->dev, "Library file '%s' loaded\n", lib_filename); payload_offset = sof_ipc4_fw_parse_ext_man(sdev, fw_lib); if (payload_offset <= 0) { @@ -251,22 +249,117 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev, if (unlikely(ret)) goto release; - kfree(fw_filename); - return 0; release: release_firmware(fw_lib->sof_fw.fw); /* Allocated within sof_ipc4_fw_parse_ext_man() */ devm_kfree(sdev->dev, fw_lib->modules); -free_filename: - kfree(fw_filename); free_fw_lib: devm_kfree(sdev->dev, fw_lib); return ret; } +/** + * sof_ipc4_complete_split_release - loads the library parts of a split firmware + * @sdev: SOF device + * + * With IPC4 the firmware can be a single binary or a split release. + * - single binary: only the basefw + * - split release: basefw and two libraries (openmodules, debug) + * + * With split firmware release it is also allowed that for example only the + * debug library is present (the openmodules content is built in the basefw). + * + * To handle the permutations try to load the openmodules then the debug + * libraries as optional ones after the basefw boot. + * + * The libraries for the split release are stored alongside the basefw on the + * filesystem. + */ +int sof_ipc4_complete_split_release(struct snd_sof_dev *sdev) +{ + static const char * const lib_bundle[] = { "openmodules", "debug" }; + const char *fw_filename = sdev->pdata->fw_filename; + const char *lib_filename, *p; + size_t lib_name_base_size; + unsigned long lib_id = 1; + char *lib_name_base; + int i; + + p = strstr(fw_filename, ".ri"); + if (!p || strlen(p) != 3) { + dev_info(sdev->dev, + "%s: Firmware name '%s' is missing .ri extension\n", + __func__, fw_filename); + return 0; + } + + /* Space for the firmware basename + '\0', without the extension */ + lib_name_base_size = strlen(fw_filename) - 2; + lib_name_base = kzalloc(lib_name_base_size, GFP_KERNEL); + if (!lib_name_base) + return -ENOMEM; + + /* + * strscpy will 0 terminate the copied string, removing the '.ri' from + * the end of the fw_filename, for example: + * fw_filename: "sof-ptl.ri\0" + * lib_name_base: "sof-ptl\0" + */ + strscpy(lib_name_base, fw_filename, lib_name_base_size); + + for (i = 0; i < ARRAY_SIZE(lib_bundle); i++) { + int ret; + + lib_filename = kasprintf(GFP_KERNEL, "%s/%s-%s.ri", + sdev->pdata->fw_filename_prefix, + lib_name_base, lib_bundle[i]); + if (!lib_filename) { + kfree(lib_name_base); + return -ENOMEM; + } + + ret = sof_ipc4_load_library(sdev, lib_id, lib_filename, true); + if (ret) + dev_warn(sdev->dev, "%s: Failed to load %s: %d\n", + __func__, lib_filename, ret); + else + lib_id++; + + kfree(lib_filename); + } + + kfree(lib_name_base); + + return 0; +} + +static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev, + unsigned long lib_id, const guid_t *uuid) +{ + const char *lib_filename; + int ret; + + if (!sdev->pdata->fw_lib_prefix) { + dev_err(sdev->dev, + "Library loading is not supported due to not set library path\n"); + return -EINVAL; + } + + lib_filename = kasprintf(GFP_KERNEL, "%s/%pUL.bin", + sdev->pdata->fw_lib_prefix, uuid); + if (!lib_filename) + return -ENOMEM; + + ret = sof_ipc4_load_library(sdev, lib_id, lib_filename, false); + + kfree(lib_filename); + + return ret; +} + struct sof_ipc4_fw_module *sof_ipc4_find_module_by_uuid(struct snd_sof_dev *sdev, const guid_t *uuid) { diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index ea3323b90343..b798810eff91 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -101,6 +101,7 @@ extern const struct sof_ipc_fw_tracing_ops ipc4_mtrace_ops; int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 instance_id, u32 state); int sof_ipc4_mtrace_update_pos(struct snd_sof_dev *sdev, int core); +int sof_ipc4_complete_split_release(struct snd_sof_dev *sdev); int sof_ipc4_query_fw_configuration(struct snd_sof_dev *sdev); int sof_ipc4_reload_fw_libraries(struct snd_sof_dev *sdev); struct sof_ipc4_fw_module *sof_ipc4_find_module_by_uuid(struct snd_sof_dev *sdev, diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index 4386cbae16d4..2ed0c52fb2f1 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -825,8 +825,14 @@ static void sof_ipc4_exit(struct snd_sof_dev *sdev) static int sof_ipc4_post_boot(struct snd_sof_dev *sdev) { - if (sdev->first_boot) + if (sdev->first_boot) { + int ret = sof_ipc4_complete_split_release(sdev); + + if (ret) + return ret; + return sof_ipc4_query_fw_configuration(sdev); + } return sof_ipc4_reload_fw_libraries(sdev); } From 943116ba2a6ab472e8ad2d1e57a3f10f13485cc2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Feb 2025 00:16:10 +0000 Subject: [PATCH 051/651] ASoC: add common snd_soc_ret() and use it Each soc-xxx.c is using own snd_xxx_ret(), but we want to share it. Let's add common snd_soc_ret() for it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frkt2qlx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-card.c | 14 ++------------ sound/soc/soc-component.c | 36 ++++++++++++------------------------ sound/soc/soc-dai.c | 18 ++---------------- sound/soc/soc-link.c | 18 ++---------------- sound/soc/soc-pcm.c | 18 ++---------------- sound/soc/soc-utils.c | 26 ++++++++++++++++++++++++++ 7 files changed, 47 insertions(+), 84 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index fcdb5adfcd5e..16e4e488521c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -539,6 +539,7 @@ int snd_soc_calc_bclk(int fs, int sample_size, int channels, int tdm_slots); int snd_soc_params_to_bclk(const struct snd_pcm_hw_params *parms); int snd_soc_tdm_params_to_bclk(const struct snd_pcm_hw_params *params, int tdm_width, int tdm_slots, int slot_multiple); +int snd_soc_ret(const struct device *dev, int ret, const char *fmt, ...); /* set runtime hw params */ static inline int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, diff --git a/sound/soc/soc-card.c b/sound/soc/soc-card.c index e6eb71b3010a..235427d69061 100644 --- a/sound/soc/soc-card.c +++ b/sound/soc/soc-card.c @@ -15,18 +15,8 @@ static inline int _soc_card_ret(struct snd_soc_card *card, const char *func, int ret) { - switch (ret) { - case -EPROBE_DEFER: - case -ENOTSUPP: - case 0: - break; - default: - dev_err(card->dev, - "ASoC: error at %s on %s: %d\n", - func, card->name, ret); - } - - return ret; + return snd_soc_ret(card->dev, ret, + "at %s() on %s\n", func, card->name); } struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index b67ef78f405c..25f5e543ae8d 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -13,32 +13,20 @@ #include #include -#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret, -1) -#define soc_component_ret_reg_rw(dai, ret, reg) _soc_component_ret(dai, __func__, ret, reg) -static inline int _soc_component_ret(struct snd_soc_component *component, - const char *func, int ret, int reg) +#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret) +static inline int _soc_component_ret(struct snd_soc_component *component, const char *func, int ret) { - /* Positive/Zero values are not errors */ - if (ret >= 0) - return ret; + return snd_soc_ret(component->dev, ret, + "at %s() on %s\n", func, component->name); +} - /* Negative values might be errors */ - switch (ret) { - case -EPROBE_DEFER: - case -ENOTSUPP: - break; - default: - if (reg == -1) - dev_err(component->dev, - "ASoC: error at %s on %s: %d\n", - func, component->name, ret); - else - dev_err(component->dev, - "ASoC: error at %s on %s for register: [0x%08x] %d\n", - func, component->name, reg, ret); - } - - return ret; +#define soc_component_ret_reg_rw(dai, ret, reg) _soc_component_ret_reg_rw(dai, __func__, ret, reg) +static inline int _soc_component_ret_reg_rw(struct snd_soc_component *component, + const char *func, int ret, int reg) +{ + return snd_soc_ret(component->dev, ret, + "at %s() on %s for register: [0x%08x]\n", + func, component->name, reg); } static inline int soc_component_field_shift(struct snd_soc_component *component, diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index ca0308f6d41c..7c4c9127e5f3 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -14,22 +14,8 @@ static inline int _soc_dai_ret(const struct snd_soc_dai *dai, const char *func, int ret) { - /* Positive, Zero values are not errors */ - if (ret >= 0) - return ret; - - /* Negative values might be errors */ - switch (ret) { - case -EPROBE_DEFER: - case -ENOTSUPP: - break; - default: - dev_err(dai->dev, - "ASoC: error at %s on %s: %d\n", - func, dai->name, ret); - } - - return ret; + return snd_soc_ret(dai->dev, ret, + "at %s() on %s\n", func, dai->name); } /* diff --git a/sound/soc/soc-link.c b/sound/soc/soc-link.c index 7f1f1bc717e2..02fd68f2e702 100644 --- a/sound/soc/soc-link.c +++ b/sound/soc/soc-link.c @@ -12,22 +12,8 @@ static inline int _soc_link_ret(struct snd_soc_pcm_runtime *rtd, const char *func, int ret) { - /* Positive, Zero values are not errors */ - if (ret >= 0) - return ret; - - /* Negative values might be errors */ - switch (ret) { - case -EPROBE_DEFER: - case -ENOTSUPP: - break; - default: - dev_err(rtd->dev, - "ASoC: error at %s on %s: %d\n", - func, rtd->dai_link->name, ret); - } - - return ret; + return snd_soc_ret(rtd->dev, ret, + "at %s() on %s\n", func, rtd->dai_link->name); } /* diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 88b3ad5a2552..a2caa146cac2 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -30,22 +30,8 @@ static inline int _soc_pcm_ret(struct snd_soc_pcm_runtime *rtd, const char *func, int ret) { - /* Positive, Zero values are not errors */ - if (ret >= 0) - return ret; - - /* Negative values might be errors */ - switch (ret) { - case -EPROBE_DEFER: - case -ENOTSUPP: - break; - default: - dev_err(rtd->dev, - "ASoC: error at %s on %s: %d\n", - func, rtd->dai_link->name, ret); - } - - return ret; + return snd_soc_ret(rtd->dev, ret, + "at %s() on %s\n", func, rtd->dai_link->name); } /* is the current PCM operation for this FE ? */ diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index aa93e77ac937..e8958158acc1 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -15,6 +15,32 @@ #include #include +int snd_soc_ret(const struct device *dev, int ret, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + /* Positive, Zero values are not errors */ + if (ret >= 0) + return ret; + + /* Negative values might be errors */ + switch (ret) { + case -EPROBE_DEFER: + case -ENOTSUPP: + break; + default: + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + + dev_err(dev, "ASoC error (%d): %pV", ret, &vaf); + } + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_ret); + int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots) { return sample_size * channels * tdm_slots; From 062b7ef6b103dcbcb3c084e8ace8e74e260b2346 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Feb 2025 00:16:14 +0000 Subject: [PATCH 052/651] ASoC: soc-utils: care -EOPNOTSUPP on snd_soc_ret() We get below warning by checkpatch on soc-utils. Adds EOPNOTSUPP, but not remove existing ENOTSUPP. WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ed0d2qlt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-utils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index e8958158acc1..318b141c00b3 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -28,6 +28,7 @@ int snd_soc_ret(const struct device *dev, int ret, const char *fmt, ...) switch (ret) { case -EPROBE_DEFER: case -ENOTSUPP: + case -EOPNOTSUPP: break; default: va_start(args, fmt); From be61cd4242e4a53f5cf989ee7573121d041444bc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Feb 2025 00:16:19 +0000 Subject: [PATCH 053/651] ASoC: soc-pcm: use snd_soc_ret() Many functions uses below style for error return dev_err(dev, "message"); return -Exxxx; We can merge these into snd_soc_ret() which can use same error format. Let's cleaup code. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyfx2qlo.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 96 ++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 57 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a2caa146cac2..ebe99d369ca9 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -238,11 +238,9 @@ static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf, int stream; char *buf; - if (fe->dai_link->num_cpus > 1) { - dev_err(fe->dev, + if (fe->dai_link->num_cpus > 1) + return snd_soc_ret(fe->dev, -EINVAL, "%s doesn't support Multi CPU yet\n", __func__); - return -EINVAL; - } buf = kmalloc(out_count, GFP_KERNEL); if (!buf) @@ -460,12 +458,9 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, ret = snd_pcm_hw_constraint_single(substream->runtime, \ SNDRV_PCM_HW_PARAM_##NAME,\ soc_dai->symmetric_##name); \ - if (ret < 0) { \ - dev_err(soc_dai->dev, \ - "ASoC: Unable to apply %s constraint: %d\n",\ - #name, ret); \ - return ret; \ - } \ + if (ret < 0) \ + return snd_soc_ret(soc_dai->dev, ret, \ + "Unable to apply %s constraint\n", #name); \ } __soc_pcm_apply_symmetry(rate, RATE); @@ -496,12 +491,11 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ if (!snd_soc_dai_is_dummy(cpu_dai) && \ cpu_dai->symmetric_##xxx && \ - cpu_dai->symmetric_##xxx != d.symmetric_##xxx) { \ - dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %s:%d - %s:%d\n", \ - #xxx, cpu_dai->name, cpu_dai->symmetric_##xxx, \ - d.name, d.symmetric_##xxx); \ - return -EINVAL; \ - } + cpu_dai->symmetric_##xxx != d.symmetric_##xxx) \ + return snd_soc_ret(rtd->dev, -EINVAL, \ + "unmatched %s symmetry: %s:%d - %s:%d\n", \ + #xxx, cpu_dai->name, cpu_dai->symmetric_##xxx, \ + d.name, d.symmetric_##xxx); /* reject unmatched parameters when applying symmetry */ __soc_pcm_params_symmetry(rate); @@ -846,9 +840,8 @@ static int soc_hw_sanity_check(struct snd_pcm_substream *substream) return 0; config_err: - dev_err(dev, "ASoC: %s <-> %s No matching %s\n", - name_codec, name_cpu, err_msg); - return -EINVAL; + return snd_soc_ret(dev, -EINVAL, + "%s <-> %s No matching %s\n", name_codec, name_cpu, err_msg); } /* @@ -1319,11 +1312,11 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, fe_substream = snd_soc_dpcm_get_substream(fe, stream); be_substream = snd_soc_dpcm_get_substream(be, stream); - if (!fe_substream->pcm->nonatomic && be_substream->pcm->nonatomic) { - dev_err(be->dev, "%s: FE is atomic but BE is nonatomic, invalid configuration\n", - __func__); - return -EINVAL; - } + if (!fe_substream->pcm->nonatomic && be_substream->pcm->nonatomic) + return snd_soc_ret(be->dev, -EINVAL, + "%s: %s is atomic but %s is nonatomic, invalid configuration\n", + __func__, fe->dai_link->name, be->dai_link->name); + if (fe_substream->pcm->nonatomic && !be_substream->pcm->nonatomic) { dev_dbg(be->dev, "FE is nonatomic but BE is not, forcing BE as nonatomic\n"); be_substream->pcm->nonatomic = 1; @@ -1493,11 +1486,9 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe, struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(fe, 0); int paths; - if (fe->dai_link->num_cpus > 1) { - dev_err(fe->dev, + if (fe->dai_link->num_cpus > 1) + return snd_soc_ret(fe->dev, -EINVAL, "%s doesn't support Multi CPU yet\n", __func__); - return -EINVAL; - } /* get number of valid DAI paths and their widgets */ paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, list, @@ -2388,23 +2379,23 @@ static int dpcm_dai_trigger_fe_be(struct snd_pcm_substream *substream, ret = soc_pcm_trigger(substream, cmd); if (ret < 0) - return ret; + goto end; ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); - return ret; + goto end; } /* call trigger on the frontend after the backend. */ ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); if (ret < 0) - return ret; + goto end; dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n", fe->dai_link->name, cmd); ret = soc_pcm_trigger(substream, cmd); - - return ret; +end: + return snd_soc_ret(fe->dev, ret, "trigger FE cmd: %d failed\n", cmd); } static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd) @@ -2460,11 +2451,8 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd) goto out; } - if (ret < 0) { - dev_err(fe->dev, "ASoC: trigger FE cmd: %d failed: %d\n", - cmd, ret); + if (ret < 0) goto out; - } switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -2693,11 +2681,9 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new) if (!fe->dai_link->dynamic) return 0; - if (fe->dai_link->num_cpus > 1) { - dev_err(fe->dev, + if (fe->dai_link->num_cpus > 1) + return snd_soc_ret(fe->dev, -EINVAL, "%s doesn't support Multi CPU yet\n", __func__); - return -EINVAL; - } /* only check active links */ if (!snd_soc_dai_active(snd_soc_rtd_to_cpu(fe, 0))) @@ -2768,7 +2754,8 @@ int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) out: snd_soc_dpcm_mutex_unlock(card); - return ret; + + return snd_soc_ret(card->dev, ret, "%s() failed\n", __func__); } EXPORT_SYMBOL_GPL(snd_soc_dpcm_runtime_update); @@ -2842,10 +2829,9 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd, int has_capture = 0; int i; - if (dai_link->dynamic && dai_link->num_cpus > 1) { - dev_err(rtd->dev, "DPCM doesn't support Multi CPU for Front-Ends yet\n"); - return -EINVAL; - } + if (dai_link->dynamic && dai_link->num_cpus > 1) + return snd_soc_ret(rtd->dev, -EINVAL, + "DPCM doesn't support Multi CPU for Front-Ends yet\n"); /* Adapt stream for codec2codec links */ cpu_capture = snd_soc_get_stream_cpu(dai_link, SNDRV_PCM_STREAM_CAPTURE); @@ -2887,12 +2873,9 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd, if (dai_link->capture_only) has_playback = 0; - if (!has_playback && !has_capture) { - dev_err(rtd->dev, "substream %s has no playback, no capture\n", - dai_link->stream_name); - - return -EINVAL; - } + if (!has_playback && !has_capture) + return snd_soc_ret(rtd->dev, -EINVAL, + "substream %s has no playback, no capture\n", dai_link->stream_name); *playback = has_playback; *capture = has_capture; @@ -2932,11 +2915,10 @@ static int soc_create_pcm(struct snd_pcm **pcm, ret = snd_pcm_new(rtd->card->snd_card, new_name, rtd->id, playback, capture, pcm); } - if (ret < 0) { - dev_err(rtd->card->dev, "ASoC: can't create pcm %s for dailink %s: %d\n", - new_name, rtd->dai_link->name, ret); - return ret; - } + if (ret < 0) + return snd_soc_ret(rtd->dev, ret, + "can't create pcm %s for dailink %s\n", new_name, rtd->dai_link->name); + dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n", rtd->id, new_name); return 0; From a0ef5b4b101424b8a666ed56bf1717dafe2d37f5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Feb 2025 00:16:23 +0000 Subject: [PATCH 054/651] ASoC: simple-card: use snd_soc_ret() We can use snd_soc_ret() to indicate error message when return. Let's use it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjvh2qlk.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 130 +++++++++++++++++--------------- 1 file changed, 71 insertions(+), 59 deletions(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index afe7e79ffdbd..004fda4504c4 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -29,7 +29,16 @@ static const struct snd_soc_ops simple_ops = { .hw_params = simple_util_hw_params, }; -static int simple_parse_platform(struct device_node *node, struct snd_soc_dai_link_component *dlc) +#define simple_ret(priv, ret) _simple_ret(priv, __func__, ret) +static inline int _simple_ret(struct simple_util_priv *priv, + const char *func, int ret) +{ + return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func); +} + +static int simple_parse_platform(struct simple_util_priv *priv, + struct device_node *node, + struct snd_soc_dai_link_component *dlc) { struct of_phandle_args args; int ret; @@ -43,7 +52,7 @@ static int simple_parse_platform(struct device_node *node, struct snd_soc_dai_li */ ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args); if (ret) - return ret; + return simple_ret(priv, ret); /* dai_name is not required and may not exist for plat component */ @@ -52,11 +61,12 @@ static int simple_parse_platform(struct device_node *node, struct snd_soc_dai_li return 0; } -static int simple_parse_dai(struct device *dev, +static int simple_parse_dai(struct simple_util_priv *priv, struct device_node *node, struct snd_soc_dai_link_component *dlc, int *is_single_link) { + struct device *dev = simple_priv_to_dev(priv); struct of_phandle_args args; struct snd_soc_dai *dai; int ret; @@ -70,17 +80,18 @@ static int simple_parse_dai(struct device *dev, */ ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args); if (ret) - return ret; + goto end; /* * Try to find from DAI args */ dai = snd_soc_get_dai_via_args(&args); if (dai) { + ret = -ENOMEM; dlc->dai_name = snd_soc_dai_name_get(dai); dlc->dai_args = snd_soc_copy_dai_args(dev, &args); if (!dlc->dai_args) - return -ENOMEM; + goto end; goto parse_dai_end; } @@ -106,13 +117,14 @@ static int simple_parse_dai(struct device *dev, */ ret = snd_soc_get_dlc(&args, dlc); if (ret < 0) - return ret; + goto end; parse_dai_end: if (is_single_link) *is_single_link = !args.args_count; - - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } static void simple_parse_convert(struct device *dev, @@ -149,19 +161,17 @@ static int simple_parse_node(struct simple_util_priv *priv, dai = simple_props_to_dai_codec(dai_props, 0); } - ret = simple_parse_dai(dev, np, dlc, cpu); + ret = simple_parse_dai(priv, np, dlc, cpu); if (ret) - return ret; + goto end; ret = simple_util_parse_clk(dev, np, dai, dlc); if (ret) - return ret; + goto end; ret = simple_util_parse_tdm(np, dai); - if (ret) - return ret; - - return 0; +end: + return simple_ret(priv, ret); } static int simple_link_init(struct simple_util_priv *priv, @@ -183,7 +193,7 @@ static int simple_link_init(struct simple_util_priv *priv, ret = simple_util_parse_daifmt(dev, node, codec, prefix, &dai_link->dai_fmt); if (ret < 0) - return ret; + goto end; graph_util_parse_link_direction(top, &playback_only, &capture_only); graph_util_parse_link_direction(node, &playback_only, &capture_only); @@ -213,7 +223,9 @@ static int simple_link_init(struct simple_util_priv *priv, dai_link->init = simple_util_dai_init; dai_link->ops = &simple_ops; - return simple_util_set_dailink_name(dev, dai_link, name); + ret = simple_util_set_dailink_name(dev, dai_link, name); +end: + return simple_ret(priv, ret); } static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, @@ -290,7 +302,7 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv, out_put_node: li->link++; - return ret; + return simple_ret(priv, ret); } static int simple_dai_link_of(struct simple_util_priv *priv, @@ -330,7 +342,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv, if (ret < 0) goto dai_link_of_err; - ret = simple_parse_platform(plat, platforms); + ret = simple_parse_platform(priv, plat, platforms); if (ret < 0) goto dai_link_of_err; @@ -345,7 +357,7 @@ static int simple_dai_link_of(struct simple_util_priv *priv, dai_link_of_err: li->link++; - return ret; + return simple_ret(priv, ret); } static int __simple_for_each_link(struct simple_util_priv *priv, @@ -443,10 +455,10 @@ static int __simple_for_each_link(struct simple_util_priv *priv, node = of_get_next_child(top, node); } while (!is_top && node); - error: +error: of_node_put(node); - return ret; + return simple_ret(priv, ret); } static int simple_for_each_link(struct simple_util_priv *priv, @@ -479,7 +491,7 @@ static int simple_for_each_link(struct simple_util_priv *priv, break; } - return ret; + return simple_ret(priv, ret); } static void simple_depopulate_aux(void *data) @@ -500,9 +512,11 @@ static int simple_populate_aux(struct simple_util_priv *priv) ret = of_platform_populate(node, NULL, NULL, dev); if (ret) - return ret; + goto end; - return devm_add_action_or_reset(dev, simple_depopulate_aux, priv); + ret = devm_add_action_or_reset(dev, simple_depopulate_aux, priv); +end: + return simple_ret(priv, ret); } static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li) @@ -512,15 +526,15 @@ static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li) ret = simple_util_parse_widgets(card, PREFIX); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_routing(card, PREFIX); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_pin_switches(card, PREFIX); if (ret < 0) - return ret; + goto end; /* Single/Muti DAI link(s) & New style of DT node */ memset(li, 0, sizeof(*li)); @@ -528,19 +542,19 @@ static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li) simple_dai_link_of, simple_dai_link_of_dpcm); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_card_name(card, PREFIX); if (ret < 0) - return ret; + goto end; ret = simple_populate_aux(priv); if (ret < 0) - return ret; + goto end; ret = snd_soc_of_parse_aux_devs(card, PREFIX "aux-devs"); - - return ret; +end: + return simple_ret(priv, ret); } static int simple_count_noml(struct simple_util_priv *priv, @@ -548,12 +562,10 @@ static int simple_count_noml(struct simple_util_priv *priv, struct device_node *codec, struct link_info *li, bool is_top) { - if (li->link >= SNDRV_MAX_LINKS) { - struct device *dev = simple_priv_to_dev(priv); + int ret = -EINVAL; - dev_err(dev, "too many links\n"); - return -EINVAL; - } + if (li->link >= SNDRV_MAX_LINKS) + goto end; /* * DON'T REMOVE platforms @@ -575,8 +587,9 @@ static int simple_count_noml(struct simple_util_priv *priv, li->num[li->link].codecs = 1; li->link += 1; - - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } static int simple_count_dpcm(struct simple_util_priv *priv, @@ -584,12 +597,10 @@ static int simple_count_dpcm(struct simple_util_priv *priv, struct device_node *codec, struct link_info *li, bool is_top) { - if (li->link >= SNDRV_MAX_LINKS) { - struct device *dev = simple_priv_to_dev(priv); + int ret = -EINVAL; - dev_err(dev, "too many links\n"); - return -EINVAL; - } + if (li->link >= SNDRV_MAX_LINKS) + goto end; if (li->cpu) { /* @@ -606,8 +617,9 @@ static int simple_count_dpcm(struct simple_util_priv *priv, li->link++; /* dummy-Codec */ } - - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } static int simple_get_dais_count(struct simple_util_priv *priv, @@ -683,17 +695,15 @@ static int simple_soc_probe(struct snd_soc_card *card) ret = simple_util_init_hp(card, &priv->hp_jack, PREFIX); if (ret < 0) - return ret; + goto end; ret = simple_util_init_mic(card, &priv->mic_jack, PREFIX); if (ret < 0) - return ret; + goto end; ret = simple_util_init_aux_jacks(priv, PREFIX); - if (ret < 0) - return ret; - - return 0; +end: + return simple_ret(priv, ret); } static int simple_probe(struct platform_device *pdev) @@ -715,20 +725,22 @@ static int simple_probe(struct platform_device *pdev) card->probe = simple_soc_probe; card->driver_name = "simple-card"; + ret = -ENOMEM; struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL); if (!li) - return -ENOMEM; + goto end; ret = simple_get_dais_count(priv, li); if (ret < 0) - return ret; + goto end; + ret = -EINVAL; if (!li->link) - return -EINVAL; + goto end; ret = simple_util_init_priv(priv, li); if (ret < 0) - return ret; + goto end; if (np && of_device_is_available(np)) { @@ -795,8 +807,8 @@ static int simple_probe(struct platform_device *pdev) return 0; err: simple_util_clean_reference(card); - - return ret; +end: + return dev_err_probe(dev, ret, "parse error\n"); } static const struct of_device_id simple_of_match[] = { From 2d7395b23dbf4c2d60be49b73e4c4705fc446662 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Feb 2025 00:16:27 +0000 Subject: [PATCH 055/651] ASoC: simple-card-utils: use snd_soc_ret() We can use snd_soc_ret() to indicate error message when return. Let's use it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5b12qlg.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/simple_card_utils.h | 8 +- sound/soc/generic/audio-graph-card.c | 6 +- sound/soc/generic/audio-graph-card2.c | 14 +-- sound/soc/generic/simple-card-utils.c | 170 +++++++++++++++----------- sound/soc/generic/simple-card.c | 4 +- 5 files changed, 115 insertions(+), 87 deletions(-) diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 892f70532363..69a9c9c4d0e9 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -142,14 +142,14 @@ int simple_util_parse_daifmt(struct device *dev, struct device_node *codec, char *prefix, unsigned int *retfmt); -int simple_util_parse_tdm_width_map(struct device *dev, struct device_node *np, +int simple_util_parse_tdm_width_map(struct simple_util_priv *priv, struct device_node *np, struct simple_util_dai *dai); __printf(3, 4) -int simple_util_set_dailink_name(struct device *dev, +int simple_util_set_dailink_name(struct simple_util_priv *priv, struct snd_soc_dai_link *dai_link, const char *fmt, ...); -int simple_util_parse_card_name(struct snd_soc_card *card, +int simple_util_parse_card_name(struct simple_util_priv *priv, char *prefix); int simple_util_parse_clk(struct device *dev, @@ -201,7 +201,7 @@ void simple_util_remove(struct platform_device *pdev); int graph_util_card_probe(struct snd_soc_card *card); int graph_util_is_ports0(struct device_node *port); -int graph_util_parse_dai(struct device *dev, struct device_node *ep, +int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep, struct snd_soc_dai_link_component *dlc, int *is_single_link); void graph_util_parse_link_direction(struct device_node *np, diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 7c422535b01a..bd7ebbec0fc9 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -111,7 +111,7 @@ static int graph_parse_node(struct simple_util_priv *priv, dai = simple_props_to_dai_codec(dai_props, 0); } - ret = graph_util_parse_dai(dev, ep, dlc, cpu); + ret = graph_util_parse_dai(priv, ep, dlc, cpu); if (ret < 0) return ret; @@ -183,7 +183,7 @@ static int graph_link_init(struct simple_util_priv *priv, if (priv->ops) dai_link->ops = priv->ops; - return simple_util_set_dailink_name(dev, dai_link, name); + return simple_util_set_dailink_name(priv, dai_link, name); } static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, @@ -586,7 +586,7 @@ int audio_graph_parse_of(struct simple_util_priv *priv, struct device *dev) if (ret < 0) goto err; - ret = simple_util_parse_card_name(card, NULL); + ret = simple_util_parse_card_name(priv, NULL); if (ret < 0) goto err; diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index ee94b256b770..945a16e6d691 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -409,7 +409,7 @@ static int __graph_parse_node(struct simple_util_priv *priv, dai = simple_props_to_dai_codec(dai_props, idx); } - ret = graph_util_parse_dai(dev, ep, dlc, &is_single_links); + ret = graph_util_parse_dai(priv, ep, dlc, &is_single_links); if (ret < 0) return ret; @@ -417,7 +417,7 @@ static int __graph_parse_node(struct simple_util_priv *priv, if (ret < 0) return ret; - ret = simple_util_parse_tdm_width_map(dev, ep, dai); + ret = simple_util_parse_tdm_width_map(priv, ep, dai); if (ret < 0) return ret; @@ -443,22 +443,22 @@ static int __graph_parse_node(struct simple_util_priv *priv, case GRAPH_NORMAL: /* run is_cpu only. see audio_graph2_link_normal() */ if (is_cpu) - simple_util_set_dailink_name(dev, dai_link, "%s%s-%s%s", + simple_util_set_dailink_name(priv, dai_link, "%s%s-%s%s", cpus->dai_name, cpu_multi, codecs->dai_name, codec_multi); break; case GRAPH_DPCM: if (is_cpu) - simple_util_set_dailink_name(dev, dai_link, "fe.%pOFP.%s%s", + simple_util_set_dailink_name(priv, dai_link, "fe.%pOFP.%s%s", cpus->of_node, cpus->dai_name, cpu_multi); else - simple_util_set_dailink_name(dev, dai_link, "be.%pOFP.%s%s", + simple_util_set_dailink_name(priv, dai_link, "be.%pOFP.%s%s", codecs->of_node, codecs->dai_name, codec_multi); break; case GRAPH_C2C: /* run is_cpu only. see audio_graph2_link_c2c() */ if (is_cpu) - simple_util_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s", + simple_util_set_dailink_name(priv, dai_link, "c2c.%s%s-%s%s", cpus->dai_name, cpu_multi, codecs->dai_name, codec_multi); break; @@ -1332,7 +1332,7 @@ int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev, if (ret < 0) goto err; - ret = simple_util_parse_card_name(card, NULL); + ret = simple_util_parse_card_name(priv, NULL); if (ret < 0) goto err; diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index c2445c5ccd84..51e0e434514d 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -15,6 +15,13 @@ #include #include +#define simple_ret(priv, ret) _simple_ret(priv, __func__, ret) +static inline int _simple_ret(struct simple_util_priv *priv, + const char *func, int ret) +{ + return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func); +} + int simple_util_get_sample_fmt(struct simple_util_data *data) { int i; @@ -133,33 +140,42 @@ int simple_util_parse_daifmt(struct device *dev, } EXPORT_SYMBOL_GPL(simple_util_parse_daifmt); -int simple_util_parse_tdm_width_map(struct device *dev, struct device_node *np, +int simple_util_parse_tdm_width_map(struct simple_util_priv *priv, struct device_node *np, struct simple_util_dai *dai) { + struct device *dev = simple_priv_to_dev(priv); int n, i, ret; u32 *p; + /* + * NOTE + * + * Clang doesn't allow to use "goto end" before calling __free(), + * because it bypasses the initialization. Use simple_ret() directly. + */ + n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32)); if (n <= 0) return 0; + if (n % 3) { dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n"); - return -EINVAL; + return simple_ret(priv, -EINVAL); /* see NOTE */ } + ret = -ENOMEM; dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL); if (!dai->tdm_width_map) - return -ENOMEM; + return simple_ret(priv, ret); /* see NOTE */ - u32 *array_values __free(kfree) = kcalloc(n, sizeof(*array_values), - GFP_KERNEL); + u32 *array_values __free(kfree) = kcalloc(n, sizeof(*array_values), GFP_KERNEL); if (!array_values) - return -ENOMEM; + goto end; ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n); if (ret < 0) { dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret); - return ret; + goto end; } p = array_values; @@ -170,15 +186,17 @@ int simple_util_parse_tdm_width_map(struct device *dev, struct device_node *np, } dai->n_tdm_widths = i; - - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(simple_util_parse_tdm_width_map); -int simple_util_set_dailink_name(struct device *dev, +int simple_util_set_dailink_name(struct simple_util_priv *priv, struct snd_soc_dai_link *dai_link, const char *fmt, ...) { + struct device *dev = simple_priv_to_dev(priv); va_list ap; char *name = NULL; int ret = -ENOMEM; @@ -194,13 +212,14 @@ int simple_util_set_dailink_name(struct device *dev, dai_link->stream_name = name; } - return ret; + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(simple_util_set_dailink_name); -int simple_util_parse_card_name(struct snd_soc_card *card, +int simple_util_parse_card_name(struct simple_util_priv *priv, char *prefix) { + struct snd_soc_card *card = simple_priv_to_card(priv); int ret; if (!prefix) @@ -214,13 +233,13 @@ int simple_util_parse_card_name(struct snd_soc_card *card, snprintf(prop, sizeof(prop), "%sname", prefix); ret = snd_soc_of_parse_card_name(card, prop); if (ret < 0) - return ret; + goto end; } if (!card->name && card->dai_link) card->name = card->dai_link->name; - - return 0; +end: + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(simple_util_parse_card_name); @@ -348,7 +367,8 @@ cpu_err: break; simple_clk_disable(dai); } - return ret; + + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(simple_util_startup); @@ -379,16 +399,19 @@ void simple_util_shutdown(struct snd_pcm_substream *substream) } EXPORT_SYMBOL_GPL(simple_util_shutdown); -static int simple_set_clk_rate(struct device *dev, - struct simple_util_dai *simple_dai, - unsigned long rate) +static int simple_set_clk_rate(struct simple_util_priv *priv, + struct simple_util_dai *simple_dai, + unsigned long rate) { + struct device *dev = simple_priv_to_dev(priv); + int ret = -EINVAL; + if (!simple_dai) return 0; if (simple_dai->clk_fixed && rate != simple_dai->sysclk) { dev_err(dev, "dai %s invalid clock rate %lu\n", simple_dai->name, rate); - return -EINVAL; + goto end; } if (!simple_dai->clk) @@ -397,12 +420,15 @@ static int simple_set_clk_rate(struct device *dev, if (clk_get_rate(simple_dai->clk) == rate) return 0; - return clk_set_rate(simple_dai->clk, rate); + ret = clk_set_rate(simple_dai->clk, rate); +end: + return simple_ret(priv, ret); } -static int simple_set_tdm(struct snd_soc_dai *dai, - struct simple_util_dai *simple_dai, - struct snd_pcm_hw_params *params) +static int simple_set_tdm(struct simple_util_priv *priv, + struct snd_soc_dai *dai, + struct simple_util_dai *simple_dai, + struct snd_pcm_hw_params *params) { int sample_bits = params_width(params); int slot_width, slot_count; @@ -430,12 +456,8 @@ static int simple_set_tdm(struct snd_soc_dai *dai, simple_dai->rx_slot_mask, slot_count, slot_width); - if (ret && ret != -ENOTSUPP) { - dev_err(dai->dev, "simple-card: set_tdm_slot error: %d\n", ret); - return ret; - } - return 0; + return simple_ret(priv, ret); } int simple_util_hw_params(struct snd_pcm_substream *substream, @@ -457,15 +479,15 @@ int simple_util_hw_params(struct snd_pcm_substream *substream, mclk = params_rate(params) * mclk_fs; for_each_prop_dai_codec(props, i, pdai) { - ret = simple_set_clk_rate(rtd->dev, pdai, mclk); + ret = simple_set_clk_rate(priv, pdai, mclk); if (ret < 0) - return ret; + goto end; } for_each_prop_dai_cpu(props, i, pdai) { - ret = simple_set_clk_rate(rtd->dev, pdai, mclk); + ret = simple_set_clk_rate(priv, pdai, mclk); if (ret < 0) - return ret; + goto end; } /* Ensure sysclk is set on all components in case any @@ -476,39 +498,40 @@ int simple_util_hw_params(struct snd_pcm_substream *substream, ret = snd_soc_component_set_sysclk(component, 0, 0, mclk, SND_SOC_CLOCK_IN); if (ret && ret != -ENOTSUPP) - return ret; + goto end; } for_each_rtd_codec_dais(rtd, i, sdai) { pdai = simple_props_to_dai_codec(props, i); ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); if (ret && ret != -ENOTSUPP) - return ret; + goto end; } for_each_rtd_cpu_dais(rtd, i, sdai) { pdai = simple_props_to_dai_cpu(props, i); ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); if (ret && ret != -ENOTSUPP) - return ret; + goto end; } } for_each_prop_dai_codec(props, i, pdai) { sdai = snd_soc_rtd_to_codec(rtd, i); - ret = simple_set_tdm(sdai, pdai, params); + ret = simple_set_tdm(priv, sdai, pdai, params); if (ret < 0) - return ret; + goto end; } for_each_prop_dai_cpu(props, i, pdai) { sdai = snd_soc_rtd_to_cpu(rtd, i); - ret = simple_set_tdm(sdai, pdai, params); + ret = simple_set_tdm(priv, sdai, pdai, params); if (ret < 0) - return ret; + goto end; } - - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(simple_util_hw_params); @@ -536,7 +559,8 @@ int simple_util_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, } EXPORT_SYMBOL_GPL(simple_util_be_hw_params_fixup); -static int simple_init_dai(struct snd_soc_dai *dai, struct simple_util_dai *simple_dai) +static int simple_init_dai(struct simple_util_priv *priv, + struct snd_soc_dai *dai, struct simple_util_dai *simple_dai) { int ret; @@ -548,7 +572,7 @@ static int simple_init_dai(struct snd_soc_dai *dai, struct simple_util_dai *simp simple_dai->clk_direction); if (ret && ret != -ENOTSUPP) { dev_err(dai->dev, "simple-card: set_sysclk error\n"); - return ret; + goto end; } } @@ -560,11 +584,12 @@ static int simple_init_dai(struct snd_soc_dai *dai, struct simple_util_dai *simp simple_dai->slot_width); if (ret && ret != -ENOTSUPP) { dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); - return ret; + goto end; } } - - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } static inline int simple_component_is_codec(struct snd_soc_component *component) @@ -572,7 +597,8 @@ static inline int simple_component_is_codec(struct snd_soc_component *component) return component->driver->endianness; } -static int simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd, +static int simple_init_for_codec2codec(struct simple_util_priv *priv, + struct snd_soc_pcm_runtime *rtd, struct simple_dai_props *dai_props) { struct snd_soc_dai_link *dai_link = rtd->dai_link; @@ -604,12 +630,13 @@ static int simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd, if (ret < 0) { dev_err(rtd->dev, "simple-card: no valid dai_link params\n"); - return ret; + goto end; } + ret = -ENOMEM; c2c_params = devm_kzalloc(rtd->dev, sizeof(*c2c_params), GFP_KERNEL); if (!c2c_params) - return -ENOMEM; + goto end; c2c_params->formats = hw.formats; c2c_params->rates = hw.rates; @@ -621,7 +648,9 @@ static int simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd, dai_link->c2c_params = c2c_params; dai_link->num_c2c_params = 1; - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } int simple_util_dai_init(struct snd_soc_pcm_runtime *rtd) @@ -632,21 +661,19 @@ int simple_util_dai_init(struct snd_soc_pcm_runtime *rtd) int i, ret; for_each_prop_dai_codec(props, i, dai) { - ret = simple_init_dai(snd_soc_rtd_to_codec(rtd, i), dai); + ret = simple_init_dai(priv, snd_soc_rtd_to_codec(rtd, i), dai); if (ret < 0) - return ret; + goto end; } for_each_prop_dai_cpu(props, i, dai) { - ret = simple_init_dai(snd_soc_rtd_to_cpu(rtd, i), dai); + ret = simple_init_dai(priv, snd_soc_rtd_to_cpu(rtd, i), dai); if (ret < 0) - return ret; + goto end; } - ret = simple_init_for_codec2codec(rtd, props); - if (ret < 0) - return ret; - - return 0; + ret = simple_init_for_codec2codec(priv, rtd, props); +end: + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(simple_util_dai_init); @@ -831,7 +858,7 @@ int simple_util_init_aux_jacks(struct simple_util_priv *priv, char *prefix) priv->aux_jacks = devm_kcalloc(card->dev, num, sizeof(struct snd_soc_jack), GFP_KERNEL); if (!priv->aux_jacks) - return -ENOMEM; + return simple_ret(priv, -ENOMEM); for_each_card_auxs(card, component) { char id[128]; @@ -992,13 +1019,11 @@ int graph_util_card_probe(struct snd_soc_card *card) ret = simple_util_init_hp(card, &priv->hp_jack, NULL); if (ret < 0) - return ret; + goto end; ret = simple_util_init_mic(card, &priv->mic_jack, NULL); - if (ret < 0) - return ret; - - return 0; +end: + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(graph_util_card_probe); @@ -1074,9 +1099,10 @@ static int graph_get_dai_id(struct device_node *ep) return id; } -int graph_util_parse_dai(struct device *dev, struct device_node *ep, +int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep, struct snd_soc_dai_link_component *dlc, int *is_single_link) { + struct device *dev = simple_priv_to_dev(priv); struct of_phandle_args args = {}; struct snd_soc_dai *dai; int ret; @@ -1092,11 +1118,12 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep, args.np = ep; dai = snd_soc_get_dai_via_args(&args); if (dai) { + ret = -ENOMEM; dlc->of_node = node; dlc->dai_name = snd_soc_dai_name_get(dai); dlc->dai_args = snd_soc_copy_dai_args(dev, &args); if (!dlc->dai_args) - return -ENOMEM; + goto end; goto parse_dai_end; } @@ -1127,13 +1154,14 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep, */ ret = snd_soc_get_dlc(&args, dlc); if (ret < 0) - return ret; + goto end; parse_dai_end: if (is_single_link) *is_single_link = of_graph_get_endpoint_count(node) == 1; - - return 0; + ret = 0; +end: + return simple_ret(priv, ret); } EXPORT_SYMBOL_GPL(graph_util_parse_dai); diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 004fda4504c4..5af6d1b308f2 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -223,7 +223,7 @@ static int simple_link_init(struct simple_util_priv *priv, dai_link->init = simple_util_dai_init; dai_link->ops = &simple_ops; - ret = simple_util_set_dailink_name(dev, dai_link, name); + ret = simple_util_set_dailink_name(priv, dai_link, name); end: return simple_ret(priv, ret); } @@ -544,7 +544,7 @@ static int simple_parse_of(struct simple_util_priv *priv, struct link_info *li) if (ret < 0) goto end; - ret = simple_util_parse_card_name(card, PREFIX); + ret = simple_util_parse_card_name(priv, PREFIX); if (ret < 0) goto end; From 74a0ca4c7f19f1b273d665b3b53f7ae8af879658 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Feb 2025 00:16:31 +0000 Subject: [PATCH 056/651] ASoC: audio-graph-card: use snd_soc_ret() We can use snd_soc_ret() to indicate error message when return. Let's use it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qql2qlc.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/audio-graph-card.c | 93 +++++++++++++++------------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index bd7ebbec0fc9..a8a3bad3df00 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -20,6 +20,13 @@ #define DPCM_SELECTABLE 1 +#define graph_ret(priv, ret) _graph_ret(priv, __func__, ret) +static inline int _graph_ret(struct simple_util_priv *priv, + const char *func, int ret) +{ + return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func); +} + #define ep_to_port(ep) of_get_parent(ep) static struct device_node *port_to_ports(struct device_node *port) { @@ -113,17 +120,15 @@ static int graph_parse_node(struct simple_util_priv *priv, ret = graph_util_parse_dai(priv, ep, dlc, cpu); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_tdm(ep, dai); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_clk(dev, ep, dai, dlc); - if (ret < 0) - return ret; - - return 0; +end: + return graph_ret(priv, ret); } static int graph_link_init(struct simple_util_priv *priv, @@ -148,7 +153,7 @@ static int graph_link_init(struct simple_util_priv *priv, ret = simple_util_parse_daifmt(dev, ep_cpu, ep_codec, NULL, &dai_link->dai_fmt); if (ret < 0) - return ret; + goto end; graph_util_parse_link_direction(top, &playback_only, &capture_only); graph_util_parse_link_direction(port_cpu, &playback_only, &capture_only); @@ -183,7 +188,9 @@ static int graph_link_init(struct simple_util_priv *priv, if (priv->ops) dai_link->ops = priv->ops; - return simple_util_set_dailink_name(priv, dai_link, name); + ret = simple_util_set_dailink_name(priv, dai_link, name); +end: + return graph_ret(priv, ret); } static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, @@ -215,7 +222,7 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, ret = graph_parse_node(priv, cpu_ep, li, &is_single_links); if (ret) - return ret; + goto end; snprintf(dai_name, sizeof(dai_name), "fe.%pOFP.%s", cpus->of_node, cpus->dai_name); @@ -248,7 +255,7 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, ret = graph_parse_node(priv, codec_ep, li, NULL); if (ret < 0) - return ret; + goto end; snprintf(dai_name, sizeof(dai_name), "be.%pOFP.%s", codecs->of_node, codecs->dai_name); @@ -267,8 +274,8 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv, ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name); li->link++; - - return ret; +end: + return graph_ret(priv, ret); } static int graph_dai_link_of(struct simple_util_priv *priv, @@ -288,11 +295,11 @@ static int graph_dai_link_of(struct simple_util_priv *priv, ret = graph_parse_node(priv, cpu_ep, li, &is_single_links); if (ret < 0) - return ret; + goto end; ret = graph_parse_node(priv, codec_ep, li, NULL); if (ret < 0) - return ret; + goto end; snprintf(dai_name, sizeof(dai_name), "%s-%s", cpus->dai_name, codecs->dai_name); @@ -302,11 +309,11 @@ static int graph_dai_link_of(struct simple_util_priv *priv, ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name); if (ret < 0) - return ret; + goto end; li->link++; - - return 0; +end: + return graph_ret(priv, ret); } static inline bool parse_as_dpcm_link(struct simple_util_priv *priv, @@ -383,13 +390,13 @@ static int __graph_for_each_link(struct simple_util_priv *priv, } if (ret < 0) - return ret; + goto end; codec_port_old = codec_port; } } - - return 0; +end: + return graph_ret(priv, ret); } static int graph_for_each_link(struct simple_util_priv *priv, @@ -422,7 +429,7 @@ static int graph_for_each_link(struct simple_util_priv *priv, break; } - return ret; + return graph_ret(priv, ret); } static int graph_count_noml(struct simple_util_priv *priv, @@ -431,11 +438,10 @@ static int graph_count_noml(struct simple_util_priv *priv, struct link_info *li) { struct device *dev = simple_priv_to_dev(priv); + int ret = -EINVAL; - if (li->link >= SNDRV_MAX_LINKS) { - dev_err(dev, "too many links\n"); - return -EINVAL; - } + if (li->link >= SNDRV_MAX_LINKS) + goto end; /* * DON'T REMOVE platforms @@ -450,8 +456,9 @@ static int graph_count_noml(struct simple_util_priv *priv, li->link += 1; /* 1xCPU-Codec */ dev_dbg(dev, "Count As Normal\n"); - - return 0; + ret = 0; +end: + return graph_ret(priv, ret); } static int graph_count_dpcm(struct simple_util_priv *priv, @@ -460,11 +467,10 @@ static int graph_count_dpcm(struct simple_util_priv *priv, struct link_info *li) { struct device *dev = simple_priv_to_dev(priv); + int ret = -EINVAL; - if (li->link >= SNDRV_MAX_LINKS) { - dev_err(dev, "too many links\n"); - return -EINVAL; - } + if (li->link >= SNDRV_MAX_LINKS) + goto end; if (li->cpu) { /* @@ -483,8 +489,9 @@ static int graph_count_dpcm(struct simple_util_priv *priv, } dev_dbg(dev, "Count As DPCM\n"); - - return 0; + ret = 0; +end: + return graph_ret(priv, ret); } static int graph_get_dais_count(struct simple_util_priv *priv, @@ -544,40 +551,41 @@ static int graph_get_dais_count(struct simple_util_priv *priv, int audio_graph_parse_of(struct simple_util_priv *priv, struct device *dev) { struct snd_soc_card *card = simple_priv_to_card(priv); - int ret; + int ret = -ENOMEM; struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL); if (!li) - return -ENOMEM; + goto end; card->owner = THIS_MODULE; card->dev = dev; ret = graph_get_dais_count(priv, li); if (ret < 0) - return ret; + goto end; + ret = -EINVAL; if (!li->link) - return -EINVAL; + goto end; ret = simple_util_init_priv(priv, li); if (ret < 0) - return ret; + goto end; priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW); if (IS_ERR(priv->pa_gpio)) { ret = PTR_ERR(priv->pa_gpio); dev_err(dev, "failed to get amplifier gpio: %d\n", ret); - return ret; + goto end; } ret = simple_util_parse_widgets(card, NULL); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_routing(card, NULL); if (ret < 0) - return ret; + goto end; memset(li, 0, sizeof(*li)); ret = graph_for_each_link(priv, li, @@ -599,10 +607,9 @@ int audio_graph_parse_of(struct simple_util_priv *priv, struct device *dev) goto err; return 0; - err: simple_util_clean_reference(card); - +end: return dev_err_probe(dev, ret, "parse error\n"); } EXPORT_SYMBOL_GPL(audio_graph_parse_of); From 8d83282e53185ec257a4ce08812e8fabee2c7212 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Feb 2025 00:16:36 +0000 Subject: [PATCH 057/651] ASoC: audio-graph-card2: use snd_soc_ret() We can use snd_soc_ret() to indicate error message when return. Let's use it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c652ql8.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/audio-graph-card2.c | 81 ++++++++++++++++----------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 945a16e6d691..5dcc78c551a2 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -234,6 +234,13 @@ enum graph_type { #define GRAPH_NODENAME_DPCM "dpcm" #define GRAPH_NODENAME_C2C "codec2codec" +#define graph_ret(priv, ret) _graph_ret(priv, __func__, ret) +static inline int _graph_ret(struct simple_util_priv *priv, + const char *func, int ret) +{ + return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func); +} + #define ep_to_port(ep) of_get_parent(ep) static struct device_node *port_to_ports(struct device_node *port) { @@ -411,19 +418,19 @@ static int __graph_parse_node(struct simple_util_priv *priv, ret = graph_util_parse_dai(priv, ep, dlc, &is_single_links); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_tdm(ep, dai); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_tdm_width_map(priv, ep, dai); if (ret < 0) - return ret; + goto end; ret = simple_util_parse_clk(dev, ep, dai, dlc); if (ret < 0) - return ret; + goto end; /* * set DAI Name @@ -488,11 +495,12 @@ static int __graph_parse_node(struct simple_util_priv *priv, simple_util_canonicalize_cpu(cpus, is_single_links); simple_util_canonicalize_platform(platforms, cpus); } - - return 0; +end: + return graph_ret(priv, ret); } -static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, +static int graph_parse_node_multi_nm(struct simple_util_priv *priv, + struct snd_soc_dai_link *dai_link, int *nm_idx, int cpu_idx, struct device_node *mcpu_port) { @@ -534,10 +542,10 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, struct device_node *mcodec_port_top __free(device_node) = ep_to_port(mcodec_ep_top); struct device_node *mcodec_ports __free(device_node) = port_to_ports(mcodec_port_top); int nm_max = max(dai_link->num_cpus, dai_link->num_codecs); - int ret = 0; + int ret = -EINVAL; if (cpu_idx > dai_link->num_cpus) - return -EINVAL; + goto end; for_each_of_graph_port_endpoint(mcpu_port, mcpu_ep_n) { int codec_idx = 0; @@ -578,8 +586,8 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link, if (ret < 0) break; } - - return ret; +end: + return graph_ret(priv, ret); } static int graph_parse_node_multi(struct simple_util_priv *priv, @@ -633,7 +641,7 @@ static int graph_parse_node_multi(struct simple_util_priv *priv, /* CPU:Codec = N:M */ if (is_cpu && dai_link->ch_maps) { - ret = graph_parse_node_multi_nm(dai_link, &nm_idx, idx, port); + ret = graph_parse_node_multi_nm(priv, dai_link, &nm_idx, idx, port); if (ret < 0) goto multi_err; } @@ -643,7 +651,7 @@ static int graph_parse_node_multi(struct simple_util_priv *priv, ret = -EINVAL; multi_err: - return ret; + return graph_ret(priv, ret); } static int graph_parse_node_single(struct simple_util_priv *priv, @@ -651,7 +659,7 @@ static int graph_parse_node_single(struct simple_util_priv *priv, struct device_node *ep, struct link_info *li, int is_cpu) { - return __graph_parse_node(priv, gtype, ep, li, is_cpu, 0); + return graph_ret(priv, __graph_parse_node(priv, gtype, ep, li, is_cpu, 0)); } static int graph_parse_node(struct simple_util_priv *priv, @@ -660,11 +668,14 @@ static int graph_parse_node(struct simple_util_priv *priv, struct link_info *li, int is_cpu) { struct device_node *port __free(device_node) = ep_to_port(ep); + int ret; if (graph_lnk_is_multi(port)) - return graph_parse_node_multi(priv, gtype, port, li, is_cpu); + ret = graph_parse_node_multi(priv, gtype, port, li, is_cpu); else - return graph_parse_node_single(priv, gtype, ep, li, is_cpu); + ret = graph_parse_node_single(priv, gtype, ep, li, is_cpu); + + return graph_ret(priv, ret); } static void graph_parse_daifmt(struct device_node *node, unsigned int *daifmt) @@ -842,18 +853,19 @@ int audio_graph2_link_normal(struct simple_util_priv *priv, */ ret = graph_parse_node(priv, GRAPH_NORMAL, codec_ep, li, 0); if (ret < 0) - return ret; + goto end; /* * call CPU, and set DAI Name */ ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_ep, li, 1); if (ret < 0) - return ret; + goto end; graph_link_init(priv, lnk, cpu_ep, codec_ep, li, 1); - return ret; +end: + return graph_ret(priv, ret); } EXPORT_SYMBOL_GPL(audio_graph2_link_normal); @@ -946,7 +958,7 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv, graph_link_init(priv, lnk, cpu_ep, codec_ep, li, is_cpu); - return ret; + return graph_ret(priv, ret); } EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm); @@ -992,8 +1004,13 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv, struct snd_soc_pcm_stream *c2c_conf; c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL); - if (!c2c_conf) - return ret; + if (!c2c_conf) { + /* + * Clang doesn't allow to use "goto end" before calling __free(), + * because it bypasses the initialization. Use graph_ret() directly. + */ + return graph_ret(priv, -ENOMEM); + } c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ c2c_conf->rates = SNDRV_PCM_RATE_8000_384000; @@ -1019,18 +1036,18 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv, */ ret = graph_parse_node(priv, GRAPH_C2C, codec1_ep, li, 0); if (ret < 0) - return ret; + goto end; /* * call CPU, and set DAI Name */ ret = graph_parse_node(priv, GRAPH_C2C, codec0_ep, li, 1); if (ret < 0) - return ret; + goto end; graph_link_init(priv, lnk, codec0_ep, codec1_ep, li, 1); - - return ret; +end: + return graph_ret(priv, ret); } EXPORT_SYMBOL_GPL(audio_graph2_link_c2c); @@ -1078,7 +1095,7 @@ static int graph_link(struct simple_util_priv *priv, li->link++; err: - return ret; + return graph_ret(priv, ret); } static int graph_counter(struct device_node *lnk) @@ -1249,7 +1266,7 @@ static int graph_count(struct simple_util_priv *priv, li->link++; err: - return ret; + return graph_ret(priv, ret); } static int graph_for_each_link(struct simple_util_priv *priv, @@ -1266,7 +1283,7 @@ static int graph_for_each_link(struct simple_util_priv *priv, struct device_node *node = dev->of_node; struct device_node *lnk; enum graph_type gtype; - int rc, ret; + int rc, ret = 0; /* loop for all listed CPU port */ of_for_each_phandle(&it, rc, node, "links", NULL, 0) { @@ -1276,10 +1293,10 @@ static int graph_for_each_link(struct simple_util_priv *priv, ret = func(priv, hooks, gtype, lnk, li); if (ret < 0) - return ret; + break; } - return 0; + return graph_ret(priv, ret); } int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev, @@ -1355,7 +1372,7 @@ err: if (ret < 0) dev_err_probe(dev, ret, "parse error\n"); - return ret; + return graph_ret(priv, ret); } EXPORT_SYMBOL_GPL(audio_graph2_parse_of); From cb161c333927142818d6bf22a4da2b023fb2b8c9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 6 Feb 2025 21:25:15 +0200 Subject: [PATCH 058/651] ASoC: tas2781: Switch to use %ptTsr Use %ptTsr instead of open-coded variant to print contents of time64_t type in human readable form. Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20250206192537.1133763-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- include/sound/tas2781.h | 1 - sound/pci/hda/tas2781-spi.h | 1 - sound/pci/hda/tas2781_hda_i2c.c | 8 +++----- sound/pci/hda/tas2781_hda_spi.c | 3 --- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 72d2060904f6..0f1e585635bb 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -161,7 +161,6 @@ struct tasdevice_priv { struct mutex codec_lock; struct regmap *regmap; struct device *dev; - struct tm tm; enum device_catlog_id catlog_id; unsigned char cal_binaryname[TASDEVICE_MAX_CHANNELS][64]; diff --git a/sound/pci/hda/tas2781-spi.h b/sound/pci/hda/tas2781-spi.h index ecfc3c8bb821..7a0faceeb675 100644 --- a/sound/pci/hda/tas2781-spi.h +++ b/sound/pci/hda/tas2781-spi.h @@ -88,7 +88,6 @@ struct tasdevice_priv { struct mutex codec_lock; struct regmap *regmap; struct device *dev; - struct tm tm; unsigned char crc8_lkp_tbl[CRC8_TABLE_SIZE]; unsigned char coef_binaryname[64]; diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index 0e42b87dadb8..be9a90f643eb 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -594,7 +594,6 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv) efi_guid_t efi_guid = EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, 0x5a, 0xa3, 0x5d, 0xb3); static efi_char16_t efi_name[] = L"CALI_DATA"; - struct tm *tm = &tas_priv->tm; unsigned int attr, crc; unsigned int *tmp_val; efi_status_t status; @@ -629,10 +628,9 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv) crc, tmp_val[21]); if (crc == tmp_val[21]) { - time64_to_tm(tmp_val[20], 0, tm); - dev_dbg(tas_priv->dev, "%4ld-%2d-%2d, %2d:%2d:%2d\n", - tm->tm_year, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); + time64_t seconds = tmp_val[20]; + + dev_dbg(tas_priv->dev, "%ptTsr\n", &seconds); tasdevice_apply_calibration(tas_priv); } else tas_priv->cali_data.total_sz = 0; diff --git a/sound/pci/hda/tas2781_hda_spi.c b/sound/pci/hda/tas2781_hda_spi.c index a42fa990e7b9..d91b19602485 100644 --- a/sound/pci/hda/tas2781_hda_spi.c +++ b/sound/pci/hda/tas2781_hda_spi.c @@ -802,7 +802,6 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv) static efi_char16_t efi_name[] = TASDEVICE_CALIBRATION_DATA_NAME; unsigned char data[TASDEVICE_CALIBRATION_DATA_SIZE], *buf; unsigned int attr, crc, offset, *tmp_val; - struct tm *tm = &tas_priv->tm; unsigned long total_sz = 0; efi_status_t status; @@ -849,7 +848,6 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv) if (crc != tmp_val[3 + tmp_val[1] * 6]) return 0; - time64_to_tm(tmp_val[2], 0, tm); for (int j = 0; j < tmp_val[1]; j++) { offset = j * 6 + 3; if (tmp_val[offset] == tas_priv->index) { @@ -882,7 +880,6 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv) */ crc = crc32(~0, data, 84) ^ ~0; if (crc == tmp_val[21]) { - time64_to_tm(tmp_val[20], 0, tm); for (int i = 0; i < CALIB_MAX; i++) tas_priv->cali_data[i] = tmp_val[tas_priv->index * 5 + i]; From e2ceac2f323625632f12dd5333092976298a0cde Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:57:55 +0530 Subject: [PATCH 059/651] ASoC: amd: ps: rename structure names, variable and other macros Rename macros and structure names, variable with ACP63 tag which are specific to ACP6.3 platform. Rename 'stream_index' and 'sdw_dma_data' variable names to avoid check patch warnings. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-2-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 66 ++++++++++++++++---------------- sound/soc/amd/ps/pci-ps.c | 64 +++++++++++++++---------------- sound/soc/amd/ps/ps-sdw-dma.c | 72 +++++++++++++++++------------------ 3 files changed, 101 insertions(+), 101 deletions(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index e54eabaa4d3e..01910273624b 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -13,13 +13,13 @@ #define ACP63_REG_END 0x125C000 #define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 -#define ACP_PGFSM_CNTL_POWER_ON_MASK 1 -#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0 -#define ACP_PGFSM_STATUS_MASK 3 -#define ACP_POWERED_ON 0 -#define ACP_POWER_ON_IN_PROGRESS 1 -#define ACP_POWERED_OFF 2 -#define ACP_POWER_OFF_IN_PROGRESS 3 +#define ACP63_PGFSM_CNTL_POWER_ON_MASK 1 +#define ACP63_PGFSM_CNTL_POWER_OFF_MASK 0 +#define ACP63_PGFSM_STATUS_MASK 3 +#define ACP63_POWERED_ON 0 +#define ACP63_POWER_ON_IN_PROGRESS 1 +#define ACP63_POWERED_OFF 2 +#define ACP63_POWER_OFF_IN_PROGRESS 3 #define ACP_ERROR_MASK 0x20000000 #define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF @@ -60,7 +60,7 @@ #define AMD_SDW_MAX_MANAGERS 2 /* time in ms for acp timeout */ -#define ACP_TIMEOUT 500 +#define ACP63_TIMEOUT 500 #define ACP_SDW0_STAT BIT(21) #define ACP_SDW1_STAT BIT(2) @@ -72,13 +72,13 @@ #define ACP_AUDIO0_RX_THRESHOLD 0x1b #define ACP_AUDIO1_RX_THRESHOLD 0x19 #define ACP_AUDIO2_RX_THRESHOLD 0x17 -#define ACP_P1_AUDIO1_TX_THRESHOLD BIT(6) -#define ACP_P1_AUDIO1_RX_THRESHOLD BIT(5) -#define ACP_SDW_DMA_IRQ_MASK 0x1F800000 -#define ACP_P1_SDW_DMA_IRQ_MASK 0x60 +#define ACP63_P1_AUDIO1_TX_THRESHOLD BIT(6) +#define ACP63_P1_AUDIO1_RX_THRESHOLD BIT(5) +#define ACP63_SDW_DMA_IRQ_MASK 0x1F800000 +#define ACP63_P1_SDW_DMA_IRQ_MASK 0x60 #define ACP63_SDW0_DMA_MAX_STREAMS 6 #define ACP63_SDW1_DMA_MAX_STREAMS 2 -#define ACP_P1_AUDIO_TX_THRESHOLD 6 +#define ACP63_P1_AUDIO_TX_THRESHOLD 6 /* * Below entries describes SDW0 instance DMA stream id and DMA irq bit mapping @@ -91,8 +91,8 @@ * 4 (SDW0_AUDIO1_RX) 25 * 5 (SDW0_AUDIO2_RX) 23 */ -#define SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) -#define SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) +#define ACP63_SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) +#define ACP63_SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) /* * Below entries describes SDW1 instance DMA stream id and DMA irq bit mapping @@ -101,7 +101,7 @@ * 0 (SDW1_AUDIO1_TX) 6 * 1 (SDW1_AUDIO1_RX) 5 */ -#define SDW1_DMA_IRQ_MASK(i) (ACP_P1_AUDIO_TX_THRESHOLD - (i)) +#define ACP63_SDW1_DMA_IRQ_MASK(i) (ACP63_P1_AUDIO_TX_THRESHOLD - (i)) #define ACP_DELAY_US 5 #define ACP_SDW_RING_BUFF_ADDR_OFFSET (128 * 1024) @@ -148,18 +148,18 @@ enum acp_config { ACP_CONFIG_15, }; -enum amd_sdw0_channel { - ACP_SDW0_AUDIO0_TX = 0, - ACP_SDW0_AUDIO1_TX, - ACP_SDW0_AUDIO2_TX, - ACP_SDW0_AUDIO0_RX, - ACP_SDW0_AUDIO1_RX, - ACP_SDW0_AUDIO2_RX, +enum amd_acp63_sdw0_channel { + ACP63_SDW0_AUDIO0_TX = 0, + ACP63_SDW0_AUDIO1_TX, + ACP63_SDW0_AUDIO2_TX, + ACP63_SDW0_AUDIO0_RX, + ACP63_SDW0_AUDIO1_RX, + ACP63_SDW0_AUDIO2_RX, }; -enum amd_sdw1_channel { - ACP_SDW1_AUDIO1_TX, - ACP_SDW1_AUDIO1_RX, +enum amd_acp63_sdw1_channel { + ACP63_SDW1_AUDIO1_TX, + ACP63_SDW1_AUDIO1_RX, }; struct pdm_stream_instance { @@ -180,8 +180,8 @@ struct pdm_dev_data { struct sdw_dma_dev_data { void __iomem *acp_base; struct mutex *acp_lock; /* used to protect acp common register access */ - struct snd_pcm_substream *sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; - struct snd_pcm_substream *sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp63_sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp63_sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; }; struct acp_sdw_dma_stream { @@ -232,8 +232,10 @@ struct sdw_dma_ring_buf_reg { * @addr: pci ioremap address * @reg_range: ACP reigister range * @acp_rev: ACP PCI revision id - * @sdw0-dma_intr_stat: DMA interrupt status array for SoundWire manager-SW0 instance - * @sdw_dma_intr_stat: DMA interrupt status array for SoundWire manager-SW1 instance + * @acp63_sdw0-dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire + * manager-SW0 instance + * @acp63_sdw_dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire + * manager-SW1 instance */ struct acp63_dev_data { @@ -256,8 +258,8 @@ struct acp63_dev_data { u32 addr; u32 reg_range; u32 acp_rev; - u16 sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; - u16 sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; + u16 acp63_sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; + u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; }; int snd_amd_acp_find_config(struct pci_dev *pci); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 8b556950b855..f5beb7f14913 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -30,10 +30,10 @@ static int acp63_power_on(void __iomem *acp_base) if (!val) return val; - if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS) - writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); + if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS) + writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); - return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP_TIMEOUT); + return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT); } static int acp63_reset(void __iomem *acp_base) @@ -45,13 +45,13 @@ static int acp63_reset(void __iomem *acp_base) ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, - DELAY_US, ACP_TIMEOUT); + DELAY_US, ACP63_TIMEOUT); if (ret) return ret; writel(0, acp_base + ACP_SOFT_RESET); - return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT); + return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT); } static void acp63_enable_interrupts(void __iomem *acp_base) @@ -104,24 +104,24 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) static irqreturn_t acp63_irq_thread(int irq, void *context) { - struct sdw_dma_dev_data *sdw_dma_data; + struct sdw_dma_dev_data *sdw_data; struct acp63_dev_data *adata = context; - u32 stream_index; + u32 stream_id; - sdw_dma_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); + sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); - for (stream_index = 0; stream_index < ACP63_SDW0_DMA_MAX_STREAMS; stream_index++) { - if (adata->sdw0_dma_intr_stat[stream_index]) { - if (sdw_dma_data->sdw0_dma_stream[stream_index]) - snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]); - adata->sdw0_dma_intr_stat[stream_index] = 0; + for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw0_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw0_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]); + adata->acp63_sdw0_dma_intr_stat[stream_id] = 0; } } - for (stream_index = 0; stream_index < ACP63_SDW1_DMA_MAX_STREAMS; stream_index++) { - if (adata->sdw1_dma_intr_stat[stream_index]) { - if (sdw_dma_data->sdw1_dma_stream[stream_index]) - snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]); - adata->sdw1_dma_intr_stat[stream_index] = 0; + for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw1_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw1_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]); + adata->acp63_sdw1_dma_intr_stat[stream_id] = 0; } } return IRQ_HANDLED; @@ -180,48 +180,48 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) snd_pcm_period_elapsed(ps_pdm_data->capture_stream); irq_flag = 1; } - if (ext_intr_stat & ACP_SDW_DMA_IRQ_MASK) { + if (ext_intr_stat & ACP63_SDW_DMA_IRQ_MASK) { for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) { if (ext_intr_stat & BIT(index)) { writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); switch (index) { case ACP_AUDIO0_TX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO0_TX; + stream_id = ACP63_SDW0_AUDIO0_TX; break; case ACP_AUDIO1_TX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO1_TX; + stream_id = ACP63_SDW0_AUDIO1_TX; break; case ACP_AUDIO2_TX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO2_TX; + stream_id = ACP63_SDW0_AUDIO2_TX; break; case ACP_AUDIO0_RX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO0_RX; + stream_id = ACP63_SDW0_AUDIO0_RX; break; case ACP_AUDIO1_RX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO1_RX; + stream_id = ACP63_SDW0_AUDIO1_RX; break; case ACP_AUDIO2_RX_THRESHOLD: - stream_id = ACP_SDW0_AUDIO2_RX; + stream_id = ACP63_SDW0_AUDIO2_RX; break; } - adata->sdw0_dma_intr_stat[stream_id] = 1; + adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; sdw_dma_irq_flag = 1; } } } - if (ext_intr_stat1 & ACP_P1_AUDIO1_RX_THRESHOLD) { - writel(ACP_P1_AUDIO1_RX_THRESHOLD, + if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1; + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; sdw_dma_irq_flag = 1; } - if (ext_intr_stat1 & ACP_P1_AUDIO1_TX_THRESHOLD) { - writel(ACP_P1_AUDIO1_TX_THRESHOLD, + if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_TX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1; + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; sdw_dma_irq_flag = 1; } diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index b602cca92b8b..878683619a05 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -18,7 +18,7 @@ #define DRV_NAME "amd_ps_sdw_dma" -static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { +static struct sdw_dma_ring_buf_reg acp63_sdw0_dma_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE, ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, @@ -44,7 +44,7 @@ static struct sdw_dma_ring_buf_reg sdw0_dma_ring_buf_reg[ACP63_SDW0_DMA_MAX_STRE * For TX/RX streams DMA registers programming for SDW1 instance, it uses ACP_P1_AUDIO1 register * set as per hardware register documentation */ -static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { +static struct sdw_dma_ring_buf_reg acp63_sdw1_dma_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE, ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR, ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE, @@ -55,7 +55,7 @@ static struct sdw_dma_ring_buf_reg sdw1_dma_ring_buf_reg[ACP63_SDW1_DMA_MAX_STRE ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, }; -static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { +static u32 acp63_sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { ACP_SW0_AUDIO0_TX_EN, ACP_SW0_AUDIO1_TX_EN, ACP_SW0_AUDIO2_TX_EN, @@ -70,7 +70,7 @@ static u32 sdw0_dma_enable_reg[ACP63_SDW0_DMA_MAX_STREAMS] = { * it uses ACP_SW1_AUDIO1_TX_EN and ACP_SW1_AUDIO1_RX_EN registers * as per hardware register documentation. */ -static u32 sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { +static u32 acp63_sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { ACP_SW1_AUDIO1_TX_EN, ACP_SW1_AUDIO1_RX_EN, }; @@ -117,8 +117,8 @@ static const struct snd_pcm_hardware acp63_sdw_hardware_capture = { static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, bool enable) { u32 ext_intr_cntl, ext_intr_cntl1; - u32 irq_mask = ACP_SDW_DMA_IRQ_MASK; - u32 irq_mask1 = ACP_P1_SDW_DMA_IRQ_MASK; + u32 irq_mask = ACP63_SDW_DMA_IRQ_MASK; + u32 irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK; if (enable) { ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL); @@ -182,18 +182,18 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, switch (manager_instance) { case ACP_SDW0: - reg_dma_size = sdw0_dma_ring_buf_reg[stream_id].reg_dma_size; - reg_fifo_addr = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_addr; - reg_fifo_size = sdw0_dma_ring_buf_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = sdw0_dma_ring_buf_reg[stream_id].reg_ring_buf_addr; + reg_dma_size = acp63_sdw0_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp63_sdw0_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw0_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_addr; break; case ACP_SDW1: - reg_dma_size = sdw1_dma_ring_buf_reg[stream_id].reg_dma_size; - reg_fifo_addr = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_addr; - reg_fifo_size = sdw1_dma_ring_buf_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = sdw1_dma_ring_buf_reg[stream_id].reg_ring_buf_addr; + reg_dma_size = acp63_sdw1_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp63_sdw1_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw1_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_addr; break; default: return -EINVAL; @@ -267,19 +267,19 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, stream_id = stream->stream_id; switch (stream->instance) { case ACP_SDW0: - sdw_data->sdw0_dma_stream[stream_id] = substream; - water_mark_size_reg = sdw0_dma_ring_buf_reg[stream_id].water_mark_size_reg; + sdw_data->acp63_sdw0_dma_stream[stream_id] = substream; + water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg; acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - irq_mask = BIT(SDW0_DMA_TX_IRQ_MASK(stream_id)); + irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id)); else - irq_mask = BIT(SDW0_DMA_RX_IRQ_MASK(stream_id)); + irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id)); break; case ACP_SDW1: - sdw_data->sdw1_dma_stream[stream_id] = substream; + sdw_data->acp63_sdw1_dma_stream[stream_id] = substream; acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; - water_mark_size_reg = sdw1_dma_ring_buf_reg[stream_id].water_mark_size_reg; - irq_mask = BIT(SDW1_DMA_IRQ_MASK(stream_id)); + water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg; + irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(stream_id)); break; default: return -EINVAL; @@ -310,12 +310,12 @@ static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __io byte_count.bytescount = 0; switch (stream->instance) { case ACP_SDW0: - pos_low_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_low_reg; - pos_high_reg = sdw0_dma_ring_buf_reg[stream->stream_id].pos_high_reg; + pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg; break; case ACP_SDW1: - pos_low_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_low_reg; - pos_high_reg = sdw1_dma_ring_buf_reg[stream->stream_id].pos_high_reg; + pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg; break; default: goto POINTER_RETURN_BYTES; @@ -369,10 +369,10 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, return -EINVAL; switch (stream->instance) { case ACP_SDW0: - sdw_data->sdw0_dma_stream[stream->stream_id] = NULL; + sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL; break; case ACP_SDW1: - sdw_data->sdw1_dma_stream[stream->stream_id] = NULL; + sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL; break; default: return -EINVAL; @@ -395,10 +395,10 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream, stream_id = stream->stream_id; switch (stream->instance) { case ACP_SDW0: - sdw_dma_en_reg = sdw0_dma_enable_reg[stream_id]; + sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id]; break; case ACP_SDW1: - sdw_dma_en_reg = sdw1_dma_enable_reg[stream_id]; + sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[stream_id]; break; default: return -EINVAL; @@ -512,13 +512,11 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) for (index = 0; index < stream_count; index++) { if (instance == ACP_SDW0) { - substream = sdw_data->sdw0_dma_stream[index]; - water_mark_size_reg = - sdw0_dma_ring_buf_reg[index].water_mark_size_reg; + substream = sdw_data->acp63_sdw0_dma_stream[index]; + water_mark_size_reg = acp63_sdw0_dma_reg[index].water_mark_size_reg; } else { - substream = sdw_data->sdw1_dma_stream[index]; - water_mark_size_reg = - sdw1_dma_ring_buf_reg[index].water_mark_size_reg; + substream = sdw_data->acp63_sdw1_dma_stream[index]; + water_mark_size_reg = acp63_sdw1_dma_reg[index].water_mark_size_reg; } if (substream && substream->runtime) { From 4b36a47e2d989b98953dbfb1e97da0f0169f5086 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:57:56 +0530 Subject: [PATCH 060/651] ASoC: amd: ps: use macro for ACP6.3 pci revision id Use macro for ACP6.3 PCI revision id instead of hard coded value. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-3-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 1 + sound/soc/amd/ps/pci-ps.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 01910273624b..8f3a597f658b 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -11,6 +11,7 @@ #define ACP_DEVICE_ID 0x15E2 #define ACP63_REG_START 0x1240000 #define ACP63_REG_END 0x125C000 +#define ACP63_PCI_REV 0x63 #define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 #define ACP63_PGFSM_CNTL_POWER_ON_MASK 1 diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index f5beb7f14913..9cc66a807ad9 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -562,7 +562,7 @@ static int snd_acp63_probe(struct pci_dev *pci, /* Pink Sardine device check */ switch (pci->revision) { - case 0x63: + case ACP63_PCI_REV: break; default: dev_dbg(&pci->dev, "acp63 pci device not found\n"); From db746fff89a14419379226ce0df8b94f472cf38c Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:57:57 +0530 Subject: [PATCH 061/651] ASoC: amd: ps: add acp pci driver hw_ops for acp6.3 platform Add ACP6.3 platform specific PCI driver hw_ops for acp init/de-init sequence. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-4-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/Makefile | 2 +- sound/soc/amd/ps/acp63.h | 32 ++++++++++ sound/soc/amd/ps/pci-ps.c | 118 +++++++++-------------------------- sound/soc/amd/ps/ps-common.c | 104 ++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 89 deletions(-) create mode 100644 sound/soc/amd/ps/ps-common.c diff --git a/sound/soc/amd/ps/Makefile b/sound/soc/amd/ps/Makefile index b5efb1c5382c..778ee4726389 100644 --- a/sound/soc/amd/ps/Makefile +++ b/sound/soc/amd/ps/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only # Pink Sardine platform Support -snd-pci-ps-y := pci-ps.o +snd-pci-ps-y := pci-ps.o ps-common.o snd-ps-pdm-dma-y := ps-pdm-dma.o snd-soc-ps-mach-y := ps-mach.o snd-ps-sdw-dma-y := ps-sdw-dma.o diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 8f3a597f658b..ec22a7dad6ac 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -130,6 +130,8 @@ #define SDW_MAX_BUFFER (SDW_PLAYBACK_MAX_PERIOD_SIZE * SDW_PLAYBACK_MAX_NUM_PERIODS) #define SDW_MIN_BUFFER SDW_MAX_BUFFER +#define ACP_HW_OPS(acp_data, cb) ((acp_data)->hw_ops->cb) + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -213,10 +215,23 @@ struct sdw_dma_ring_buf_reg { u32 pos_high_reg; }; +struct acp63_dev_data; + +/** + * struct acp_hw_ops - ACP PCI driver platform specific ops + * @acp_init: ACP initialization + * @acp_deinit: ACP de-initialization + */ +struct acp_hw_ops { + int (*acp_init)(void __iomem *acp_base, struct device *dev); + int (*acp_deinit)(void __iomem *acp_base, struct device *dev); +}; + /** * struct acp63_dev_data - acp pci driver context * @acp63_base: acp mmio base * @res: resource + * @hw_ops: ACP pci driver platform-specific ops * @pdm_dev: ACP PDM controller platform device * @dmic_codec: platform device for DMIC Codec * sdw_dma_dev: platform device for SoundWire DMA controller @@ -242,6 +257,7 @@ struct sdw_dma_ring_buf_reg { struct acp63_dev_data { void __iomem *acp63_base; struct resource *res; + struct acp_hw_ops *hw_ops; struct platform_device *pdm_dev; struct platform_device *dmic_codec_dev; struct platform_device *sdw_dma_dev; @@ -263,4 +279,20 @@ struct acp63_dev_data { u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; }; +void acp63_hw_init_ops(struct acp_hw_ops *hw_ops); + +static inline int acp_hw_init(struct acp63_dev_data *adata, struct device *dev) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_init) + return ACP_HW_OPS(adata, acp_init)(adata->acp63_base, dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_deinit(struct acp63_dev_data *adata, struct device *dev) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_deinit) + return ACP_HW_OPS(adata, acp_deinit)(adata->acp63_base, dev); + return -EOPNOTSUPP; +} + int snd_amd_acp_find_config(struct pci_dev *pci); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 9cc66a807ad9..120bab1844bb 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -21,87 +21,6 @@ #include "acp63.h" -static int acp63_power_on(void __iomem *acp_base) -{ - u32 val; - - val = readl(acp_base + ACP_PGFSM_STATUS); - - if (!val) - return val; - - if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS) - writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); - - return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT); -} - -static int acp63_reset(void __iomem *acp_base) -{ - u32 val; - int ret; - - writel(1, acp_base + ACP_SOFT_RESET); - - ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, - val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, - DELAY_US, ACP63_TIMEOUT); - if (ret) - return ret; - - writel(0, acp_base + ACP_SOFT_RESET); - - return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT); -} - -static void acp63_enable_interrupts(void __iomem *acp_base) -{ - writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); - writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); -} - -static void acp63_disable_interrupts(void __iomem *acp_base) -{ - writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); - writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); - writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); -} - -static int acp63_init(void __iomem *acp_base, struct device *dev) -{ - int ret; - - ret = acp63_power_on(acp_base); - if (ret) { - dev_err(dev, "ACP power on failed\n"); - return ret; - } - writel(0x01, acp_base + ACP_CONTROL); - ret = acp63_reset(acp_base); - if (ret) { - dev_err(dev, "ACP reset failed\n"); - return ret; - } - acp63_enable_interrupts(acp_base); - writel(0, acp_base + ACP_ZSC_DSP_CTRL); - return 0; -} - -static int acp63_deinit(void __iomem *acp_base, struct device *dev) -{ - int ret; - - acp63_disable_interrupts(acp_base); - ret = acp63_reset(acp_base); - if (ret) { - dev_err(dev, "ACP reset failed\n"); - return ret; - } - writel(0, acp_base + ACP_CONTROL); - writel(1, acp_base + ACP_ZSC_DSP_CTRL); - return 0; -} - static irqreturn_t acp63_irq_thread(int irq, void *context) { struct sdw_dma_dev_data *sdw_data; @@ -540,11 +459,29 @@ unregister_dmic_codec_dev: unregister_pdm_dev: platform_device_unregister(adata->pdm_dev); de_init: - if (acp63_deinit(adata->acp63_base, &pci->dev)) + if (acp_hw_deinit(adata, &pci->dev)) dev_err(&pci->dev, "ACP de-init failed\n"); return ret; } +static int acp_hw_init_ops(struct acp63_dev_data *adata, struct pci_dev *pci) +{ + adata->hw_ops = devm_kzalloc(&pci->dev, sizeof(struct acp_hw_ops), + GFP_KERNEL); + if (!adata->hw_ops) + return -ENOMEM; + + switch (adata->acp_rev) { + case ACP63_PCI_REV: + acp63_hw_init_ops(adata->hw_ops); + break; + default: + dev_err(&pci->dev, "ACP device not found\n"); + return -ENODEV; + } + return 0; +} + static int snd_acp63_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -598,7 +535,12 @@ static int snd_acp63_probe(struct pci_dev *pci, pci_set_master(pci); pci_set_drvdata(pci, adata); mutex_init(&adata->acp_lock); - ret = acp63_init(adata->acp63_base, &pci->dev); + ret = acp_hw_init_ops(adata, pci); + if (ret) { + dev_err(&pci->dev, "ACP hw ops init failed\n"); + goto release_regions; + } + ret = acp_hw_init(adata, &pci->dev); if (ret) goto release_regions; ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler, @@ -632,7 +574,7 @@ skip_pdev_creation: pm_runtime_allow(&pci->dev); return 0; de_init: - if (acp63_deinit(adata->acp63_base, &pci->dev)) + if (acp_hw_deinit(adata, &pci->dev)) dev_err(&pci->dev, "ACP de-init failed\n"); release_regions: pci_release_regions(pci); @@ -677,7 +619,7 @@ static int __maybe_unused snd_acp63_suspend(struct device *dev) return 0; } } - ret = acp63_deinit(adata->acp63_base, dev); + ret = acp_hw_deinit(adata, dev); if (ret) dev_err(dev, "ACP de-init failed\n"); @@ -694,7 +636,7 @@ static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); return 0; } - ret = acp63_init(adata->acp63_base, dev); + ret = acp_hw_init(adata, dev); if (ret) { dev_err(dev, "ACP init failed\n"); return ret; @@ -716,7 +658,7 @@ static int __maybe_unused snd_acp63_resume(struct device *dev) return 0; } - ret = acp63_init(adata->acp63_base, dev); + ret = acp_hw_deinit(adata, dev); if (ret) dev_err(dev, "ACP init failed\n"); @@ -744,7 +686,7 @@ static void snd_acp63_remove(struct pci_dev *pci) } if (adata->mach_dev) platform_device_unregister(adata->mach_dev); - ret = acp63_deinit(adata->acp63_base, &pci->dev); + ret = acp_hw_deinit(adata, &pci->dev); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); pm_runtime_forbid(&pci->dev); diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c new file mode 100644 index 000000000000..771249a76537 --- /dev/null +++ b/sound/soc/amd/ps/ps-common.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * AMD ACP PCI driver callback routines for ACP6.3, ACP7.0 & ACP7.1 + * platforms. + * + * Copyright 2025 Advanced Micro Devices, Inc. + * Authors: Vijendar Mukunda + */ + +#include +#include +#include +#include +#include +#include + +#include "acp63.h" + +static int acp63_power_on(void __iomem *acp_base) +{ + u32 val; + + val = readl(acp_base + ACP_PGFSM_STATUS); + + if (!val) + return val; + + if ((val & ACP63_PGFSM_STATUS_MASK) != ACP63_POWER_ON_IN_PROGRESS) + writel(ACP63_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); + + return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP63_TIMEOUT); +} + +static int acp63_reset(void __iomem *acp_base) +{ + u32 val; + int ret; + + writel(1, acp_base + ACP_SOFT_RESET); + + ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, + val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, + DELAY_US, ACP63_TIMEOUT); + if (ret) + return ret; + + writel(0, acp_base + ACP_SOFT_RESET); + + return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP63_TIMEOUT); +} + +static void acp63_enable_interrupts(void __iomem *acp_base) +{ + writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); + writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); +} + +static void acp63_disable_interrupts(void __iomem *acp_base) +{ + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); + writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); + writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); +} + +static int acp63_init(void __iomem *acp_base, struct device *dev) +{ + int ret; + + ret = acp63_power_on(acp_base); + if (ret) { + dev_err(dev, "ACP power on failed\n"); + return ret; + } + writel(0x01, acp_base + ACP_CONTROL); + ret = acp63_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + acp63_enable_interrupts(acp_base); + writel(0, acp_base + ACP_ZSC_DSP_CTRL); + return 0; +} + +static int acp63_deinit(void __iomem *acp_base, struct device *dev) +{ + int ret; + + acp63_disable_interrupts(acp_base); + ret = acp63_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + writel(0, acp_base + ACP_CONTROL); + writel(1, acp_base + ACP_ZSC_DSP_CTRL); + return 0; +} + +void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) +{ + hw_ops->acp_init = acp63_init; + hw_ops->acp_deinit = acp63_deinit; +} From 491628388005a26c02d6827e649284357daec213 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:57:58 +0530 Subject: [PATCH 062/651] ASoC: amd: ps: add callback functions for acp pci driver pm ops Add acp pci driver pm ops related callback functions for ACP6.3 platform. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-5-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 44 ++++++++++++++++++ sound/soc/amd/ps/pci-ps.c | 82 ++++------------------------------ sound/soc/amd/ps/ps-common.c | 86 ++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 74 deletions(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index ec22a7dad6ac..4e3f7eaac040 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -221,10 +221,18 @@ struct acp63_dev_data; * struct acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization + * acp_suspend: ACP system level suspend callback + * acp_resume: ACP system level resume callback + * acp_suspend_runtime: ACP runtime suspend callback + * acp_resume_runtime: ACP runtime resume callback */ struct acp_hw_ops { int (*acp_init)(void __iomem *acp_base, struct device *dev); int (*acp_deinit)(void __iomem *acp_base, struct device *dev); + int (*acp_suspend)(struct device *dev); + int (*acp_resume)(struct device *dev); + int (*acp_suspend_runtime)(struct device *dev); + int (*acp_resume_runtime)(struct device *dev); }; /** @@ -295,4 +303,40 @@ static inline int acp_hw_deinit(struct acp63_dev_data *adata, struct device *dev return -EOPNOTSUPP; } +static inline int acp_hw_suspend(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_suspend) + return ACP_HW_OPS(adata, acp_suspend)(dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_resume(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_resume) + return ACP_HW_OPS(adata, acp_resume)(dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_suspend_runtime(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_suspend_runtime) + return ACP_HW_OPS(adata, acp_suspend_runtime)(dev); + return -EOPNOTSUPP; +} + +static inline int acp_hw_runtime_resume(struct device *dev) +{ + struct acp63_dev_data *adata = dev_get_drvdata(dev); + + if (adata && adata->hw_ops && adata->hw_ops->acp_resume_runtime) + return ACP_HW_OPS(adata, acp_resume_runtime)(dev); + return -EOPNOTSUPP; +} + int snd_amd_acp_find_config(struct pci_dev *pci); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 120bab1844bb..a37fb6172958 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -584,90 +584,24 @@ disable_pci: return ret; } -static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata) +static int __maybe_unused snd_acp_suspend(struct device *dev) { - u32 sdw0_en, sdw1_en; - - sdw0_en = readl(adata->acp63_base + ACP_SW0_EN); - sdw1_en = readl(adata->acp63_base + ACP_SW1_EN); - return (sdw0_en || sdw1_en); + return acp_hw_suspend(dev); } -static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata) +static int __maybe_unused snd_acp_runtime_resume(struct device *dev) { - u32 val; - - val = readl(adata->acp63_base + ACP_SW0_WAKE_EN); - if (val && adata->sdw->pdev[0]) - pm_request_resume(&adata->sdw->pdev[0]->dev); - - val = readl(adata->acp63_base + ACP_SW1_WAKE_EN); - if (val && adata->sdw->pdev[1]) - pm_request_resume(&adata->sdw->pdev[1]->dev); + return acp_hw_runtime_resume(dev); } -static int __maybe_unused snd_acp63_suspend(struct device *dev) +static int __maybe_unused snd_acp_resume(struct device *dev) { - struct acp63_dev_data *adata; - int ret; - - adata = dev_get_drvdata(dev); - if (adata->is_sdw_dev) { - adata->sdw_en_stat = check_acp_sdw_enable_status(adata); - if (adata->sdw_en_stat) { - writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); - return 0; - } - } - ret = acp_hw_deinit(adata, dev); - if (ret) - dev_err(dev, "ACP de-init failed\n"); - - return ret; -} - -static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) -{ - struct acp63_dev_data *adata; - int ret; - - adata = dev_get_drvdata(dev); - if (adata->sdw_en_stat) { - writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); - return 0; - } - ret = acp_hw_init(adata, dev); - if (ret) { - dev_err(dev, "ACP init failed\n"); - return ret; - } - - if (!adata->sdw_en_stat) - handle_acp63_sdw_pme_event(adata); - return 0; -} - -static int __maybe_unused snd_acp63_resume(struct device *dev) -{ - struct acp63_dev_data *adata; - int ret; - - adata = dev_get_drvdata(dev); - if (adata->sdw_en_stat) { - writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); - return 0; - } - - ret = acp_hw_deinit(adata, dev); - if (ret) - dev_err(dev, "ACP init failed\n"); - - return ret; + return acp_hw_resume(dev); } static const struct dev_pm_ops acp63_pm_ops = { - SET_RUNTIME_PM_OPS(snd_acp63_suspend, snd_acp63_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(snd_acp63_suspend, snd_acp63_resume) + SET_RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume) }; static void snd_acp63_remove(struct pci_dev *pci) diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 771249a76537..7643f321be37 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "acp63.h" @@ -97,8 +98,93 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) return 0; } +static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata) +{ + u32 sdw0_en, sdw1_en; + + sdw0_en = readl(adata->acp63_base + ACP_SW0_EN); + sdw1_en = readl(adata->acp63_base + ACP_SW1_EN); + return (sdw0_en || sdw1_en); +} + +static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata) +{ + u32 val; + + val = readl(adata->acp63_base + ACP_SW0_WAKE_EN); + if (val && adata->sdw->pdev[0]) + pm_request_resume(&adata->sdw->pdev[0]->dev); + + val = readl(adata->acp63_base + ACP_SW1_WAKE_EN); + if (val && adata->sdw->pdev[1]) + pm_request_resume(&adata->sdw->pdev[1]->dev); +} + +static int __maybe_unused snd_acp63_suspend(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->is_sdw_dev) { + adata->sdw_en_stat = check_acp_sdw_enable_status(adata); + if (adata->sdw_en_stat) { + writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + } + ret = acp_hw_deinit(adata, dev); + if (ret) + dev_err(dev, "ACP de-init failed\n"); + + return ret; +} + +static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + ret = acp_hw_init(adata, dev); + if (ret) { + dev_err(dev, "ACP init failed\n"); + return ret; + } + + if (!adata->sdw_en_stat) + handle_acp63_sdw_pme_event(adata); + return 0; +} + +static int __maybe_unused snd_acp63_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + + ret = acp_hw_init(adata, dev); + if (ret) + dev_err(dev, "ACP init failed\n"); + + return ret; +} + void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp63_init; hw_ops->acp_deinit = acp63_deinit; + hw_ops->acp_suspend = snd_acp63_suspend; + hw_ops->acp_resume = snd_acp63_resume; + hw_ops->acp_suspend_runtime = snd_acp63_suspend; + hw_ops->acp_resume_runtime = snd_acp63_runtime_resume; } From 6547577e94ae3d9f8ff30d3267fe7ec394e3b20d Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:57:59 +0530 Subject: [PATCH 063/651] ASoC: amd: ps: add callback to read acp pin configuration Add pci driver callback to read acp pin configuration for ACP6.3 platform. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-6-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 8 ++++++++ sound/soc/amd/ps/pci-ps.c | 26 +------------------------- sound/soc/amd/ps/ps-common.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 4e3f7eaac040..a918a988e4d8 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -221,6 +221,7 @@ struct acp63_dev_data; * struct acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization + * @acp_get_config: function to read the acp pin configuration * acp_suspend: ACP system level suspend callback * acp_resume: ACP system level resume callback * acp_suspend_runtime: ACP runtime suspend callback @@ -229,6 +230,7 @@ struct acp63_dev_data; struct acp_hw_ops { int (*acp_init)(void __iomem *acp_base, struct device *dev); int (*acp_deinit)(void __iomem *acp_base, struct device *dev); + void (*acp_get_config)(struct pci_dev *pci, struct acp63_dev_data *acp_data); int (*acp_suspend)(struct device *dev); int (*acp_resume)(struct device *dev); int (*acp_suspend_runtime)(struct device *dev); @@ -303,6 +305,12 @@ static inline int acp_hw_deinit(struct acp63_dev_data *adata, struct device *dev return -EOPNOTSUPP; } +static inline void acp_hw_get_config(struct pci_dev *pci, struct acp63_dev_data *adata) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_get_config) + ACP_HW_OPS(adata, acp_get_config)(pci, adata); +} + static inline int acp_hw_suspend(struct device *dev) { struct acp63_dev_data *adata = dev_get_drvdata(dev); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index a37fb6172958..96399acf906c 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -299,7 +299,6 @@ static int get_acp63_device_config(struct pci_dev *pci, struct acp63_dev_data *a const union acpi_object *obj; acpi_handle handle; acpi_integer dmic_status; - u32 config; bool is_dmic_dev = false; bool is_sdw_dev = false; bool wov_en, dmic_en; @@ -309,30 +308,7 @@ static int get_acp63_device_config(struct pci_dev *pci, struct acp63_dev_data *a wov_en = true; dmic_en = false; - config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); - switch (config) { - case ACP_CONFIG_4: - case ACP_CONFIG_5: - case ACP_CONFIG_10: - case ACP_CONFIG_11: - acp_data->is_pdm_config = true; - break; - case ACP_CONFIG_2: - case ACP_CONFIG_3: - acp_data->is_sdw_config = true; - break; - case ACP_CONFIG_6: - case ACP_CONFIG_7: - case ACP_CONFIG_12: - case ACP_CONFIG_8: - case ACP_CONFIG_13: - case ACP_CONFIG_14: - acp_data->is_pdm_config = true; - acp_data->is_sdw_config = true; - break; - default: - break; - } + acp_hw_get_config(pci, acp_data); if (acp_data->is_pdm_config) { pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0); diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 7643f321be37..30e9e5fe034b 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -98,6 +99,37 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) return 0; } +static void acp63_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data) +{ + u32 config; + + config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); + dev_dbg(&pci->dev, "ACP config value: %d\n", config); + switch (config) { + case ACP_CONFIG_4: + case ACP_CONFIG_5: + case ACP_CONFIG_10: + case ACP_CONFIG_11: + acp_data->is_pdm_config = true; + break; + case ACP_CONFIG_2: + case ACP_CONFIG_3: + acp_data->is_sdw_config = true; + break; + case ACP_CONFIG_6: + case ACP_CONFIG_7: + case ACP_CONFIG_12: + case ACP_CONFIG_8: + case ACP_CONFIG_13: + case ACP_CONFIG_14: + acp_data->is_pdm_config = true; + acp_data->is_sdw_config = true; + break; + default: + break; + } +} + static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata) { u32 sdw0_en, sdw1_en; @@ -183,6 +215,7 @@ void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp63_init; hw_ops->acp_deinit = acp63_deinit; + hw_ops->acp_get_config = acp63_get_config; hw_ops->acp_suspend = snd_acp63_suspend; hw_ops->acp_resume = snd_acp63_resume; hw_ops->acp_suspend_runtime = snd_acp63_suspend; From 0a27b2d7a224326fab543ca586d501fe1857b655 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:00 +0530 Subject: [PATCH 064/651] ASoC: amd: ps: add soundwire dma irq thread callback Add acp pci driver Soundwire DMA irq thread callaback for ACP6.3 platform. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-7-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 8 ++++++++ sound/soc/amd/ps/pci-ps.c | 19 +------------------ sound/soc/amd/ps/ps-common.c | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index a918a988e4d8..9a20846d30ff 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -222,6 +222,7 @@ struct acp63_dev_data; * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization * @acp_get_config: function to read the acp pin configuration + * @acp_sdw_dma_irq_thread: ACP SoundWire DMA interrupt thread * acp_suspend: ACP system level suspend callback * acp_resume: ACP system level resume callback * acp_suspend_runtime: ACP runtime suspend callback @@ -231,6 +232,7 @@ struct acp_hw_ops { int (*acp_init)(void __iomem *acp_base, struct device *dev); int (*acp_deinit)(void __iomem *acp_base, struct device *dev); void (*acp_get_config)(struct pci_dev *pci, struct acp63_dev_data *acp_data); + void (*acp_sdw_dma_irq_thread)(struct acp63_dev_data *acp_data); int (*acp_suspend)(struct device *dev); int (*acp_resume)(struct device *dev); int (*acp_suspend_runtime)(struct device *dev); @@ -311,6 +313,12 @@ static inline void acp_hw_get_config(struct pci_dev *pci, struct acp63_dev_data ACP_HW_OPS(adata, acp_get_config)(pci, adata); } +static inline void acp_hw_sdw_dma_irq_thread(struct acp63_dev_data *adata) +{ + if (adata && adata->hw_ops && adata->hw_ops->acp_sdw_dma_irq_thread) + ACP_HW_OPS(adata, acp_sdw_dma_irq_thread)(adata); +} + static inline int acp_hw_suspend(struct device *dev) { struct acp63_dev_data *adata = dev_get_drvdata(dev); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 96399acf906c..5d9c230043a6 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -23,26 +23,9 @@ static irqreturn_t acp63_irq_thread(int irq, void *context) { - struct sdw_dma_dev_data *sdw_data; struct acp63_dev_data *adata = context; - u32 stream_id; - sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); - - for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) { - if (adata->acp63_sdw0_dma_intr_stat[stream_id]) { - if (sdw_data->acp63_sdw0_dma_stream[stream_id]) - snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]); - adata->acp63_sdw0_dma_intr_stat[stream_id] = 0; - } - } - for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) { - if (adata->acp63_sdw1_dma_intr_stat[stream_id]) { - if (sdw_data->acp63_sdw1_dma_stream[stream_id]) - snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]); - adata->acp63_sdw1_dma_intr_stat[stream_id] = 0; - } - } + acp_hw_sdw_dma_irq_thread(adata); return IRQ_HANDLED; } diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 30e9e5fe034b..9098974b3608 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "acp63.h" @@ -211,11 +212,35 @@ static int __maybe_unused snd_acp63_resume(struct device *dev) return ret; } +static void acp63_sdw_dma_irq_thread(struct acp63_dev_data *adata) +{ + struct sdw_dma_dev_data *sdw_data; + u32 stream_id; + + sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); + + for (stream_id = 0; stream_id < ACP63_SDW0_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw0_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw0_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw0_dma_stream[stream_id]); + adata->acp63_sdw0_dma_intr_stat[stream_id] = 0; + } + } + for (stream_id = 0; stream_id < ACP63_SDW1_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp63_sdw1_dma_intr_stat[stream_id]) { + if (sdw_data->acp63_sdw1_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp63_sdw1_dma_stream[stream_id]); + adata->acp63_sdw1_dma_intr_stat[stream_id] = 0; + } + } +} + void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp63_init; hw_ops->acp_deinit = acp63_deinit; hw_ops->acp_get_config = acp63_get_config; + hw_ops->acp_sdw_dma_irq_thread = acp63_sdw_dma_irq_thread; hw_ops->acp_suspend = snd_acp63_suspend; hw_ops->acp_resume = snd_acp63_resume; hw_ops->acp_suspend_runtime = snd_acp63_suspend; From 4516be370ced14c4fb454fd6cc016e47bffe109e Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:01 +0530 Subject: [PATCH 065/651] ASoC: amd: ps: refactor soundwire dma interrupt handling Move the Soundwire DMA interrupt handling to separate function. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-8-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/pci-ps.c | 96 ++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 5d9c230043a6..04b43b4128bc 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -21,6 +21,55 @@ #include "acp63.h" +static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 ext_intr_stat, + u32 ext_intr_stat1) +{ + u32 stream_id = 0; + u16 sdw_dma_irq_flag = 0; + u16 index; + + if (ext_intr_stat & ACP63_SDW_DMA_IRQ_MASK) { + for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) { + if (ext_intr_stat & BIT(index)) { + writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); + switch (index) { + case ACP_AUDIO0_TX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO0_TX; + break; + case ACP_AUDIO1_TX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO1_TX; + break; + case ACP_AUDIO2_TX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO2_TX; + break; + case ACP_AUDIO0_RX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO0_RX; + break; + case ACP_AUDIO1_RX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO1_RX; + break; + case ACP_AUDIO2_RX_THRESHOLD: + stream_id = ACP63_SDW0_AUDIO2_RX; + break; + } + adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; + sdw_dma_irq_flag = 1; + } + } + } + if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; + sdw_dma_irq_flag = 1; + } + if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_TX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; + sdw_dma_irq_flag = 1; + } + return sdw_dma_irq_flag; +} + static irqreturn_t acp63_irq_thread(int irq, void *context) { struct acp63_dev_data *adata = context; @@ -35,10 +84,8 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) struct pdm_dev_data *ps_pdm_data; struct amd_sdw_manager *amd_manager; u32 ext_intr_stat, ext_intr_stat1; - u32 stream_id = 0; u16 irq_flag = 0; u16 sdw_dma_irq_flag = 0; - u16 index; adata = dev_id; if (!adata) @@ -82,51 +129,8 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) snd_pcm_period_elapsed(ps_pdm_data->capture_stream); irq_flag = 1; } - if (ext_intr_stat & ACP63_SDW_DMA_IRQ_MASK) { - for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) { - if (ext_intr_stat & BIT(index)) { - writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); - switch (index) { - case ACP_AUDIO0_TX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO0_TX; - break; - case ACP_AUDIO1_TX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO1_TX; - break; - case ACP_AUDIO2_TX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO2_TX; - break; - case ACP_AUDIO0_RX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO0_RX; - break; - case ACP_AUDIO1_RX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO1_RX; - break; - case ACP_AUDIO2_RX_THRESHOLD: - stream_id = ACP63_SDW0_AUDIO2_RX; - break; - } - - adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; - sdw_dma_irq_flag = 1; - } - } - } - - if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_RX_THRESHOLD, - adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; - sdw_dma_irq_flag = 1; - } - - if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_TX_THRESHOLD, - adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; - sdw_dma_irq_flag = 1; - } + sdw_dma_irq_flag = check_and_handle_sdw_dma_irq(adata, ext_intr_stat, ext_intr_stat1); if (sdw_dma_irq_flag) return IRQ_WAKE_THREAD; From fcb754602724fa2a1d0db72f13ddc3ef0306f911 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:02 +0530 Subject: [PATCH 066/651] ASoC: amd: ps: store acp revision id in SoundWire dma driver private data Store acp pci revision id in SoundWire dma driver private data structure. It will be used to distinguish platform specific code. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-9-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 1 + sound/soc/amd/ps/ps-sdw-dma.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 9a20846d30ff..098597d92bf9 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -183,6 +183,7 @@ struct pdm_dev_data { struct sdw_dma_dev_data { void __iomem *acp_base; struct mutex *acp_lock; /* used to protect acp common register access */ + u32 acp_rev; struct snd_pcm_substream *acp63_sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; struct snd_pcm_substream *acp63_sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; }; diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 878683619a05..b3c716371d15 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -474,6 +474,7 @@ static int acp63_sdw_platform_probe(struct platform_device *pdev) return -ENOMEM; sdw_data->acp_lock = &acp_data->acp_lock; + sdw_data->acp_rev = acp_data->acp_rev; dev_set_drvdata(&pdev->dev, sdw_data); status = devm_snd_soc_register_component(&pdev->dev, &acp63_sdw_component, From 0fa0843db17ccd427fc7a23d313aafa88fc89e04 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:03 +0530 Subject: [PATCH 067/651] ASoC: amd: ps: refactor soundwire dma driver code Refactor existing SoundWire dma driver code by adding acp_rev check for ACP6.3 platform. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-10-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/ps-sdw-dma.c | 146 +++++++++++++++++++++------------- 1 file changed, 89 insertions(+), 57 deletions(-) diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index b3c716371d15..d10950e1cf73 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -167,7 +167,7 @@ static void acp63_config_dma(struct acp_sdw_dma_stream *stream, void __iomem *ac } static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 size, - u32 manager_instance) + u32 manager_instance, u32 acp_rev) { u32 reg_dma_size; u32 reg_fifo_addr; @@ -180,20 +180,26 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, u32 sdw_ring_buf_size; u32 sdw_mem_window_offset; - switch (manager_instance) { - case ACP_SDW0: - reg_dma_size = acp63_sdw0_dma_reg[stream_id].reg_dma_size; - reg_fifo_addr = acp63_sdw0_dma_reg[stream_id].reg_fifo_addr; - reg_fifo_size = acp63_sdw0_dma_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_addr; - break; - case ACP_SDW1: - reg_dma_size = acp63_sdw1_dma_reg[stream_id].reg_dma_size; - reg_fifo_addr = acp63_sdw1_dma_reg[stream_id].reg_fifo_addr; - reg_fifo_size = acp63_sdw1_dma_reg[stream_id].reg_fifo_size; - reg_ring_buf_size = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_size; - reg_ring_buf_addr = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_addr; + switch (acp_rev) { + case ACP63_PCI_REV: + switch (manager_instance) { + case ACP_SDW0: + reg_dma_size = acp63_sdw0_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp63_sdw0_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw0_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw0_dma_reg[stream_id].reg_ring_buf_addr; + break; + case ACP_SDW1: + reg_dma_size = acp63_sdw1_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp63_sdw1_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp63_sdw1_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp63_sdw1_dma_reg[stream_id].reg_ring_buf_addr; + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -265,21 +271,27 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, if (!stream) return -EINVAL; stream_id = stream->stream_id; - switch (stream->instance) { - case ACP_SDW0: - sdw_data->acp63_sdw0_dma_stream[stream_id] = substream; - water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg; - acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id)); - else - irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id)); - break; - case ACP_SDW1: - sdw_data->acp63_sdw1_dma_stream[stream_id] = substream; - acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; - water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg; - irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(stream_id)); + switch (sdw_data->acp_rev) { + case ACP63_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_data->acp63_sdw0_dma_stream[stream_id] = substream; + water_mark_size_reg = acp63_sdw0_dma_reg[stream_id].water_mark_size_reg; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + irq_mask = BIT(ACP63_SDW0_DMA_TX_IRQ_MASK(stream_id)); + else + irq_mask = BIT(ACP63_SDW0_DMA_RX_IRQ_MASK(stream_id)); + break; + case ACP_SDW1: + sdw_data->acp63_sdw1_dma_stream[stream_id] = substream; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; + water_mark_size_reg = acp63_sdw1_dma_reg[stream_id].water_mark_size_reg; + irq_mask = BIT(ACP63_SDW1_DMA_IRQ_MASK(stream_id)); + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -290,7 +302,7 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, stream->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); acp63_config_dma(stream, sdw_data->acp_base, stream_id); ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, stream_id, size, - stream->instance); + stream->instance, sdw_data->acp_rev); if (ret) { dev_err(component->dev, "Invalid DMA channel\n"); return -EINVAL; @@ -302,20 +314,27 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, return 0; } -static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base) +static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __iomem *acp_base, + u32 acp_rev) { union acp_sdw_dma_count byte_count; u32 pos_low_reg, pos_high_reg; byte_count.bytescount = 0; - switch (stream->instance) { - case ACP_SDW0: - pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg; - pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg; - break; - case ACP_SDW1: - pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg; - pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg; + switch (acp_rev) { + case ACP63_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + pos_low_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp63_sdw0_dma_reg[stream->stream_id].pos_high_reg; + break; + case ACP_SDW1: + pos_low_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp63_sdw1_dma_reg[stream->stream_id].pos_high_reg; + break; + default: + goto POINTER_RETURN_BYTES; + } break; default: goto POINTER_RETURN_BYTES; @@ -340,7 +359,7 @@ static snd_pcm_uframes_t acp63_sdw_dma_pointer(struct snd_soc_component *comp, stream = substream->runtime->private_data; buffersize = frames_to_bytes(substream->runtime, substream->runtime->buffer_size); - bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base); + bytescount = acp63_sdw_get_byte_count(stream, sdw_data->acp_base, sdw_data->acp_rev); if (bytescount > stream->bytescount) bytescount -= stream->bytescount; pos = do_div(bytescount, buffersize); @@ -367,12 +386,18 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, stream = substream->runtime->private_data; if (!stream) return -EINVAL; - switch (stream->instance) { - case ACP_SDW0: - sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL; - break; - case ACP_SDW1: - sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL; + switch (sdw_data->acp_rev) { + case ACP63_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_data->acp63_sdw0_dma_stream[stream->stream_id] = NULL; + break; + case ACP_SDW1: + sdw_data->acp63_sdw1_dma_stream[stream->stream_id] = NULL; + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -382,7 +407,7 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, } static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream, - void __iomem *acp_base, bool sdw_dma_enable) + void __iomem *acp_base, u32 acp_rev, bool sdw_dma_enable) { struct acp_sdw_dma_stream *stream; u32 stream_id; @@ -393,12 +418,18 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream, stream = substream->runtime->private_data; stream_id = stream->stream_id; - switch (stream->instance) { - case ACP_SDW0: - sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id]; - break; - case ACP_SDW1: - sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[stream_id]; + switch (acp_rev) { + case ACP63_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_dma_en_reg = acp63_sdw0_dma_enable_reg[stream_id]; + break; + case ACP_SDW1: + sdw_dma_en_reg = acp63_sdw1_dma_enable_reg[stream_id]; + break; + default: + return -EINVAL; + } break; default: return -EINVAL; @@ -422,12 +453,12 @@ static int acp63_sdw_dma_trigger(struct snd_soc_component *comp, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: - ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, true); + ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, true); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: - ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, false); + ret = acp63_sdw_dma_enable(substream, sdw_data->acp_base, sdw_data->acp_rev, false); break; default: ret = -EINVAL; @@ -527,7 +558,8 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) buf_size = frames_to_bytes(runtime, runtime->buffer_size); acp63_config_dma(stream, sdw_data->acp_base, index); ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index, - buf_size, instance); + buf_size, instance, + ACP63_PCI_REV); if (ret) return ret; writel(period_bytes, sdw_data->acp_base + water_mark_size_reg); From 43d6140cedad9f031b47dfde6f85856e007b3f04 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:04 +0530 Subject: [PATCH 068/651] ASoC: amd: ps: refactor soundwire dma interrupts enable/disable sequence Refactor SoundWire dma interrupts enable/disable sequence by passing interrupt mask values as an arguments. This will allow to use same function for enabling/disabling SoundWire dma interrupts for different platforms. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-11-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/ps-sdw-dma.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index d10950e1cf73..674203a20338 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -114,11 +114,10 @@ static const struct snd_pcm_hardware acp63_sdw_hardware_capture = { .periods_max = SDW_CAPTURE_MAX_NUM_PERIODS, }; -static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, bool enable) +static void acp63_enable_disable_sdw_dma_interrupts(void __iomem *acp_base, u32 irq_mask, + u32 irq_mask1, bool enable) { u32 ext_intr_cntl, ext_intr_cntl1; - u32 irq_mask = ACP63_SDW_DMA_IRQ_MASK; - u32 irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK; if (enable) { ext_intr_cntl = readl(acp_base + ACP_EXTERNAL_INTR_CNTL); @@ -533,9 +532,11 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; u32 period_bytes, buf_size, water_mark_size_reg; - u32 stream_count; + u32 stream_count, irq_mask, irq_mask1; int index, instance, ret; + irq_mask = ACP63_SDW_DMA_IRQ_MASK; + irq_mask1 = ACP63_P1_SDW_DMA_IRQ_MASK; for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) { if (instance == ACP_SDW0) stream_count = ACP63_SDW0_DMA_MAX_STREAMS; @@ -566,7 +567,7 @@ static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) } } } - acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, true); + acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true); return 0; } From 605aab3b3ca83f58681841b2dd16d4a7baefde6c Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:05 +0530 Subject: [PATCH 069/651] ASoC: amd: ps: rename acp_restore_sdw_dma_config() function Rename acp_restore_sdw_dma_config() as acp63_restore_sdw_dma_config() which is specific to ACP6.3 platform. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-12-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/ps-sdw-dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 674203a20338..7cd153a4edc9 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -526,7 +526,7 @@ static void acp63_sdw_platform_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) +static int acp63_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) { struct acp_sdw_dma_stream *stream; struct snd_pcm_substream *substream; @@ -576,7 +576,7 @@ static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) struct sdw_dma_dev_data *sdw_data; sdw_data = dev_get_drvdata(dev); - return acp_restore_sdw_dma_config(sdw_data); + return acp63_restore_sdw_dma_config(sdw_data); } static const struct dev_pm_ops acp63_pm_ops = { From 7c0ea26c57b0bb72d503fe27d6533f5addc5e3a3 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:06 +0530 Subject: [PATCH 070/651] ASoC: amd: ps: add pci driver hw_ops for ACP7.0 & ACP7.1 variants Add below ACP pci driver hw_ops for ACP7.0 & ACP7.1 variants. - acp_init() - acp_deinit() - acp_get_config() Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-13-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 14 ++++ sound/soc/amd/ps/pci-ps.c | 10 ++- sound/soc/amd/ps/ps-common.c | 138 +++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 098597d92bf9..f65f242211e9 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -12,6 +12,8 @@ #define ACP63_REG_START 0x1240000 #define ACP63_REG_END 0x125C000 #define ACP63_PCI_REV 0x63 +#define ACP70_PCI_REV 0x70 +#define ACP71_PCI_REV 0x71 #define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 #define ACP63_PGFSM_CNTL_POWER_ON_MASK 1 @@ -132,6 +134,12 @@ #define ACP_HW_OPS(acp_data, cb) ((acp_data)->hw_ops->cb) +#define ACP70_PGFSM_CNTL_POWER_ON_MASK 0x1F +#define ACP70_PGFSM_CNTL_POWER_OFF_MASK 0 +#define ACP70_PGFSM_STATUS_MASK 0xFF +#define ACP70_TIMEOUT 2000 +#define ACP70_SDW_HOST_WAKE_MASK 0x0C00000 + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -149,6 +157,11 @@ enum acp_config { ACP_CONFIG_13, ACP_CONFIG_14, ACP_CONFIG_15, + ACP_CONFIG_16, + ACP_CONFIG_17, + ACP_CONFIG_18, + ACP_CONFIG_19, + ACP_CONFIG_20, }; enum amd_acp63_sdw0_channel { @@ -293,6 +306,7 @@ struct acp63_dev_data { }; void acp63_hw_init_ops(struct acp_hw_ops *hw_ops); +void acp70_hw_init_ops(struct acp_hw_ops *hw_ops); static inline int acp_hw_init(struct acp63_dev_data *adata, struct device *dev) { diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 04b43b4128bc..8f73d2ce2197 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -438,6 +438,10 @@ static int acp_hw_init_ops(struct acp63_dev_data *adata, struct pci_dev *pci) case ACP63_PCI_REV: acp63_hw_init_ops(adata->hw_ops); break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + acp70_hw_init_ops(adata->hw_ops); + break; default: dev_err(&pci->dev, "ACP device not found\n"); return -ENODEV; @@ -460,12 +464,14 @@ static int snd_acp63_probe(struct pci_dev *pci, if (flag) return -ENODEV; - /* Pink Sardine device check */ + /* ACP PCI revision id check for ACP6.3, ACP7.0 & ACP7.1 platforms */ switch (pci->revision) { case ACP63_PCI_REV: + case ACP70_PCI_REV: + case ACP71_PCI_REV: break; default: - dev_dbg(&pci->dev, "acp63 pci device not found\n"); + dev_dbg(&pci->dev, "acp63/acp70/acp71 pci device not found\n"); return -ENODEV; } if (pci_enable_device(pci)) { diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 9098974b3608..a15284bde48d 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -246,3 +246,141 @@ void acp63_hw_init_ops(struct acp_hw_ops *hw_ops) hw_ops->acp_suspend_runtime = snd_acp63_suspend; hw_ops->acp_resume_runtime = snd_acp63_runtime_resume; } + +static int acp70_power_on(void __iomem *acp_base) +{ + u32 val = 0; + + val = readl(acp_base + ACP_PGFSM_STATUS); + + if (!val) + return 0; + if (val & ACP70_PGFSM_STATUS_MASK) + writel(ACP70_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL); + + return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP70_TIMEOUT); +} + +static int acp70_reset(void __iomem *acp_base) +{ + u32 val; + int ret; + + writel(1, acp_base + ACP_SOFT_RESET); + + ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, + val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK, + DELAY_US, ACP70_TIMEOUT); + if (ret) + return ret; + + writel(0, acp_base + ACP_SOFT_RESET); + + return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP70_TIMEOUT); +} + +static void acp70_enable_sdw_host_wake_interrupts(void __iomem *acp_base) +{ + u32 ext_intr_cntl1; + + ext_intr_cntl1 = readl(acp_base + ACP_EXTERNAL_INTR_CNTL1); + ext_intr_cntl1 |= ACP70_SDW_HOST_WAKE_MASK; + writel(ext_intr_cntl1, acp_base + ACP_EXTERNAL_INTR_CNTL1); +} + +static void acp70_enable_interrupts(void __iomem *acp_base) +{ + u32 sdw0_wake_en, sdw1_wake_en; + + writel(1, acp_base + ACP_EXTERNAL_INTR_ENB); + writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL); + sdw0_wake_en = readl(acp_base + ACP_SW0_WAKE_EN); + sdw1_wake_en = readl(acp_base + ACP_SW1_WAKE_EN); + if (sdw0_wake_en || sdw1_wake_en) + acp70_enable_sdw_host_wake_interrupts(acp_base); +} + +static void acp70_disable_interrupts(void __iomem *acp_base) +{ + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT); + writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL); + writel(0, acp_base + ACP_EXTERNAL_INTR_ENB); +} + +static int acp70_init(void __iomem *acp_base, struct device *dev) +{ + int ret; + + ret = acp70_power_on(acp_base); + if (ret) { + dev_err(dev, "ACP power on failed\n"); + return ret; + } + writel(0x01, acp_base + ACP_CONTROL); + ret = acp70_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + writel(0, acp_base + ACP_ZSC_DSP_CTRL); + acp70_enable_interrupts(acp_base); + writel(0x1, acp_base + ACP_PME_EN); + return 0; +} + +static int acp70_deinit(void __iomem *acp_base, struct device *dev) +{ + int ret; + + acp70_disable_interrupts(acp_base); + ret = acp70_reset(acp_base); + if (ret) { + dev_err(dev, "ACP reset failed\n"); + return ret; + } + writel(0x01, acp_base + ACP_ZSC_DSP_CTRL); + return 0; +} + +static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_data) +{ + u32 config; + + config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); + dev_dbg(&pci->dev, "ACP config value: %d\n", config); + switch (config) { + case ACP_CONFIG_4: + case ACP_CONFIG_5: + case ACP_CONFIG_10: + case ACP_CONFIG_11: + case ACP_CONFIG_20: + acp_data->is_pdm_config = true; + break; + case ACP_CONFIG_2: + case ACP_CONFIG_3: + case ACP_CONFIG_16: + acp_data->is_sdw_config = true; + break; + case ACP_CONFIG_6: + case ACP_CONFIG_7: + case ACP_CONFIG_12: + case ACP_CONFIG_8: + case ACP_CONFIG_13: + case ACP_CONFIG_14: + case ACP_CONFIG_17: + case ACP_CONFIG_18: + case ACP_CONFIG_19: + acp_data->is_pdm_config = true; + acp_data->is_sdw_config = true; + break; + default: + break; + } +} + +void acp70_hw_init_ops(struct acp_hw_ops *hw_ops) +{ + hw_ops->acp_init = acp70_init; + hw_ops->acp_deinit = acp70_deinit; + hw_ops->acp_get_config = acp70_get_config; +} From fde277dbcf53be685d0b9976d636366c80a74da8 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:07 +0530 Subject: [PATCH 071/651] ASoC: amd: ps: add pm ops related hw_ops for ACP7.0 & ACP7.1 platforms Add ACP7.0 & ACP7.1 platform specific PM ops related hw_ops. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-14-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/ps-common.c | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index a15284bde48d..6639dac0a415 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -378,9 +378,74 @@ static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_dat } } +static int __maybe_unused snd_acp70_suspend(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + if (adata->is_sdw_dev) { + adata->sdw_en_stat = check_acp_sdw_enable_status(adata); + if (adata->sdw_en_stat) { + writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); + return 0; + } + } + ret = acp_hw_deinit(adata, dev); + if (ret) + dev_err(dev, "ACP de-init failed\n"); + + return ret; +} + +static int __maybe_unused snd_acp70_runtime_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + writel(1, adata->acp63_base + ACP_PME_EN); + return 0; + } + + ret = acp_hw_init(adata, dev); + if (ret) { + dev_err(dev, "ACP init failed\n"); + return ret; + } + return 0; +} + +static int __maybe_unused snd_acp70_resume(struct device *dev) +{ + struct acp63_dev_data *adata; + int ret; + + adata = dev_get_drvdata(dev); + + if (adata->sdw_en_stat) { + writel(0, adata->acp63_base + ACP_ZSC_DSP_CTRL); + writel(1, adata->acp63_base + ACP_PME_EN); + return 0; + } + + ret = acp_hw_init(adata, dev); + if (ret) + dev_err(dev, "ACP init failed\n"); + + return ret; +} + void acp70_hw_init_ops(struct acp_hw_ops *hw_ops) { hw_ops->acp_init = acp70_init; hw_ops->acp_deinit = acp70_deinit; hw_ops->acp_get_config = acp70_get_config; + hw_ops->acp_suspend = snd_acp70_suspend; + hw_ops->acp_resume = snd_acp70_resume; + hw_ops->acp_suspend_runtime = snd_acp70_suspend; + hw_ops->acp_resume_runtime = snd_acp70_runtime_resume; } From c878d5c1a525b88807d9d79888fe8340bcbf1aa3 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:08 +0530 Subject: [PATCH 072/651] ASoC: amd: ps: add ACP7.0 & ACP7.1 specific soundwire dma driver changes Add SoundWire dma driver changes specific to ACP7.0 & ACP7.1 platforms. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-15-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 52 ++++++++++++ sound/soc/amd/ps/ps-sdw-dma.c | 154 ++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index f65f242211e9..4d197bb8271a 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -140,6 +140,47 @@ #define ACP70_TIMEOUT 2000 #define ACP70_SDW_HOST_WAKE_MASK 0x0C00000 +#define ACP70_SDW0_DMA_MAX_STREAMS 6 +#define ACP70_SDW1_DMA_MAX_STREAMS ACP70_SDW0_DMA_MAX_STREAMS + +#define ACP70_P1_AUDIO0_TX_THRESHOLD 0x8 +#define ACP70_P1_AUDIO1_TX_THRESHOLD 0x6 +#define ACP70_P1_AUDIO2_TX_THRESHOLD 0x4 +#define ACP70_P1_AUDIO0_RX_THRESHOLD 0x7 +#define ACP70_P1_AUDIO1_RX_THRESHOLD 0x5 +#define ACP70_P1_AUDIO2_RX_THRESHOLD 0x3 + +#define ACP70_SDW0_DMA_TX_IRQ_MASK(i) (ACP_AUDIO0_TX_THRESHOLD - (2 * (i))) +#define ACP70_SDW0_DMA_RX_IRQ_MASK(i) (ACP_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) + +/* + * Below entries describes SDW1 instance DMA stream id and DMA irq bit mapping + * in ACP_EXTENAL_INTR_CNTL1 register for ACP70/ACP71 platforms + * Stream id IRQ Bit + * 0 (SDW1_AUDIO0_TX) 8 + * 1 (SDW1_AUDIO1_TX) 6 + * 2 (SDW1_AUDIO2_TX) 4 + * 3 (SDW1_AUDIO0_RX) 7 + * 4 (SDW1_AUDIO1_RX) 5 + * 5 (SDW1_AUDIO2_RX) 3 + */ +#define ACP70_SDW1_DMA_TX_IRQ_MASK(i) (ACP70_P1_AUDIO0_TX_THRESHOLD - (2 * (i))) +#define ACP70_SDW1_DMA_RX_IRQ_MASK(i) (ACP70_P1_AUDIO0_RX_THRESHOLD - (2 * ((i) - 3))) + +#define ACP70_SW0_AUDIO0_TX_EN ACP_SW0_AUDIO0_TX_EN +#define ACP70_SW0_AUDIO1_TX_EN ACP_SW0_AUDIO1_TX_EN +#define ACP70_SW0_AUDIO2_TX_EN ACP_SW0_AUDIO2_TX_EN +#define ACP70_SW0_AUDIO0_RX_EN ACP_SW0_AUDIO0_RX_EN +#define ACP70_SW0_AUDIO1_RX_EN ACP_SW0_AUDIO1_RX_EN +#define ACP70_SW0_AUDIO2_RX_EN ACP_SW0_AUDIO2_RX_EN + +#define ACP70_SW1_AUDIO0_TX_EN 0x0003C10 +#define ACP70_SW1_AUDIO1_TX_EN 0x0003C50 +#define ACP70_SW1_AUDIO2_TX_EN 0x0003C6C +#define ACP70_SW1_AUDIO0_RX_EN 0x0003C88 +#define ACP70_SW1_AUDIO1_RX_EN 0x0003D28 +#define ACP70_SW1_AUDIO2_RX_EN 0x0003D44 + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -178,6 +219,15 @@ enum amd_acp63_sdw1_channel { ACP63_SDW1_AUDIO1_RX, }; +enum amd_acp70_sdw_channel { + ACP70_SDW_AUDIO0_TX = 0, + ACP70_SDW_AUDIO1_TX, + ACP70_SDW_AUDIO2_TX, + ACP70_SDW_AUDIO0_RX, + ACP70_SDW_AUDIO1_RX, + ACP70_SDW_AUDIO2_RX, +}; + struct pdm_stream_instance { u16 num_pages; u16 channels; @@ -199,6 +249,8 @@ struct sdw_dma_dev_data { u32 acp_rev; struct snd_pcm_substream *acp63_sdw0_dma_stream[ACP63_SDW0_DMA_MAX_STREAMS]; struct snd_pcm_substream *acp63_sdw1_dma_stream[ACP63_SDW1_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp70_sdw0_dma_stream[ACP70_SDW0_DMA_MAX_STREAMS]; + struct snd_pcm_substream *acp70_sdw1_dma_stream[ACP70_SDW1_DMA_MAX_STREAMS]; }; struct acp_sdw_dma_stream { diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 7cd153a4edc9..2966244eb25e 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -75,6 +75,72 @@ static u32 acp63_sdw1_dma_enable_reg[ACP63_SDW1_DMA_MAX_STREAMS] = { ACP_SW1_AUDIO1_RX_EN, }; +static struct sdw_dma_ring_buf_reg acp70_sdw0_dma_reg[ACP70_SDW0_DMA_MAX_STREAMS] = { + {ACP_AUDIO0_TX_DMA_SIZE, ACP_AUDIO0_TX_FIFOADDR, ACP_AUDIO0_TX_FIFOSIZE, + ACP_AUDIO0_TX_RINGBUFSIZE, ACP_AUDIO0_TX_RINGBUFADDR, ACP_AUDIO0_TX_INTR_WATERMARK_SIZE, + ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO1_TX_DMA_SIZE, ACP_AUDIO1_TX_FIFOADDR, ACP_AUDIO1_TX_FIFOSIZE, + ACP_AUDIO1_TX_RINGBUFSIZE, ACP_AUDIO1_TX_RINGBUFADDR, ACP_AUDIO1_TX_INTR_WATERMARK_SIZE, + ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO2_TX_DMA_SIZE, ACP_AUDIO2_TX_FIFOADDR, ACP_AUDIO2_TX_FIFOSIZE, + ACP_AUDIO2_TX_RINGBUFSIZE, ACP_AUDIO2_TX_RINGBUFADDR, ACP_AUDIO2_TX_INTR_WATERMARK_SIZE, + ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO0_RX_DMA_SIZE, ACP_AUDIO0_RX_FIFOADDR, ACP_AUDIO0_RX_FIFOSIZE, + ACP_AUDIO0_RX_RINGBUFSIZE, ACP_AUDIO0_RX_RINGBUFADDR, ACP_AUDIO0_RX_INTR_WATERMARK_SIZE, + ACP_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO1_RX_DMA_SIZE, ACP_AUDIO1_RX_FIFOADDR, ACP_AUDIO1_RX_FIFOSIZE, + ACP_AUDIO1_RX_RINGBUFSIZE, ACP_AUDIO1_RX_RINGBUFADDR, ACP_AUDIO1_RX_INTR_WATERMARK_SIZE, + ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_AUDIO2_RX_DMA_SIZE, ACP_AUDIO2_RX_FIFOADDR, ACP_AUDIO2_RX_FIFOSIZE, + ACP_AUDIO2_RX_RINGBUFSIZE, ACP_AUDIO2_RX_RINGBUFADDR, ACP_AUDIO2_RX_INTR_WATERMARK_SIZE, + ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH} +}; + +static struct sdw_dma_ring_buf_reg acp70_sdw1_dma_reg[ACP70_SDW1_DMA_MAX_STREAMS] = { + {ACP_P1_AUDIO0_TX_DMA_SIZE, ACP_P1_AUDIO0_TX_FIFOADDR, ACP_P1_AUDIO0_TX_FIFOSIZE, + ACP_P1_AUDIO0_TX_RINGBUFSIZE, ACP_P1_AUDIO0_TX_RINGBUFADDR, + ACP_P1_AUDIO0_TX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO1_TX_DMA_SIZE, ACP_P1_AUDIO1_TX_FIFOADDR, ACP_P1_AUDIO1_TX_FIFOSIZE, + ACP_P1_AUDIO1_TX_RINGBUFSIZE, ACP_P1_AUDIO1_TX_RINGBUFADDR, + ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO2_TX_DMA_SIZE, ACP_P1_AUDIO2_TX_FIFOADDR, ACP_P1_AUDIO2_TX_FIFOSIZE, + ACP_P1_AUDIO2_TX_RINGBUFSIZE, ACP_P1_AUDIO2_TX_RINGBUFADDR, + ACP_P1_AUDIO2_TX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO0_RX_DMA_SIZE, ACP_P1_AUDIO0_RX_FIFOADDR, ACP_P1_AUDIO0_RX_FIFOSIZE, + ACP_P1_AUDIO0_RX_RINGBUFSIZE, ACP_P1_AUDIO0_RX_RINGBUFADDR, + ACP_P1_AUDIO0_RX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO1_RX_DMA_SIZE, ACP_P1_AUDIO1_RX_FIFOADDR, ACP_P1_AUDIO1_RX_FIFOSIZE, + ACP_P1_AUDIO1_RX_RINGBUFSIZE, ACP_P1_AUDIO1_RX_RINGBUFADDR, + ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH}, + {ACP_P1_AUDIO2_RX_DMA_SIZE, ACP_P1_AUDIO2_RX_FIFOADDR, ACP_P1_AUDIO2_RX_FIFOSIZE, + ACP_P1_AUDIO2_RX_RINGBUFSIZE, ACP_P1_AUDIO2_RX_RINGBUFADDR, + ACP_P1_AUDIO2_RX_INTR_WATERMARK_SIZE, + ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_LOW, ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH} +}; + +static u32 acp70_sdw0_dma_enable_reg[ACP70_SDW0_DMA_MAX_STREAMS] = { + ACP70_SW0_AUDIO0_TX_EN, + ACP70_SW0_AUDIO1_TX_EN, + ACP70_SW0_AUDIO2_TX_EN, + ACP70_SW0_AUDIO0_RX_EN, + ACP70_SW0_AUDIO1_RX_EN, + ACP70_SW0_AUDIO2_RX_EN, +}; + +static u32 acp70_sdw1_dma_enable_reg[ACP70_SDW1_DMA_MAX_STREAMS] = { + ACP70_SW1_AUDIO0_TX_EN, + ACP70_SW1_AUDIO1_TX_EN, + ACP70_SW1_AUDIO2_TX_EN, + ACP70_SW1_AUDIO0_RX_EN, + ACP70_SW1_AUDIO1_RX_EN, + ACP70_SW1_AUDIO2_RX_EN, +}; + static const struct snd_pcm_hardware acp63_sdw_hardware_playback = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -200,6 +266,27 @@ static int acp63_configure_sdw_ringbuffer(void __iomem *acp_base, u32 stream_id, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (manager_instance) { + case ACP_SDW0: + reg_dma_size = acp70_sdw0_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp70_sdw0_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp70_sdw0_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp70_sdw0_dma_reg[stream_id].reg_ring_buf_addr; + break; + case ACP_SDW1: + reg_dma_size = acp70_sdw1_dma_reg[stream_id].reg_dma_size; + reg_fifo_addr = acp70_sdw1_dma_reg[stream_id].reg_fifo_addr; + reg_fifo_size = acp70_sdw1_dma_reg[stream_id].reg_fifo_size; + reg_ring_buf_size = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_size; + reg_ring_buf_addr = acp70_sdw1_dma_reg[stream_id].reg_ring_buf_addr; + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; } @@ -292,6 +379,32 @@ static int acp63_sdw_dma_hw_params(struct snd_soc_component *component, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_data->acp70_sdw0_dma_stream[stream_id] = substream; + water_mark_size_reg = acp70_sdw0_dma_reg[stream_id].water_mark_size_reg; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + irq_mask = BIT(ACP70_SDW0_DMA_TX_IRQ_MASK(stream_id)); + else + irq_mask = BIT(ACP70_SDW0_DMA_RX_IRQ_MASK(stream_id)); + break; + case ACP_SDW1: + sdw_data->acp70_sdw1_dma_stream[stream_id] = substream; + acp_ext_intr_cntl_reg = ACP_EXTERNAL_INTR_CNTL1; + water_mark_size_reg = acp70_sdw1_dma_reg[stream_id].water_mark_size_reg; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + irq_mask = BIT(ACP70_SDW1_DMA_TX_IRQ_MASK(stream_id)); + else + irq_mask = BIT(ACP70_SDW1_DMA_RX_IRQ_MASK(stream_id)); + + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; } @@ -335,6 +448,21 @@ static u64 acp63_sdw_get_byte_count(struct acp_sdw_dma_stream *stream, void __io goto POINTER_RETURN_BYTES; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + pos_low_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp70_sdw0_dma_reg[stream->stream_id].pos_high_reg; + break; + case ACP_SDW1: + pos_low_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_low_reg; + pos_high_reg = acp70_sdw1_dma_reg[stream->stream_id].pos_high_reg; + break; + default: + goto POINTER_RETURN_BYTES; + } + break; default: goto POINTER_RETURN_BYTES; } @@ -398,6 +526,19 @@ static int acp63_sdw_dma_close(struct snd_soc_component *component, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_data->acp70_sdw0_dma_stream[stream->stream_id] = NULL; + break; + case ACP_SDW1: + sdw_data->acp70_sdw1_dma_stream[stream->stream_id] = NULL; + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; } @@ -430,6 +571,19 @@ static int acp63_sdw_dma_enable(struct snd_pcm_substream *substream, return -EINVAL; } break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + switch (stream->instance) { + case ACP_SDW0: + sdw_dma_en_reg = acp70_sdw0_dma_enable_reg[stream_id]; + break; + case ACP_SDW1: + sdw_dma_en_reg = acp70_sdw1_dma_enable_reg[stream_id]; + break; + default: + return -EINVAL; + } + break; default: return -EINVAL; } From 1c35755f46423150e19ff57448786b4bb48fdb46 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:09 +0530 Subject: [PATCH 073/651] ASoC: amd: ps: implement function to restore dma config for ACP7.0 platform Implement function to restore the dma configuration during system level resume for ACP7.0 & ACP7.1 platforms. Add a conditional check to invoke restore dma configuration function based on acp pci revision id. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-16-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 2 ++ sound/soc/amd/ps/ps-sdw-dma.c | 46 ++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 4d197bb8271a..0aef3a852ff1 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -142,6 +142,8 @@ #define ACP70_SDW0_DMA_MAX_STREAMS 6 #define ACP70_SDW1_DMA_MAX_STREAMS ACP70_SDW0_DMA_MAX_STREAMS +#define ACP70_SDW_DMA_IRQ_MASK 0x1F800000 +#define ACP70_P1_SDW_DMA_IRQ_MASK 0x1F8 #define ACP70_P1_AUDIO0_TX_THRESHOLD 0x8 #define ACP70_P1_AUDIO1_TX_THRESHOLD 0x6 diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 2966244eb25e..557d312a23b2 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -725,12 +725,56 @@ static int acp63_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) return 0; } +static int acp70_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) +{ + struct acp_sdw_dma_stream *stream; + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + u32 period_bytes, buf_size, water_mark_size_reg; + u32 stream_count, irq_mask, irq_mask1; + int index, instance, ret; + + irq_mask = ACP70_SDW_DMA_IRQ_MASK; + irq_mask1 = ACP70_P1_SDW_DMA_IRQ_MASK; + stream_count = ACP70_SDW0_DMA_MAX_STREAMS; + for (instance = 0; instance < AMD_SDW_MAX_MANAGERS; instance++) { + for (index = 0; index < stream_count; index++) { + if (instance == ACP_SDW0) { + substream = sdw_data->acp70_sdw0_dma_stream[index]; + water_mark_size_reg = acp70_sdw0_dma_reg[index].water_mark_size_reg; + } else { + substream = sdw_data->acp70_sdw1_dma_stream[index]; + water_mark_size_reg = acp70_sdw1_dma_reg[index].water_mark_size_reg; + } + + if (substream && substream->runtime) { + runtime = substream->runtime; + stream = runtime->private_data; + period_bytes = frames_to_bytes(runtime, runtime->period_size); + buf_size = frames_to_bytes(runtime, runtime->buffer_size); + acp63_config_dma(stream, sdw_data->acp_base, index); + ret = acp63_configure_sdw_ringbuffer(sdw_data->acp_base, index, + buf_size, instance, + sdw_data->acp_rev); + if (ret) + return ret; + writel(period_bytes, sdw_data->acp_base + water_mark_size_reg); + } + } + } + acp63_enable_disable_sdw_dma_interrupts(sdw_data->acp_base, irq_mask, irq_mask1, true); + return 0; +} + static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) { struct sdw_dma_dev_data *sdw_data; sdw_data = dev_get_drvdata(dev); - return acp63_restore_sdw_dma_config(sdw_data); + if (sdw_data->acp_rev == ACP63_PCI_REV) + return acp63_restore_sdw_dma_config(sdw_data); + else + return acp70_restore_sdw_dma_config(sdw_data); } static const struct dev_pm_ops acp63_pm_ops = { From 0b6914a0121b4c9fc8f575b60a5dd43b74612908 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:10 +0530 Subject: [PATCH 074/651] ASoC: amd: ps: add soundwire dma interrupts handling for ACP7.0 platform Add Soundwie dma interrupts handling for ACP7.0 & ACP7.1 platforms. Add acp pci revision id conditional checks for handling platform specific implementation. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-17-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 6 ++++ sound/soc/amd/ps/pci-ps.c | 61 ++++++++++++++++++++++++++++++------ sound/soc/amd/ps/ps-common.c | 24 ++++++++++++++ 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 0aef3a852ff1..48dac2a044c2 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -332,6 +332,10 @@ struct acp_hw_ops { * manager-SW0 instance * @acp63_sdw_dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire * manager-SW1 instance + * @acp70_sdw0-dma_intr_stat: DMA interrupt status array for ACP7.0 platform SoundWire + * manager-SW0 instance + * @acp70_sdw_dma_intr_stat: DMA interrupt status array for ACP7.0 platform SoundWire + * manager-SW1 instance */ struct acp63_dev_data { @@ -357,6 +361,8 @@ struct acp63_dev_data { u32 acp_rev; u16 acp63_sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; + u16 acp70_sdw0_dma_intr_stat[ACP70_SDW0_DMA_MAX_STREAMS]; + u16 acp70_sdw1_dma_intr_stat[ACP70_SDW1_DMA_MAX_STREAMS]; }; void acp63_hw_init_ops(struct acp_hw_ops *hw_ops); diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 8f73d2ce2197..a9e140ca1296 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -52,20 +52,61 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 stream_id = ACP63_SDW0_AUDIO2_RX; break; } - adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; + if (adata->acp_rev >= ACP70_PCI_REV) + adata->acp70_sdw0_dma_intr_stat[stream_id] = 1; + else + adata->acp63_sdw0_dma_intr_stat[stream_id] = 1; + sdw_dma_irq_flag = 1; } } } - if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; - sdw_dma_irq_flag = 1; - } - if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { - writel(ACP63_P1_AUDIO1_TX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; - sdw_dma_irq_flag = 1; + if (adata->acp_rev == 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); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; + sdw_dma_irq_flag = 1; + } + if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { + writel(ACP63_P1_AUDIO1_TX_THRESHOLD, + adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_TX] = 1; + sdw_dma_irq_flag = 1; + } + } else { + if (ext_intr_stat1 & ACP70_P1_SDW_DMA_IRQ_MASK) { + for (index = ACP70_P1_AUDIO2_RX_THRESHOLD; + index <= ACP70_P1_AUDIO0_TX_THRESHOLD; index++) { + if (ext_intr_stat1 & BIT(index)) { + writel(BIT(index), + adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + switch (index) { + case ACP70_P1_AUDIO0_TX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO0_TX; + break; + case ACP70_P1_AUDIO1_TX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO1_TX; + break; + case ACP70_P1_AUDIO2_TX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO2_TX; + break; + case ACP70_P1_AUDIO0_RX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO0_RX; + break; + case ACP70_P1_AUDIO1_RX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO1_RX; + break; + case ACP70_P1_AUDIO2_RX_THRESHOLD: + stream_id = ACP70_SDW_AUDIO2_RX; + break; + } + + adata->acp70_sdw1_dma_intr_stat[stream_id] = 1; + sdw_dma_irq_flag = 1; + } + } + } } return sdw_dma_irq_flag; } diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 6639dac0a415..1c89fb5fe1da 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -378,6 +378,29 @@ static void acp70_get_config(struct pci_dev *pci, struct acp63_dev_data *acp_dat } } +static void acp70_sdw_dma_irq_thread(struct acp63_dev_data *adata) +{ + struct sdw_dma_dev_data *sdw_data; + u32 stream_id; + + sdw_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); + + for (stream_id = 0; stream_id < ACP70_SDW0_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp70_sdw0_dma_intr_stat[stream_id]) { + if (sdw_data->acp70_sdw0_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp70_sdw0_dma_stream[stream_id]); + adata->acp70_sdw0_dma_intr_stat[stream_id] = 0; + } + } + for (stream_id = 0; stream_id < ACP70_SDW1_DMA_MAX_STREAMS; stream_id++) { + if (adata->acp70_sdw1_dma_intr_stat[stream_id]) { + if (sdw_data->acp70_sdw1_dma_stream[stream_id]) + snd_pcm_period_elapsed(sdw_data->acp70_sdw1_dma_stream[stream_id]); + adata->acp70_sdw1_dma_intr_stat[stream_id] = 0; + } + } +} + static int __maybe_unused snd_acp70_suspend(struct device *dev) { struct acp63_dev_data *adata; @@ -444,6 +467,7 @@ void acp70_hw_init_ops(struct acp_hw_ops *hw_ops) hw_ops->acp_init = acp70_init; hw_ops->acp_deinit = acp70_deinit; hw_ops->acp_get_config = acp70_get_config; + hw_ops->acp_sdw_dma_irq_thread = acp70_sdw_dma_irq_thread; hw_ops->acp_suspend = snd_acp70_suspend; hw_ops->acp_resume = snd_acp70_resume; hw_ops->acp_suspend_runtime = snd_acp70_suspend; From 3898b189079c85735f57759b0d407518c01c745e Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:11 +0530 Subject: [PATCH 075/651] ASoC: amd: ps: add soundwire wake interrupt handling Add SoundWire wake interrupt handling for ACP7.0 & ACP7.1 platforms. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-18-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 8 +++++ sound/soc/amd/ps/pci-ps.c | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 48dac2a044c2..9940151b0675 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -139,6 +139,10 @@ #define ACP70_PGFSM_STATUS_MASK 0xFF #define ACP70_TIMEOUT 2000 #define ACP70_SDW_HOST_WAKE_MASK 0x0C00000 +#define ACP70_SDW0_HOST_WAKE_STAT BIT(24) +#define ACP70_SDW1_HOST_WAKE_STAT BIT(25) +#define ACP70_SDW0_PME_STAT BIT(26) +#define ACP70_SDW1_PME_STAT BIT(27) #define ACP70_SDW0_DMA_MAX_STREAMS 6 #define ACP70_SDW1_DMA_MAX_STREAMS ACP70_SDW0_DMA_MAX_STREAMS @@ -325,6 +329,8 @@ struct acp_hw_ops { * @is_pdm_config: flat set to true when PDM configuration is selected from BIOS * @is_sdw_config: flag set to true when SDW configuration is selected from BIOS * @sdw_en_stat: flag set to true when any one of the SoundWire manager instance is enabled + * @acp70_sdw0_wake_event: flag set to true when wake irq asserted for SW0 instance + * @acp70_sdw1_wake_event: flag set to true when wake irq asserted for SW1 instance * @addr: pci ioremap address * @reg_range: ACP reigister range * @acp_rev: ACP PCI revision id @@ -356,6 +362,8 @@ struct acp63_dev_data { bool is_pdm_config; bool is_sdw_config; bool sdw_en_stat; + bool acp70_sdw0_wake_event; + bool acp70_sdw1_wake_event; u32 addr; u32 reg_range; u32 acp_rev; diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index a9e140ca1296..6a725cf36345 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -21,6 +21,65 @@ #include "acp63.h" +static void handle_acp70_sdw_wake_event(struct acp63_dev_data *adata) +{ + struct amd_sdw_manager *amd_manager; + + if (adata->acp70_sdw0_wake_event) { + amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev); + if (amd_manager) + pm_request_resume(amd_manager->dev); + adata->acp70_sdw0_wake_event = 0; + } + + if (adata->acp70_sdw1_wake_event) { + amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev); + if (amd_manager) + pm_request_resume(amd_manager->dev); + adata->acp70_sdw1_wake_event = 0; + } +} + +static short int check_and_handle_acp70_sdw_wake_irq(struct acp63_dev_data *adata) +{ + u32 ext_intr_stat1; + int irq_flag = 0; + bool sdw_wake_irq = false; + + ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + if (ext_intr_stat1 & ACP70_SDW0_HOST_WAKE_STAT) { + writel(ACP70_SDW0_HOST_WAKE_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw0_wake_event = true; + sdw_wake_irq = true; + } + + if (ext_intr_stat1 & ACP70_SDW1_HOST_WAKE_STAT) { + writel(ACP70_SDW1_HOST_WAKE_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw1_wake_event = true; + sdw_wake_irq = true; + } + + if (ext_intr_stat1 & ACP70_SDW0_PME_STAT) { + writel(0, adata->acp63_base + ACP_SW0_WAKE_EN); + writel(ACP70_SDW0_PME_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw0_wake_event = true; + sdw_wake_irq = true; + } + + if (ext_intr_stat1 & ACP70_SDW1_PME_STAT) { + writel(0, adata->acp63_base + ACP_SW1_WAKE_EN); + writel(ACP70_SDW1_PME_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); + adata->acp70_sdw1_wake_event = true; + sdw_wake_irq = true; + } + + if (sdw_wake_irq) { + handle_acp70_sdw_wake_event(adata); + irq_flag = 1; + } + return irq_flag; +} + static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 ext_intr_stat, u32 ext_intr_stat1) { @@ -163,6 +222,9 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id) irq_flag = 1; } + if (adata->acp_rev >= ACP70_PCI_REV) + irq_flag = check_and_handle_acp70_sdw_wake_irq(adata); + if (ext_intr_stat & BIT(PDM_DMA_STAT)) { ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev); writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); From 0eb8f83c055cb3461734710d1b1ce2dd4f01806e Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:12 +0530 Subject: [PATCH 076/651] ASoC: amd: ps: update module description Update module description for Pink Sardine platform acp pci driver, SoundWire dma driver and PDM driver modules. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-19-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/pci-ps.c | 2 +- sound/soc/amd/ps/ps-pdm-dma.c | 2 +- sound/soc/amd/ps/ps-sdw-dma.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 6a725cf36345..3a6034e074f5 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -723,7 +723,7 @@ module_pci_driver(ps_acp63_driver); MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); MODULE_AUTHOR("Syed.SabaKareem@amd.com"); -MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver"); +MODULE_DESCRIPTION("AMD common ACP PCI driver for ACP6.3, ACP7.0 & ACP7.1 platforms"); MODULE_IMPORT_NS("SOUNDWIRE_AMD_INIT"); MODULE_IMPORT_NS("SND_AMD_SOUNDWIRE_ACPI"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c index 318fc260f293..e726186fe8c6 100644 --- a/sound/soc/amd/ps/ps-pdm-dma.c +++ b/sound/soc/amd/ps/ps-pdm-dma.c @@ -458,6 +458,6 @@ static struct platform_driver acp63_pdm_dma_driver = { module_platform_driver(acp63_pdm_dma_driver); MODULE_AUTHOR("Syed.SabaKareem@amd.com"); -MODULE_DESCRIPTION("AMD PINK SARDINE PDM Driver"); +MODULE_DESCRIPTION("AMD common PDM Driver for ACP6.3, ACP7,0 & ACP7.1 platforms"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 557d312a23b2..2461c6421ae9 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -793,6 +793,6 @@ static struct platform_driver acp63_sdw_dma_driver = { module_platform_driver(acp63_sdw_dma_driver); MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); -MODULE_DESCRIPTION("AMD ACP6.3 PS SDW DMA Driver"); +MODULE_DESCRIPTION("AMD common SDW DMA Driver for ACP6.3, ACP7.0 & ACP7.1 platforms"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); From f1e91acacf86fb2cd7478af490326cb9aa63e8ae Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:13 +0530 Subject: [PATCH 077/651] ASoC: amd: ps: update file description and copyright year Update files description for acp pci driver, SoundWire DMA driver, PDM driver and acp header file as new support is added for ACP7.0 & ACP7.1 platforms. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-20-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/acp63.h | 4 ++-- sound/soc/amd/ps/pci-ps.c | 4 ++-- sound/soc/amd/ps/ps-pdm-dma.c | 4 ++-- sound/soc/amd/ps/ps-sdw-dma.c | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 9940151b0675..85feae45c44c 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * AMD ALSA SoC PDM Driver + * AMD Common ACP header file for ACP6.3, ACP7.0 & ACP7.1 platforms * - * Copyright (C) 2022, 2023 Advanced Micro Devices, Inc. All rights reserved. + * Copyright (C) 2022, 2023, 2025 Advanced Micro Devices, Inc. All rights reserved. */ #include diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 3a6034e074f5..2cbfeb07d5c4 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * AMD Pink Sardine ACP PCI Driver + * AMD common ACP PCI driver for ACP6.3, ACP7.0 & ACP7.1 platforms. * - * Copyright 2022 Advanced Micro Devices, Inc. + * Copyright 2022, 2025 Advanced Micro Devices, Inc. */ #include diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c index e726186fe8c6..7cdeb34e8f73 100644 --- a/sound/soc/amd/ps/ps-pdm-dma.c +++ b/sound/soc/amd/ps/ps-pdm-dma.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * AMD ALSA SoC Pink Sardine PDM Driver + * AMD ALSA SoC common PDM Driver for ACP6.3, ACP7.0 & ACP7.1 platforms. * - * Copyright 2022 Advanced Micro Devices, Inc. + * Copyright 2022, 2025 Advanced Micro Devices, Inc. */ #include diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 2461c6421ae9..21b336109c99 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * AMD ALSA SoC Pink Sardine SoundWire DMA Driver + * AMD ALSA SoC common SoundWire DMA Driver for ACP6.3, ACP7.0 and ACP7.1 + * platforms. * - * Copyright 2023 Advanced Micro Devices, Inc. + * Copyright 2023, 2025 Advanced Micro Devices, Inc. */ #include From 552f66c40134542f15d4302837e7d581a0b8e217 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:14 +0530 Subject: [PATCH 078/651] ASoC: amd: update Pink Sardine platform Kconfig description Update Pink Sardine platform Kconfig option description. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-21-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 803521178279..c7daae392d74 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -161,15 +161,15 @@ config SND_SOC_AMD_SOUNDWIRE If unsure select "N". config SND_SOC_AMD_PS - tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support" + tristate "AMD Audio Coprocessor-v6.3/v7.0/v7.1 support" select SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE select SND_SOC_ACPI_AMD_MATCH depends on X86 && PCI && ACPI help - This option enables Audio Coprocessor i.e ACP v6.3 support on - AMD Pink sardine platform. By enabling this flag build will be - triggered for ACP PCI driver, ACP PDM DMA driver, ACP SoundWire - DMA driver. + This option enables Audio Coprocessor i.e ACP6.3/ACP7.0/ACP7.1 + variants support. By enabling this flag build will be triggered + for ACP PCI driver, ACP PDM DMA driver, ACP SoundWire DMA + driver. Say m if you have such a device. If unsure select "N". From 638ad2bdb2f994c8bd99cc40e0c4796a8617ccf3 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:15 +0530 Subject: [PATCH 079/651] ASoC: amd: acp: add machine driver changes for ACP7.0 and ACP7.1 platforms Add SoundWire generic machine driver changes for legacy stack(No DSP) for ACP7.0 and ACP7.1 platforms. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-22-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-sdw-legacy-mach.c | 11 ++++++++ sound/soc/amd/acp/acp-sdw-mach-common.c | 34 +++++++++++++++++++++++++ sound/soc/amd/acp/soc_amd_sdw_common.h | 11 ++++++++ 3 files changed, 56 insertions(+) diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c index 9280cd30d19c..00aeea70f04e 100644 --- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c +++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c @@ -122,6 +122,13 @@ static int create_sdw_dailink(struct snd_soc_card *card, if (ret) return ret; break; + case ACP70_PCI_REV: + case ACP71_PCI_REV: + ret = get_acp70_cpu_pin_id(ffs(soc_end->link_mask - 1), + *be_id, &cpu_pin_id, dev); + if (ret) + return ret; + break; default: return -EINVAL; } @@ -221,6 +228,8 @@ static int create_sdw_dailinks(struct snd_soc_card *card, switch (amd_ctx->acp_rev) { case ACP63_PCI_REV: + case ACP70_PCI_REV: + case ACP71_PCI_REV: sdw_platform_component->name = "amd_ps_sdw_dma.0"; break; default: @@ -266,6 +275,8 @@ static int create_dmic_dailinks(struct snd_soc_card *card, switch (amd_ctx->acp_rev) { case ACP63_PCI_REV: + case ACP70_PCI_REV: + case ACP71_PCI_REV: pdm_cpu->name = "acp_ps_pdm_dma.0"; pdm_platform->name = "acp_ps_pdm_dma.0"; break; diff --git a/sound/soc/amd/acp/acp-sdw-mach-common.c b/sound/soc/amd/acp/acp-sdw-mach-common.c index 6f5c39ed1a18..e5f394dc2f4c 100644 --- a/sound/soc/amd/acp/acp-sdw-mach-common.c +++ b/sound/soc/amd/acp/acp-sdw-mach-common.c @@ -59,6 +59,40 @@ int get_acp63_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct dev } EXPORT_SYMBOL_NS_GPL(get_acp63_cpu_pin_id, "SND_SOC_AMD_SDW_MACH"); +int get_acp70_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct device *dev) +{ + switch (sdw_link_id) { + case AMD_SDW0: + case AMD_SDW1: + switch (be_id) { + case SOC_SDW_JACK_OUT_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO0_TX; + break; + case SOC_SDW_JACK_IN_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO0_RX; + break; + case SOC_SDW_AMP_OUT_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO1_TX; + break; + case SOC_SDW_AMP_IN_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO1_RX; + break; + case SOC_SDW_DMIC_DAI_ID: + *cpu_pin_id = ACP70_SW_AUDIO2_RX; + break; + default: + dev_err(dev, "Invalid be id:%d\n", be_id); + return -EINVAL; + } + break; + default: + return -EINVAL; + } + dev_dbg(dev, "sdw_link_id:%d, be_id:%d, cpu_pin_id:%d\n", sdw_link_id, be_id, *cpu_pin_id); + return 0; +} +EXPORT_SYMBOL_NS_GPL(get_acp70_cpu_pin_id, "SND_SOC_AMD_SDW_MACH"); + MODULE_DESCRIPTION("AMD SoundWire Common Machine driver"); MODULE_AUTHOR("Vijendar Mukunda "); MODULE_LICENSE("GPL"); diff --git a/sound/soc/amd/acp/soc_amd_sdw_common.h b/sound/soc/amd/acp/soc_amd_sdw_common.h index b7bae107c13e..9bedccfe25a9 100644 --- a/sound/soc/amd/acp/soc_amd_sdw_common.h +++ b/sound/soc/amd/acp/soc_amd_sdw_common.h @@ -19,6 +19,8 @@ #define AMD_SDW_MAX_GROUPS 9 #define ACP63_PCI_REV 0x63 +#define ACP70_PCI_REV 0x70 +#define ACP71_PCI_REV 0x71 #define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) #define ASOC_SDW_FOUR_SPK BIT(4) #define ASOC_SDW_ACP_DMIC BIT(5) @@ -38,11 +40,20 @@ #define ACP_DMIC_BE_ID 4 +#define ACP70_SW_AUDIO0_TX 0 +#define ACP70_SW_AUDIO1_TX 1 +#define ACP70_SW_AUDIO2_TX 2 + +#define ACP70_SW_AUDIO0_RX 3 +#define ACP70_SW_AUDIO1_RX 4 +#define ACP70_SW_AUDIO2_RX 5 + struct amd_mc_ctx { unsigned int acp_rev; unsigned int max_sdw_links; }; int get_acp63_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct device *dev); +int get_acp70_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct device *dev); #endif From 187150671d83324f1ca56f7ab5e00f16a3b9f2a9 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:16 +0530 Subject: [PATCH 080/651] ASoC: amd: acp: add RT711, RT714 & RT1316 support for ACP7.0 platform Add support for corresponding codecs on ACP7.0 platform hardware configuration. SDW0: RT711 Jack SDW0: RT1316 Left Speaker SDW0: RT1316 Right Speaker SDW1: RT714 DMIC Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-23-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/Makefile | 2 +- sound/soc/amd/acp/amd-acp70-acpi-match.c | 88 ++++++++++++++++++++++++ sound/soc/amd/mach-config.h | 1 + sound/soc/amd/ps/pci-ps.c | 6 +- 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 sound/soc/amd/acp/amd-acp70-acpi-match.c diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile index bb2702036338..7c75892e678b 100644 --- a/sound/soc/amd/acp/Makefile +++ b/sound/soc/amd/acp/Makefile @@ -22,7 +22,7 @@ snd-acp70-y := acp70.o snd-acp-mach-y := acp-mach-common.o snd-acp-legacy-mach-y := acp-legacy-mach.o acp3x-es83xx/acp3x-es83xx.o snd-acp-sof-mach-y := acp-sof-mach.o -snd-soc-acpi-amd-match-y := amd-acp63-acpi-match.o +snd-soc-acpi-amd-match-y := amd-acp63-acpi-match.o amd-acp70-acpi-match.o snd-acp-sdw-mach-y := acp-sdw-mach-common.o snd-acp-sdw-sof-mach-y += acp-sdw-sof-mach.o snd-acp-sdw-legacy-mach-y += acp-sdw-legacy-mach.o diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c new file mode 100644 index 000000000000..fa59b462f227 --- /dev/null +++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * amd-acp70-acpi-match.c - tables and support for ACP 7.0 & ACP7.1 + * ACPI enumeration. + * + * Copyright 2025 Advanced Micro Devices, Inc. + */ + +#include +#include "../mach-config.h" + +static const struct snd_soc_acpi_endpoint single_endpoint = { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0 +}; + +static const struct snd_soc_acpi_endpoint spk_l_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 0, + .group_id = 1 +}; + +static const struct snd_soc_acpi_endpoint spk_r_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1 +}; + +static const struct snd_soc_acpi_adr_device rt711_rt1316_group_adr[] = { + { + .adr = 0x000030025D071101ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + }, + { + .adr = 0x000030025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1316-1" + }, + { + .adr = 0x000032025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + }, +}; + +static const struct snd_soc_acpi_adr_device rt714_adr[] = { + { + .adr = 0x130025d071401ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt714" + } +}; + +static const struct snd_soc_acpi_link_adr acp70_4_in_1_sdca[] = { + { .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_rt1316_group_adr), + .adr_d = rt711_rt1316_group_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt714_adr), + .adr_d = rt714_adr, + }, + {} +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = { + { + .link_mask = BIT(0) | BIT(1), + .links = acp70_4_in_1_sdca, + .drv_name = "amd_sdw", + }, + {}, +}; +EXPORT_SYMBOL(snd_soc_acpi_amd_acp70_sdw_machines); + +MODULE_DESCRIPTION("AMD ACP7.0 & ACP7.1 tables and support for ACPI enumeration"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); diff --git a/sound/soc/amd/mach-config.h b/sound/soc/amd/mach-config.h index a86c76f781f9..fdf016a64bbf 100644 --- a/sound/soc/amd/mach-config.h +++ b/sound/soc/amd/mach-config.h @@ -26,6 +26,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[]; struct config_entry { u32 flags; diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 2cbfeb07d5c4..220dca8cba85 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -632,7 +632,11 @@ static int snd_acp63_probe(struct pci_dev *pci, dev_err(&pci->dev, "ACP platform devices creation failed\n"); goto de_init; } - adata->machines = snd_soc_acpi_amd_acp63_sdw_machines; + if (adata->acp_rev >= ACP70_PCI_REV) + adata->machines = snd_soc_acpi_amd_acp70_sdw_machines; + else + adata->machines = snd_soc_acpi_amd_acp63_sdw_machines; + ret = acp63_machine_register(&pci->dev); if (ret) { dev_err(&pci->dev, "ACP machine register failed\n"); From d0252b0b945ec67fd09fc764dcadf445fb7757ee Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:17 +0530 Subject: [PATCH 081/651] ASoC: amd: acp: amd-acp70-acpi-match: Add rt722 support Patch adds driver data and match table for rt722 multi-function codec on acp7.0 and acp7.1 platforms at sdw link0 for legacy(NO DSP) stack. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-24-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/amd-acp70-acpi-match.c | 44 ++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c index fa59b462f227..fe166015dc29 100644 --- a/sound/soc/amd/acp/amd-acp70-acpi-match.c +++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c @@ -73,7 +73,51 @@ static const struct snd_soc_acpi_link_adr acp70_4_in_1_sdca[] = { {} }; +static const struct snd_soc_acpi_endpoint rt722_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { + { + .adr = 0x000030025d072201ull, + .num_endpoints = ARRAY_SIZE(rt722_endpoints), + .endpoints = rt722_endpoints, + .name_prefix = "rt722" + } +}; + +static const struct snd_soc_acpi_link_adr acp70_rt722_only[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt722_0_single_adr), + .adr_d = rt722_0_single_adr, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = { + { + .link_mask = BIT(0), + .links = acp70_rt722_only, + .drv_name = "amd_sdw", + }, { .link_mask = BIT(0) | BIT(1), .links = acp70_4_in_1_sdca, From 31e3100d5e1fe69f944f84867be0cbfa5fd380c8 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:18 +0530 Subject: [PATCH 082/651] ASoC: amd: acp: amd-acp70-acpi-match: Add RT1320 & RT722 combination soundwire machine This patch adds below machine configuration for the ACP7.0 & ACP7.1 platforms. Link 0: RT722 codec with three endpoints: Headset, Speaker, and DMIC. Link 1: RT1320 amplifier. Note: The Speaker endpoint on the RT722 codec is not used. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-25-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/Kconfig | 1 + sound/soc/amd/acp/amd-acp70-acpi-match.c | 28 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 03f3fcbba5af..53793ec7c7b4 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -156,6 +156,7 @@ config SND_SOC_AMD_LEGACY_SDW_MACH select SND_SOC_RT712_SDCA_SDW select SND_SOC_RT712_SDCA_DMIC_SDW select SND_SOC_RT1316_SDW + select SND_SOC_RT1320_SDW select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT722_SDCA_SDW diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c index fe166015dc29..e87ccfeee5bd 100644 --- a/sound/soc/amd/acp/amd-acp70-acpi-match.c +++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c @@ -103,6 +103,15 @@ static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1320_1_single_adr[] = { + { + .adr = 0x000130025D132001ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1320-1" + } +}; + static const struct snd_soc_acpi_link_adr acp70_rt722_only[] = { { .mask = BIT(0), @@ -112,7 +121,26 @@ static const struct snd_soc_acpi_link_adr acp70_rt722_only[] = { {} }; +static const struct snd_soc_acpi_link_adr acp70_rt722_l0_rt1320_l1[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt722_0_single_adr), + .adr_d = rt722_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_single_adr), + .adr_d = rt1320_1_single_adr, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = { + { + .link_mask = BIT(0) | BIT(1), + .links = acp70_rt722_l0_rt1320_l1, + .drv_name = "amd_sdw", + }, { .link_mask = BIT(0), .links = acp70_rt722_only, From 4bb5b6f13fd83b32c8a93fbd399e7558415d1ce0 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 7 Feb 2025 11:58:19 +0530 Subject: [PATCH 083/651] ASoC: amd: amd_sdw: Add quirks for Dell SKU's This patch adds a quirk to include the codec amplifier function for Dell SKU's listed in quirk table. Note: In these SKU's, the RT722 codec amplifier is excluded, and an external amplifier is used instead. Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250207062819.1527184-26-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-sdw-legacy-mach.c | 34 +++++++++++++++++++++++++ sound/soc/amd/acp/soc_amd_sdw_common.h | 1 + 2 files changed, 35 insertions(+) diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c index 00aeea70f04e..2020c5cfb3d5 100644 --- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c +++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c @@ -28,6 +28,8 @@ static void log_quirks(struct device *dev) SOC_JACK_JDSRC(soc_sdw_quirk)); if (soc_sdw_quirk & ASOC_SDW_ACP_DMIC) dev_dbg(dev, "quirk SOC_SDW_ACP_DMIC enabled\n"); + if (soc_sdw_quirk & ASOC_SDW_CODEC_SPKR) + dev_dbg(dev, "quirk ASOC_SDW_CODEC_SPKR enabled\n"); } static int soc_sdw_quirk_cb(const struct dmi_system_id *id) @@ -45,6 +47,38 @@ static const struct dmi_system_id soc_sdw_quirk_table[] = { }, .driver_data = (void *)RT711_JD2, }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D80"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D81"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D82"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0D83"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, {} }; diff --git a/sound/soc/amd/acp/soc_amd_sdw_common.h b/sound/soc/amd/acp/soc_amd_sdw_common.h index 9bedccfe25a9..1f24e0e06487 100644 --- a/sound/soc/amd/acp/soc_amd_sdw_common.h +++ b/sound/soc/amd/acp/soc_amd_sdw_common.h @@ -24,6 +24,7 @@ #define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) #define ASOC_SDW_FOUR_SPK BIT(4) #define ASOC_SDW_ACP_DMIC BIT(5) +#define ASOC_SDW_CODEC_SPKR BIT(15) #define AMD_SDW0 0 #define AMD_SDW1 1 From 91f505dc3a94c04421a2a51e8c40acf7ea67ecbc Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Feb 2025 20:36:36 +0800 Subject: [PATCH 084/651] ASoC: Intel: soc-acpi-intel-ptl-match: add rt712_vb + rt1320 support s/lnl/ptl Fixes: bd40d912728f ("ASoC: Intel: soc-acpi-intel-ptl-match: add rt712_vb + rt1320 support") Signed-off-by: Peter Ujfalusi Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Signed-off-by: Bard Liao Link: https://patch.msgid.link/20250207123637.215320-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-ptl-match.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index 9eb4a43e3e7a..e487c4e1c034 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -270,7 +270,7 @@ static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_vb_l2_rt1320_l13[] = { {} }; -static const struct snd_soc_acpi_link_adr lnl_sdw_rt712_vb_l2_rt1320_l1[] = { +static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l2_rt1320_l1[] = { { .mask = BIT(2), .num_adr = ARRAY_SIZE(rt712_vb_2_group1_adr), @@ -337,10 +337,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { }, { .link_mask = BIT(1) | BIT(2), - .links = lnl_sdw_rt712_vb_l2_rt1320_l1, + .links = ptl_sdw_rt712_vb_l2_rt1320_l1, .drv_name = "sof_sdw", .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, - .sof_tplg_filename = "sof-lnl-rt712-l2-rt1320-l1.tplg" + .sof_tplg_filename = "sof-ptl-rt712-l2-rt1320-l1.tplg" }, { .link_mask = BIT(1) | BIT(2) | BIT(3), From 852c0b7204ded184924c41ab99b2ac7a70ad4dab Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Feb 2025 20:36:37 +0800 Subject: [PATCH 085/651] ASoC: Intel: soc-acpi-intel-ptl-match: add rt713_vb_l2_rt1320_l13 s/lnl/ptl Fixes: a7ebb0255188 ("ASoC: Intel: soc-acpi-intel-ptl-match: add rt713_vb_l2_rt1320_l13 support") Signed-off-by: Peter Ujfalusi Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Signed-off-by: Bard Liao Link: https://patch.msgid.link/20250207123637.215320-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-ptl-match.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index e487c4e1c034..dd7993b76dee 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -251,7 +251,7 @@ static const struct snd_soc_acpi_link_adr ptl_rvp[] = { {} }; -static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_vb_l2_rt1320_l13[] = { +static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l2_rt1320_l13[] = { { .mask = BIT(2), .num_adr = ARRAY_SIZE(rt713_vb_2_adr), @@ -344,10 +344,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { }, { .link_mask = BIT(1) | BIT(2) | BIT(3), - .links = lnl_sdw_rt713_vb_l2_rt1320_l13, + .links = ptl_sdw_rt713_vb_l2_rt1320_l13, .drv_name = "sof_sdw", .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, - .sof_tplg_filename = "sof-lnl-rt713-l2-rt1320-l13.tplg" + .sof_tplg_filename = "sof-ptl-rt713-l2-rt1320-l13.tplg" }, {}, }; From 651e0ed391b148f83afba0bfbd8a56e38e58c34d Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:22:40 -0500 Subject: [PATCH 086/651] ASoC: SOF: imx: introduce more common structures and functions The SOF drivers for imx chips have a lot of duplicate code and routines/code snippets that could certainly be reused among drivers. As such, introduce a new set of structures and functions that will help eliminate the redundancy and code size of the drivers. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Frank Li Link: https://patch.msgid.link/20250207162246.3104-2-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx-common.c | 431 ++++++++++++++++++++++++++++++++- sound/soc/sof/imx/imx-common.h | 151 ++++++++++++ 2 files changed, 581 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/imx/imx-common.c b/sound/soc/sof/imx/imx-common.c index fce6d9cf6a6b..82057af1436c 100644 --- a/sound/soc/sof/imx/imx-common.c +++ b/sound/soc/sof/imx/imx-common.c @@ -1,11 +1,16 @@ // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) // -// Copyright 2020 NXP +// Copyright 2020-2025 NXP // // Common helpers for the audio DSP on i.MX8 +#include #include +#include +#include +#include #include + #include "../ops.h" #include "imx-common.h" @@ -74,5 +79,429 @@ void imx8_dump(struct snd_sof_dev *sdev, u32 flags) } EXPORT_SYMBOL(imx8_dump); +static void imx_handle_reply(struct imx_dsp_ipc *ipc) +{ + struct snd_sof_dev *sdev; + unsigned long flags; + + sdev = imx_dsp_get_data(ipc); + + spin_lock_irqsave(&sdev->ipc_lock, flags); + snd_sof_ipc_process_reply(sdev, 0); + spin_unlock_irqrestore(&sdev->ipc_lock, flags); +} + +static void imx_handle_request(struct imx_dsp_ipc *ipc) +{ + struct snd_sof_dev *sdev; + u32 panic_code; + + sdev = imx_dsp_get_data(ipc); + + if (get_chip_info(sdev)->ipc_info.has_panic_code) { + sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, + &panic_code, + sizeof(panic_code)); + + if ((panic_code & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { + snd_sof_dsp_panic(sdev, panic_code, true); + return; + } + } + + snd_sof_ipc_msgs_rx(sdev); +} + +static struct imx_dsp_ops imx_ipc_ops = { + .handle_reply = imx_handle_reply, + .handle_request = imx_handle_request, +}; + +static int imx_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) +{ + struct imx_common_data *common = sdev->pdata->hw_pdata; + + sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, msg->msg_size); + imx_dsp_ring_doorbell(common->ipc_handle, 0x0); + + return 0; +} + +static int imx_get_bar_index(struct snd_sof_dev *sdev, u32 type) +{ + switch (type) { + case SOF_FW_BLK_TYPE_IRAM: + case SOF_FW_BLK_TYPE_SRAM: + return type; + default: + return -EINVAL; + } +} + +static int imx_get_mailbox_offset(struct snd_sof_dev *sdev) +{ + return get_chip_info(sdev)->ipc_info.boot_mbox_offset; +} + +static int imx_get_window_offset(struct snd_sof_dev *sdev, u32 id) +{ + return get_chip_info(sdev)->ipc_info.window_offset; +} + +static int imx_set_power_state(struct snd_sof_dev *sdev, + const struct sof_dsp_power_state *target) +{ + sdev->dsp_power_state = *target; + + return 0; +} + +static int imx_common_resume(struct snd_sof_dev *sdev) +{ + struct imx_common_data *common; + int ret, i; + + common = sdev->pdata->hw_pdata; + + ret = clk_bulk_prepare_enable(common->clk_num, common->clks); + if (ret) + dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); + + for (i = 0; i < DSP_MU_CHAN_NUM; i++) + imx_dsp_request_channel(common->ipc_handle, i); + + /* done. If need be, core will be started by SOF core immediately after */ + return 0; +} + +static int imx_common_suspend(struct snd_sof_dev *sdev) +{ + struct imx_common_data *common; + int i, ret; + + common = sdev->pdata->hw_pdata; + + ret = imx_chip_core_shutdown(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to shutdown core: %d\n", ret); + return ret; + } + + for (i = 0; i < DSP_MU_CHAN_NUM; i++) + imx_dsp_free_channel(common->ipc_handle, i); + + clk_bulk_disable_unprepare(common->clk_num, common->clks); + + return 0; +} + +static int imx_runtime_resume(struct snd_sof_dev *sdev) +{ + const struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D0, + }; + int ret; + + ret = imx_common_resume(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to runtime common resume: %d\n", ret); + return ret; + } + + return snd_sof_dsp_set_power_state(sdev, &target_state); +} + +static int imx_resume(struct snd_sof_dev *sdev) +{ + const struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D0, + }; + int ret; + + ret = imx_common_resume(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to common resume: %d\n", ret); + return ret; + } + + if (pm_runtime_suspended(sdev->dev)) { + pm_runtime_disable(sdev->dev); + pm_runtime_set_active(sdev->dev); + pm_runtime_mark_last_busy(sdev->dev); + pm_runtime_enable(sdev->dev); + pm_runtime_idle(sdev->dev); + } + + return snd_sof_dsp_set_power_state(sdev, &target_state); +} + +static int imx_runtime_suspend(struct snd_sof_dev *sdev) +{ + const struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D3, + }; + int ret; + + ret = imx_common_suspend(sdev); + if (ret < 0) + dev_err(sdev->dev, "failed to runtime common suspend: %d\n", ret); + + return snd_sof_dsp_set_power_state(sdev, &target_state); +} + +static int imx_suspend(struct snd_sof_dev *sdev, unsigned int target_state) +{ + const struct sof_dsp_power_state target_power_state = { + .state = target_state, + }; + int ret; + + if (!pm_runtime_suspended(sdev->dev)) { + ret = imx_common_suspend(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to common suspend: %d\n", ret); + return ret; + } + } + + return snd_sof_dsp_set_power_state(sdev, &target_power_state); +} + +static int imx_region_name_to_blk_type(const char *region_name) +{ + if (!strcmp(region_name, "iram")) + return SOF_FW_BLK_TYPE_IRAM; + else if (!strcmp(region_name, "dram")) + return SOF_FW_BLK_TYPE_DRAM; + else if (!strcmp(region_name, "sram")) + return SOF_FW_BLK_TYPE_SRAM; + else + return -EINVAL; +} + +static int imx_parse_ioremap_memory(struct snd_sof_dev *sdev) +{ + const struct imx_chip_info *chip_info; + struct reserved_mem *reserved; + struct platform_device *pdev; + struct device_node *res_np; + phys_addr_t base, size; + struct resource *res; + int i, blk_type, ret; + + pdev = to_platform_device(sdev->dev); + chip_info = get_chip_info(sdev); + + for (i = 0; chip_info->memory[i].name; i++) { + blk_type = imx_region_name_to_blk_type(chip_info->memory[i].name); + if (blk_type < 0) + return dev_err_probe(sdev->dev, blk_type, + "no blk type for region %s\n", + chip_info->memory[i].name); + + if (!chip_info->memory[i].reserved) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + chip_info->memory[i].name); + if (!res) + return dev_err_probe(sdev->dev, -ENODEV, + "failed to fetch %s resource\n", + chip_info->memory[i].name); + + base = res->start; + size = resource_size(res); + } else { + ret = of_property_match_string(pdev->dev.of_node, + "memory-region-names", + chip_info->memory[i].name); + if (ret < 0) + return dev_err_probe(sdev->dev, ret, + "no valid index for %s\n", + chip_info->memory[i].name); + + res_np = of_parse_phandle(pdev->dev.of_node, + "memory-region", + ret); + if (!res_np) + return dev_err_probe(sdev->dev, -ENODEV, + "failed to parse phandle %s\n", + chip_info->memory[i].name); + + reserved = of_reserved_mem_lookup(res_np); + of_node_put(res_np); + if (!reserved) + return dev_err_probe(sdev->dev, -ENODEV, + "failed to get %s reserved\n", + chip_info->memory[i].name); + + base = reserved->base; + size = reserved->size; + } + + sdev->bar[blk_type] = devm_ioremap(sdev->dev, base, size); + if (IS_ERR(sdev->bar[blk_type])) + return dev_err_probe(sdev->dev, + PTR_ERR(sdev->bar[blk_type]), + "failed to ioremap %s region\n", + chip_info->memory[i].name); + } + + return 0; +} + +static void imx_unregister_action(void *data) +{ + struct imx_common_data *common; + struct snd_sof_dev *sdev; + + sdev = data; + common = sdev->pdata->hw_pdata; + + if (get_chip_info(sdev)->has_dma_reserved) + of_reserved_mem_device_release(sdev->dev); + + platform_device_unregister(common->ipc_dev); +} + +static int imx_probe(struct snd_sof_dev *sdev) +{ + struct dev_pm_domain_attach_data domain_data = { + .pd_names = NULL, /* no filtering */ + .pd_flags = PD_FLAG_DEV_LINK_ON, + }; + struct imx_common_data *common; + struct platform_device *pdev; + int ret; + + pdev = to_platform_device(sdev->dev); + + common = devm_kzalloc(sdev->dev, sizeof(*common), GFP_KERNEL); + if (!common) + return dev_err_probe(sdev->dev, -ENOMEM, + "failed to allocate common data\n"); + + common->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp", + PLATFORM_DEVID_NONE, + pdev, sizeof(*pdev)); + if (IS_ERR(common->ipc_dev)) + return dev_err_probe(sdev->dev, PTR_ERR(common->ipc_dev), + "failed to create IPC device\n"); + + if (get_chip_info(sdev)->has_dma_reserved) { + ret = of_reserved_mem_device_init_by_name(sdev->dev, + pdev->dev.of_node, + "dma"); + if (ret) { + platform_device_unregister(common->ipc_dev); + + return dev_err_probe(sdev->dev, ret, + "failed to bind DMA region\n"); + } + } + + /* let the devres API take care of the cleanup */ + ret = devm_add_action_or_reset(sdev->dev, + imx_unregister_action, + sdev); + if (ret) + return dev_err_probe(sdev->dev, ret, "failed to add devm action\n"); + + common->ipc_handle = dev_get_drvdata(&common->ipc_dev->dev); + if (!common->ipc_handle) + return dev_err_probe(sdev->dev, -EPROBE_DEFER, + "failed to fetch IPC handle\n"); + + ret = imx_parse_ioremap_memory(sdev); + if (ret < 0) + return dev_err_probe(sdev->dev, ret, + "failed to parse/ioremap memory regions\n"); + + if (!sdev->dev->pm_domain) { + ret = devm_pm_domain_attach_list(sdev->dev, + &domain_data, &common->pd_list); + if (ret < 0) + return dev_err_probe(sdev->dev, ret, "failed to attach PDs\n"); + } + + ret = devm_clk_bulk_get_all(sdev->dev, &common->clks); + if (ret < 0) + return dev_err_probe(sdev->dev, common->clk_num, + "failed to fetch clocks\n"); + common->clk_num = ret; + + ret = clk_bulk_prepare_enable(common->clk_num, common->clks); + if (ret < 0) + return dev_err_probe(sdev->dev, ret, "failed to enable clocks\n"); + + common->ipc_handle->ops = &imx_ipc_ops; + 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; + + return imx_chip_probe(sdev); +} + +static void imx_remove(struct snd_sof_dev *sdev) +{ + struct imx_common_data *common; + int ret; + + common = sdev->pdata->hw_pdata; + + if (!pm_runtime_suspended(sdev->dev)) { + ret = imx_chip_core_shutdown(sdev); + if (ret < 0) + dev_err(sdev->dev, "failed to shutdown core: %d\n", ret); + + clk_bulk_disable_unprepare(common->clk_num, common->clks); + } +} + +const struct snd_sof_dsp_ops sof_imx_ops = { + .probe = imx_probe, + .remove = imx_remove, + + .run = imx_chip_core_kick, + .reset = imx_chip_core_reset, + + .block_read = sof_block_read, + .block_write = sof_block_write, + + .mailbox_read = sof_mailbox_read, + .mailbox_write = sof_mailbox_write, + + .send_msg = imx_send_msg, + .get_mailbox_offset = imx_get_mailbox_offset, + .get_window_offset = imx_get_window_offset, + + .ipc_msg_data = sof_ipc_msg_data, + .set_stream_data_offset = sof_set_stream_data_offset, + + .get_bar_index = imx_get_bar_index, + .load_firmware = snd_sof_load_firmware_memcpy, + + .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, + + .pcm_open = sof_stream_pcm_open, + .pcm_close = sof_stream_pcm_close, + + .runtime_suspend = imx_runtime_suspend, + .runtime_resume = imx_runtime_resume, + .suspend = imx_suspend, + .resume = imx_resume, + + .set_power_state = imx_set_power_state, + + .hw_info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_BATCH | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, +}; +EXPORT_SYMBOL(sof_imx_ops); + MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF helpers for IMX platforms"); diff --git a/sound/soc/sof/imx/imx-common.h b/sound/soc/sof/imx/imx-common.h index 13d7f3ef675e..9bd711dbb5d0 100644 --- a/sound/soc/sof/imx/imx-common.h +++ b/sound/soc/sof/imx/imx-common.h @@ -4,10 +4,159 @@ #define __IMX_COMMON_H__ #include +#include +#include + +#include "../sof-of-dev.h" +#include "../ops.h" #define EXCEPT_MAX_HDR_SIZE 0x400 #define IMX8_STACK_DUMP_SIZE 32 +/* chip_info refers to the data stored in struct sof_dev_desc's chip_info */ +#define get_chip_info(sdev)\ + ((const struct imx_chip_info *)((sdev)->pdata->desc->chip_info)) + +/* chip_pdata refers to the data stored in struct imx_common_data's chip_pdata */ +#define get_chip_pdata(sdev)\ + (((struct imx_common_data *)((sdev)->pdata->hw_pdata))->chip_pdata) + +/* can be used if: + * 1) The only supported IPC version is IPC3. + * 2) The default paths/FW name match values below. + * + * otherwise, just explicitly declare the structure + */ +#define IMX_SOF_DEV_DESC(mach_name, of_machs, \ + mach_chip_info, mach_ops, mach_ops_init) \ +static struct sof_dev_desc sof_of_##mach_name##_desc = { \ + .of_machines = of_machs, \ + .chip_info = mach_chip_info, \ + .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), \ + .ipc_default = SOF_IPC_TYPE_3, \ + .default_fw_path = { \ + [SOF_IPC_TYPE_3] = "imx/sof", \ + }, \ + .default_tplg_path = { \ + [SOF_IPC_TYPE_3] = "imx/sof-tplg", \ + }, \ + .default_fw_filename = { \ + [SOF_IPC_TYPE_3] = "sof-" #mach_name ".ri", \ + }, \ + .ops = mach_ops, \ + .ops_init = mach_ops_init, \ +} + +/* to be used alongside IMX_SOF_DEV_DESC() */ +#define IMX_SOF_DEV_DESC_NAME(mach_name) sof_of_##mach_name##_desc + +/* dai driver entry w/ playback and capture caps. If one direction is missing + * then set the channels to 0. + */ +#define IMX_SOF_DAI_DRV_ENTRY(dai_name, pb_cmin, pb_cmax, cap_cmin, cap_cmax) \ +{ \ + .name = dai_name, \ + .playback = { \ + .channels_min = pb_cmin, \ + .channels_max = pb_cmax, \ + }, \ + .capture = { \ + .channels_min = cap_cmin, \ + .channels_max = cap_cmax, \ + }, \ +} + +/* use if playback and capture have the same min/max channel count */ +#define IMX_SOF_DAI_DRV_ENTRY_BIDIR(dai_name, cmin, cmax)\ + IMX_SOF_DAI_DRV_ENTRY(dai_name, cmin, cmax, cmin, cmax) + +struct imx_ipc_info { + /* true if core is able to write a panic code to the debug box */ + bool has_panic_code; + /* offset to mailbox in which firmware initially writes FW_READY */ + int boot_mbox_offset; + /* offset to region at which the mailboxes start */ + int window_offset; +}; + +struct imx_chip_ops { + /* called after clocks and PDs are enabled */ + int (*probe)(struct snd_sof_dev *sdev); + /* used directly by the SOF core */ + int (*core_kick)(struct snd_sof_dev *sdev); + /* called during suspend()/remove() before clocks are disabled */ + int (*core_shutdown)(struct snd_sof_dev *sdev); + /* used directly by the SOF core */ + int (*core_reset)(struct snd_sof_dev *sdev); +}; + +struct imx_memory_info { + const char *name; + bool reserved; +}; + +struct imx_chip_info { + struct imx_ipc_info ipc_info; + /* does the chip have a reserved memory region for DMA? */ + bool has_dma_reserved; + struct imx_memory_info *memory; + struct snd_soc_dai_driver *drv; + int num_drv; + /* optional */ + const struct imx_chip_ops *ops; +}; + +struct imx_common_data { + struct platform_device *ipc_dev; + struct imx_dsp_ipc *ipc_handle; + /* core may have no clocks */ + struct clk_bulk_data *clks; + int clk_num; + /* core may have no PDs */ + struct dev_pm_domain_list *pd_list; + void *chip_pdata; +}; + +static inline int imx_chip_core_kick(struct snd_sof_dev *sdev) +{ + const struct imx_chip_ops *ops = get_chip_info(sdev)->ops; + + if (ops && ops->core_kick) + return ops->core_kick(sdev); + + return 0; +} + +static inline int imx_chip_core_shutdown(struct snd_sof_dev *sdev) +{ + const struct imx_chip_ops *ops = get_chip_info(sdev)->ops; + + if (ops && ops->core_shutdown) + return ops->core_shutdown(sdev); + + return 0; +} + +static inline int imx_chip_core_reset(struct snd_sof_dev *sdev) +{ + const struct imx_chip_ops *ops = get_chip_info(sdev)->ops; + + if (ops && ops->core_reset) + return ops->core_reset(sdev); + + return 0; +} + +static inline int imx_chip_probe(struct snd_sof_dev *sdev) +{ + const struct imx_chip_ops *ops = get_chip_info(sdev)->ops; + + if (ops && ops->probe) + return ops->probe(sdev); + + return 0; +} + void imx8_get_registers(struct snd_sof_dev *sdev, struct sof_ipc_dsp_oops_xtensa *xoops, struct sof_ipc_panic_info *panic_info, @@ -15,4 +164,6 @@ void imx8_get_registers(struct snd_sof_dev *sdev, void imx8_dump(struct snd_sof_dev *sdev, u32 flags); +extern const struct snd_sof_dsp_ops sof_imx_ops; + #endif From 645753d01356ff1a756812f1c69c53eb5c9081cd Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:22:41 -0500 Subject: [PATCH 087/651] ASoC: SOF: imx8: use common imx chip interface The common interface for imx chips (defined in imx-common.c) contains the definitions for a lot of functions required by the SOF core. As such, the platform driver can just use the common definitions instead of duplicating code by re-defining aforementioned functions. Make the transition to the new common interface. This consists of: 1) Removing unneeded functions, which are already defined in the common interface. 2) Defining some chip-specific operations/structures required by the interface to work. 3) Dropping structure definitions that are no longer needed. 4) Adapting some existing functions to the new interface. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Frank Li Link: https://patch.msgid.link/20250207162246.3104-3-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx8.c | 528 +++++---------------------------------- 1 file changed, 68 insertions(+), 460 deletions(-) diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 1e7bf00d7c46..25e3296a1e5e 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) // -// Copyright 2019 NXP +// Copyright 2019-2025 NXP // // Author: Daniel Baluta // @@ -41,100 +41,28 @@ #define MBOX_OFFSET 0x800000 #define MBOX_SIZE 0x1000 -struct imx8_priv { - struct device *dev; - struct snd_sof_dev *sdev; - - /* DSP IPC handler */ - struct imx_dsp_ipc *dsp_ipc; - struct platform_device *ipc_dev; - - /* System Controller IPC handler */ - struct imx_sc_ipc *sc_ipc; - - /* Power domain handling */ - int num_domains; - struct device **pd_dev; - struct device_link **link; - - struct clk_bulk_data *clks; - int clk_num; -}; - -static int imx8_get_mailbox_offset(struct snd_sof_dev *sdev) -{ - return MBOX_OFFSET; -} - -static int imx8_get_window_offset(struct snd_sof_dev *sdev, u32 id) -{ - return MBOX_OFFSET; -} - -static void imx8_dsp_handle_reply(struct imx_dsp_ipc *ipc) -{ - struct imx8_priv *priv = imx_dsp_get_data(ipc); - unsigned long flags; - - spin_lock_irqsave(&priv->sdev->ipc_lock, flags); - snd_sof_ipc_process_reply(priv->sdev, 0); - spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); -} - -static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc) -{ - struct imx8_priv *priv = imx_dsp_get_data(ipc); - u32 p; /* panic code */ - - /* Read the message from the debug box. */ - sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p)); - - /* Check to see if the message is a panic code (0x0dead***) */ - if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) - snd_sof_dsp_panic(priv->sdev, p, true); - else - snd_sof_ipc_msgs_rx(priv->sdev); -} - -static struct imx_dsp_ops dsp_ops = { - .handle_reply = imx8_dsp_handle_reply, - .handle_request = imx8_dsp_handle_request, -}; - -static int imx8_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) -{ - struct imx8_priv *priv = sdev->pdata->hw_pdata; - - sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, - msg->msg_size); - imx_dsp_ring_doorbell(priv->dsp_ipc, 0); - - return 0; -} - /* * DSP control. */ static int imx8x_run(struct snd_sof_dev *sdev) { - struct imx8_priv *dsp_priv = sdev->pdata->hw_pdata; int ret; - ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, + ret = imx_sc_misc_set_control(get_chip_pdata(sdev), IMX_SC_R_DSP, IMX_SC_C_OFS_SEL, 1); if (ret < 0) { dev_err(sdev->dev, "Error system address offset source select\n"); return ret; } - ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, + ret = imx_sc_misc_set_control(get_chip_pdata(sdev), IMX_SC_R_DSP, IMX_SC_C_OFS_AUDIO, 0x80); if (ret < 0) { dev_err(sdev->dev, "Error system address offset of AUDIO\n"); return ret; } - ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, + ret = imx_sc_misc_set_control(get_chip_pdata(sdev), IMX_SC_R_DSP, IMX_SC_C_OFS_PERIPH, 0x5A); if (ret < 0) { dev_err(sdev->dev, "Error system address offset of PERIPH %d\n", @@ -142,14 +70,14 @@ static int imx8x_run(struct snd_sof_dev *sdev) return ret; } - ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, + ret = imx_sc_misc_set_control(get_chip_pdata(sdev), IMX_SC_R_DSP, IMX_SC_C_OFS_IRQ, 0x51); if (ret < 0) { dev_err(sdev->dev, "Error system address offset of IRQ\n"); return ret; } - imx_sc_pm_cpu_start(dsp_priv->sc_ipc, IMX_SC_R_DSP, true, + imx_sc_pm_cpu_start(get_chip_pdata(sdev), IMX_SC_R_DSP, true, RESET_VECTOR_VADDR); return 0; @@ -157,17 +85,16 @@ static int imx8x_run(struct snd_sof_dev *sdev) static int imx8_run(struct snd_sof_dev *sdev) { - struct imx8_priv *dsp_priv = sdev->pdata->hw_pdata; int ret; - ret = imx_sc_misc_set_control(dsp_priv->sc_ipc, IMX_SC_R_DSP, + ret = imx_sc_misc_set_control(get_chip_pdata(sdev), IMX_SC_R_DSP, IMX_SC_C_OFS_SEL, 0); if (ret < 0) { dev_err(sdev->dev, "Error system address offset source select\n"); return ret; } - imx_sc_pm_cpu_start(dsp_priv->sc_ipc, IMX_SC_R_DSP, true, + imx_sc_pm_cpu_start(get_chip_pdata(sdev), IMX_SC_R_DSP, true, RESET_VECTOR_VADDR); return 0; @@ -175,272 +102,20 @@ static int imx8_run(struct snd_sof_dev *sdev) static int imx8_probe(struct snd_sof_dev *sdev) { - struct platform_device *pdev = to_platform_device(sdev->dev); - struct device_node *np = pdev->dev.of_node; - struct device_node *res_node; - struct resource *mmio; - struct imx8_priv *priv; - struct resource res; - u32 base, size; - int ret = 0; - int i; + struct imx_sc_ipc *sc_ipc_handle; + struct imx_common_data *common; + int ret; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + common = sdev->pdata->hw_pdata; - sdev->num_cores = 1; - sdev->pdata->hw_pdata = priv; - priv->dev = sdev->dev; - priv->sdev = sdev; + ret = imx_scu_get_handle(&sc_ipc_handle); + if (ret < 0) + return dev_err_probe(sdev->dev, ret, + "failed to fetch SC IPC handle\n"); - /* power up device associated power domains */ - priv->num_domains = of_count_phandle_with_args(np, "power-domains", - "#power-domain-cells"); - if (priv->num_domains < 0) { - dev_err(sdev->dev, "no power-domains property in %pOF\n", np); - return priv->num_domains; - } - - priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains, - sizeof(*priv->pd_dev), GFP_KERNEL); - if (!priv->pd_dev) - return -ENOMEM; - - priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains, - sizeof(*priv->link), GFP_KERNEL); - if (!priv->link) - return -ENOMEM; - - for (i = 0; i < priv->num_domains; i++) { - priv->pd_dev[i] = dev_pm_domain_attach_by_id(&pdev->dev, i); - if (IS_ERR(priv->pd_dev[i])) { - ret = PTR_ERR(priv->pd_dev[i]); - goto exit_unroll_pm; - } - priv->link[i] = device_link_add(&pdev->dev, priv->pd_dev[i], - DL_FLAG_STATELESS | - DL_FLAG_PM_RUNTIME | - DL_FLAG_RPM_ACTIVE); - if (!priv->link[i]) { - ret = -ENOMEM; - dev_pm_domain_detach(priv->pd_dev[i], false); - goto exit_unroll_pm; - } - } - - ret = imx_scu_get_handle(&priv->sc_ipc); - if (ret) { - dev_err(sdev->dev, "Cannot obtain SCU handle (err = %d)\n", - ret); - goto exit_unroll_pm; - } - - priv->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp", - PLATFORM_DEVID_NONE, - pdev, sizeof(*pdev)); - if (IS_ERR(priv->ipc_dev)) { - ret = PTR_ERR(priv->ipc_dev); - goto exit_unroll_pm; - } - - priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev); - if (!priv->dsp_ipc) { - /* DSP IPC driver not probed yet, try later */ - ret = -EPROBE_DEFER; - dev_err(sdev->dev, "Failed to get drvdata\n"); - goto exit_pdev_unregister; - } - - imx_dsp_set_data(priv->dsp_ipc, priv); - priv->dsp_ipc->ops = &dsp_ops; - - /* DSP base */ - mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mmio) { - base = mmio->start; - size = resource_size(mmio); - } else { - dev_err(sdev->dev, "error: failed to get DSP base at idx 0\n"); - ret = -EINVAL; - goto exit_pdev_unregister; - } - - sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, base, size); - if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { - dev_err(sdev->dev, "failed to ioremap base 0x%x size 0x%x\n", - base, size); - ret = -ENODEV; - goto exit_pdev_unregister; - } - sdev->mmio_bar = SOF_FW_BLK_TYPE_IRAM; - - res_node = of_parse_phandle(np, "memory-region", 0); - if (!res_node) { - dev_err(&pdev->dev, "failed to get memory region node\n"); - ret = -ENODEV; - goto exit_pdev_unregister; - } - - ret = of_address_to_resource(res_node, 0, &res); - of_node_put(res_node); - if (ret) { - dev_err(&pdev->dev, "failed to get reserved region address\n"); - goto exit_pdev_unregister; - } - - sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, res.start, - resource_size(&res)); - if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { - dev_err(sdev->dev, "failed to ioremap mem 0x%x size 0x%x\n", - base, size); - ret = -ENOMEM; - goto exit_pdev_unregister; - } - sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; - - /* set default mailbox offset for FW ready message */ - sdev->dsp_box.offset = MBOX_OFFSET; - - ret = devm_clk_bulk_get_all(sdev->dev, &priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to fetch clocks: %d\n", ret); - goto exit_pdev_unregister; - } - priv->clk_num = ret; - - ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); - goto exit_pdev_unregister; - } + common->chip_pdata = sc_ipc_handle; return 0; - -exit_pdev_unregister: - platform_device_unregister(priv->ipc_dev); -exit_unroll_pm: - while (--i >= 0) { - device_link_del(priv->link[i]); - dev_pm_domain_detach(priv->pd_dev[i], false); - } - - return ret; -} - -static void imx8_remove(struct snd_sof_dev *sdev) -{ - struct imx8_priv *priv = sdev->pdata->hw_pdata; - int i; - - clk_bulk_disable_unprepare(priv->clk_num, priv->clks); - platform_device_unregister(priv->ipc_dev); - - for (i = 0; i < priv->num_domains; i++) { - device_link_del(priv->link[i]); - dev_pm_domain_detach(priv->pd_dev[i], false); - } -} - -/* on i.MX8 there is 1 to 1 match between type and BAR idx */ -static int imx8_get_bar_index(struct snd_sof_dev *sdev, u32 type) -{ - /* Only IRAM and SRAM bars are valid */ - switch (type) { - case SOF_FW_BLK_TYPE_IRAM: - case SOF_FW_BLK_TYPE_SRAM: - return type; - default: - return -EINVAL; - } -} - -static void imx8_suspend(struct snd_sof_dev *sdev) -{ - int i; - struct imx8_priv *priv = (struct imx8_priv *)sdev->pdata->hw_pdata; - - for (i = 0; i < DSP_MU_CHAN_NUM; i++) - imx_dsp_free_channel(priv->dsp_ipc, i); - - clk_bulk_disable_unprepare(priv->clk_num, priv->clks); -} - -static int imx8_resume(struct snd_sof_dev *sdev) -{ - struct imx8_priv *priv = (struct imx8_priv *)sdev->pdata->hw_pdata; - int ret; - int i; - - ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); - return ret; - } - - for (i = 0; i < DSP_MU_CHAN_NUM; i++) - imx_dsp_request_channel(priv->dsp_ipc, i); - - return 0; -} - -static int imx8_dsp_runtime_resume(struct snd_sof_dev *sdev) -{ - int ret; - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D0, - }; - - ret = imx8_resume(sdev); - if (ret < 0) - return ret; - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8_dsp_runtime_suspend(struct snd_sof_dev *sdev) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D3, - }; - - imx8_suspend(sdev); - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8_dsp_suspend(struct snd_sof_dev *sdev, unsigned int target_state) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = target_state, - }; - - if (!pm_runtime_suspended(sdev->dev)) - imx8_suspend(sdev); - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8_dsp_resume(struct snd_sof_dev *sdev) -{ - int ret; - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D0, - }; - - ret = imx8_resume(sdev); - if (ret < 0) - return ret; - - if (pm_runtime_suspended(sdev->dev)) { - pm_runtime_disable(sdev->dev); - pm_runtime_set_active(sdev->dev); - pm_runtime_mark_last_busy(sdev->dev); - pm_runtime_enable(sdev->dev); - pm_runtime_idle(sdev->dev); - } - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); } static struct snd_soc_dai_driver imx8_dai[] = { @@ -468,135 +143,64 @@ static struct snd_soc_dai_driver imx8_dai[] = { }, }; -static int imx8_dsp_set_power_state(struct snd_sof_dev *sdev, - const struct sof_dsp_power_state *target_state) +static struct snd_sof_dsp_ops sof_imx8_ops; + +static int imx8_ops_init(struct snd_sof_dev *sdev) { - sdev->dsp_power_state = *target_state; + /* first copy from template */ + memcpy(&sof_imx8_ops, &sof_imx_ops, sizeof(sof_imx_ops)); + + /* then set common imx8 ops */ + sof_imx8_ops.dbg_dump = imx8_dump; + sof_imx8_ops.dsp_arch_ops = &sof_xtensa_arch_ops; + sof_imx8_ops.debugfs_add_region_item = + snd_sof_debugfs_add_region_item_iomem; + + /* ... and finally set DAI driver */ + sof_imx8_ops.drv = get_chip_info(sdev)->drv; + sof_imx8_ops.num_drv = get_chip_info(sdev)->num_drv; return 0; } -/* i.MX8 ops */ -static const struct snd_sof_dsp_ops sof_imx8_ops = { - /* probe and remove */ - .probe = imx8_probe, - .remove = imx8_remove, - /* DSP core boot */ - .run = imx8_run, - - /* Block IO */ - .block_read = sof_block_read, - .block_write = sof_block_write, - - /* Mailbox IO */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - - /* ipc */ - .send_msg = imx8_send_msg, - .get_mailbox_offset = imx8_get_mailbox_offset, - .get_window_offset = imx8_get_window_offset, - - .ipc_msg_data = sof_ipc_msg_data, - .set_stream_data_offset = sof_set_stream_data_offset, - - .get_bar_index = imx8_get_bar_index, - - /* firmware loading */ - .load_firmware = snd_sof_load_firmware_memcpy, - - /* Debug information */ - .dbg_dump = imx8_dump, - .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, - - /* stream callbacks */ - .pcm_open = sof_stream_pcm_open, - .pcm_close = sof_stream_pcm_close, - - /* Firmware ops */ - .dsp_arch_ops = &sof_xtensa_arch_ops, - - /* DAI drivers */ - .drv = imx8_dai, - .num_drv = ARRAY_SIZE(imx8_dai), - - /* ALSA HW info flags */ - .hw_info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, - - /* PM */ - .runtime_suspend = imx8_dsp_runtime_suspend, - .runtime_resume = imx8_dsp_runtime_resume, - - .suspend = imx8_dsp_suspend, - .resume = imx8_dsp_resume, - - .set_power_state = imx8_dsp_set_power_state, +static const struct imx_chip_ops imx8_chip_ops = { + .probe = imx8_probe, + .core_kick = imx8_run, }; -/* i.MX8X ops */ -static const struct snd_sof_dsp_ops sof_imx8x_ops = { - /* probe and remove */ - .probe = imx8_probe, - .remove = imx8_remove, - /* DSP core boot */ - .run = imx8x_run, +static const struct imx_chip_ops imx8x_chip_ops = { + .probe = imx8_probe, + .core_kick = imx8x_run, +}; - /* Block IO */ - .block_read = sof_block_read, - .block_write = sof_block_write, +static struct imx_memory_info imx8_memory_regions[] = { + { .name = "iram", .reserved = false }, + { .name = "sram", .reserved = true }, + { } +}; - /* Mailbox IO */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - - /* ipc */ - .send_msg = imx8_send_msg, - .get_mailbox_offset = imx8_get_mailbox_offset, - .get_window_offset = imx8_get_window_offset, - - .ipc_msg_data = sof_ipc_msg_data, - .set_stream_data_offset = sof_set_stream_data_offset, - - .get_bar_index = imx8_get_bar_index, - - /* firmware loading */ - .load_firmware = snd_sof_load_firmware_memcpy, - - /* Debug information */ - .dbg_dump = imx8_dump, - .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, - - /* stream callbacks */ - .pcm_open = sof_stream_pcm_open, - .pcm_close = sof_stream_pcm_close, - - /* Firmware ops */ - .dsp_arch_ops = &sof_xtensa_arch_ops, - - /* DAI drivers */ +static const struct imx_chip_info imx8_chip_info = { + .ipc_info = { + .has_panic_code = true, + .boot_mbox_offset = 0x800000, + .window_offset = 0x800000, + }, + .memory = imx8_memory_regions, .drv = imx8_dai, .num_drv = ARRAY_SIZE(imx8_dai), + .ops = &imx8_chip_ops, +}; - /* PM */ - .runtime_suspend = imx8_dsp_runtime_suspend, - .runtime_resume = imx8_dsp_runtime_resume, - - .suspend = imx8_dsp_suspend, - .resume = imx8_dsp_resume, - - .set_power_state = imx8_dsp_set_power_state, - - /* ALSA HW info flags */ - .hw_info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_BATCH | - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP +static const struct imx_chip_info imx8x_chip_info = { + .ipc_info = { + .has_panic_code = true, + .boot_mbox_offset = 0x800000, + .window_offset = 0x800000, + }, + .memory = imx8_memory_regions, + .drv = imx8_dai, + .num_drv = ARRAY_SIZE(imx8_dai), + .ops = &imx8x_chip_ops, }; static struct snd_sof_of_mach sof_imx8_machs[] = { @@ -636,6 +240,7 @@ static struct snd_sof_of_mach sof_imx8_machs[] = { static struct sof_dev_desc sof_of_imx8qxp_desc = { .of_machines = sof_imx8_machs, + .chip_info = &imx8x_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, .default_fw_path = { @@ -648,11 +253,13 @@ static struct sof_dev_desc sof_of_imx8qxp_desc = { [SOF_IPC_TYPE_3] = "sof-imx8x.ri", }, .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", - .ops = &sof_imx8x_ops, + .ops = &sof_imx8_ops, + .ops_init = imx8_ops_init, }; static struct sof_dev_desc sof_of_imx8qm_desc = { .of_machines = sof_imx8_machs, + .chip_info = &imx8_chip_info, .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), .ipc_default = SOF_IPC_TYPE_3, .default_fw_path = { @@ -666,6 +273,7 @@ static struct sof_dev_desc sof_of_imx8qm_desc = { }, .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", .ops = &sof_imx8_ops, + .ops_init = imx8_ops_init, }; static const struct of_device_id sof_of_imx8_ids[] = { From 563e40153a56cbfae8721f9591022df5d930f939 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:22:42 -0500 Subject: [PATCH 088/651] ASoC: SOF: imx8: use IMX_SOF_* macros The definition of 'struct sof_dev_desc' has the following properties for imx chips: 1) FW path is the same for all chips. 2) Topology path is the same for all chips. 3) FW name can be written as: "sof-${machine_name}.ri" 4) IPC3 is the only supported protocol The structure takes quite a few lines of code. Since the intention is to add support for more imx8 chips in the same driver, we need to try and reduce the number of lines taken by information that's not particularly useful. As such, we can use 'IMX_SOF_DEV_DESC()' to reduce the declaration of the structure to just one line. The only information that's particularly useful can be seen from the parameters of the macro. Of course, if any of the assumptions don't apply anymore, driver writers can simply declare the 'struct sof_dev_desc' the "old fashioned way". No reason to make the macro suit multiple needs. The same logic applies to the array of 'struct snd_soc_dai_driver'. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Daniel Baluta Reviewed-by: Iuliana Prodan Reviewed-by: Frank Li Link: https://patch.msgid.link/20250207162246.3104-4-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx8.c | 73 +++++++--------------------------------- 1 file changed, 12 insertions(+), 61 deletions(-) diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 25e3296a1e5e..52dff369d9cf 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -119,28 +119,8 @@ static int imx8_probe(struct snd_sof_dev *sdev) } static struct snd_soc_dai_driver imx8_dai[] = { -{ - .name = "esai0", - .playback = { - .channels_min = 1, - .channels_max = 8, - }, - .capture = { - .channels_min = 1, - .channels_max = 8, - }, -}, -{ - .name = "sai1", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, -}, + IMX_SOF_DAI_DRV_ENTRY_BIDIR("esai0", 1, 8), + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai1", 1, 32), }; static struct snd_sof_dsp_ops sof_imx8_ops; @@ -238,47 +218,18 @@ static struct snd_sof_of_mach sof_imx8_machs[] = { {} }; -static struct sof_dev_desc sof_of_imx8qxp_desc = { - .of_machines = sof_imx8_machs, - .chip_info = &imx8x_chip_info, - .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), - .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8x.ri", - }, - .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", - .ops = &sof_imx8_ops, - .ops_init = imx8_ops_init, -}; - -static struct sof_dev_desc sof_of_imx8qm_desc = { - .of_machines = sof_imx8_machs, - .chip_info = &imx8_chip_info, - .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), - .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8.ri", - }, - .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", - .ops = &sof_imx8_ops, - .ops_init = imx8_ops_init, -}; +IMX_SOF_DEV_DESC(imx8, sof_imx8_machs, &imx8_chip_info, &sof_imx8_ops, imx8_ops_init); +IMX_SOF_DEV_DESC(imx8x, sof_imx8_machs, &imx8x_chip_info, &sof_imx8_ops, imx8_ops_init); static const struct of_device_id sof_of_imx8_ids[] = { - { .compatible = "fsl,imx8qxp-dsp", .data = &sof_of_imx8qxp_desc}, - { .compatible = "fsl,imx8qm-dsp", .data = &sof_of_imx8qm_desc}, + { + .compatible = "fsl,imx8qxp-dsp", + .data = &IMX_SOF_DEV_DESC_NAME(imx8x), + }, + { + .compatible = "fsl,imx8qm-dsp", + .data = &IMX_SOF_DEV_DESC_NAME(imx8), + }, { } }; MODULE_DEVICE_TABLE(of, sof_of_imx8_ids); From 45e02edd8422b6c4a511f38403dbd805cd139733 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:22:43 -0500 Subject: [PATCH 089/651] ASoC: SOF: imx8: drop unneeded/unused macros/header includes Drop some unneeded/unused macro definitions and header includes. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Daniel Baluta Reviewed-by: Iuliana Prodan Reviewed-by: Frank Li Link: https://patch.msgid.link/20250207162246.3104-5-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx8.c | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 52dff369d9cf..9a32ebe3eabc 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -6,41 +6,12 @@ // // Hardware interface for audio DSP on i.MX8 -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - #include #include -#include "../ops.h" -#include "../sof-of-dev.h" #include "imx-common.h" -/* DSP memories */ -#define IRAM_OFFSET 0x10000 -#define IRAM_SIZE (2 * 1024) -#define DRAM0_OFFSET 0x0 -#define DRAM0_SIZE (32 * 1024) -#define DRAM1_OFFSET 0x8000 -#define DRAM1_SIZE (32 * 1024) -#define SYSRAM_OFFSET 0x18000 -#define SYSRAM_SIZE (256 * 1024) -#define SYSROM_OFFSET 0x58000 -#define SYSROM_SIZE (192 * 1024) - #define RESET_VECTOR_VADDR 0x596f8000 -#define MBOX_OFFSET 0x800000 -#define MBOX_SIZE 0x1000 - /* * DSP control. */ From 896530b7b0c08ee8b3296d5f012bfe1b0a979b86 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:22:44 -0500 Subject: [PATCH 090/651] ASoC: SOF: imx: merge imx8 and imx8m drivers Now that the common interface for imx chip has been introduced, there's no longer a need to have a separate platform driver for imx8m. As such, merge the driver with the imx8 driver. Furthermore, delete the old driver as it's no longer useful. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Frank Li Link: https://patch.msgid.link/20250207162246.3104-6-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- sound/soc/sof/imx/Kconfig | 9 - sound/soc/sof/imx/Makefile | 2 - sound/soc/sof/imx/imx8.c | 136 ++++++++- sound/soc/sof/imx/imx8m.c | 567 ------------------------------------- 4 files changed, 134 insertions(+), 580 deletions(-) delete mode 100644 sound/soc/sof/imx/imx8m.c diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 4751b04d5e6f..92fdf80d6e51 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -32,15 +32,6 @@ config SND_SOC_SOF_IMX8 Say Y if you have such a device. If unsure select "N". -config SND_SOC_SOF_IMX8M - tristate "SOF support for i.MX8M" - depends on IMX_DSP - select SND_SOC_SOF_IMX_COMMON - help - This adds support for Sound Open Firmware for NXP i.MX8M platforms. - Say Y if you have such a device. - If unsure select "N". - config SND_SOC_SOF_IMX8ULP tristate "SOF support for i.MX8ULP" depends on IMX_DSP diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile index be0bf0736dfa..852140bb8104 100644 --- a/sound/soc/sof/imx/Makefile +++ b/sound/soc/sof/imx/Makefile @@ -1,11 +1,9 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) snd-sof-imx8-y := imx8.o -snd-sof-imx8m-y := imx8m.o snd-sof-imx8ulp-y := imx8ulp.o snd-sof-imx-common-y := imx-common.o obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o -obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o obj-$(CONFIG_SND_SOC_SOF_IMX8ULP) += snd-sof-imx8ulp.o obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 9a32ebe3eabc..7e08b239aac0 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -6,12 +6,34 @@ // // Hardware interface for audio DSP on i.MX8 -#include #include + +#include +#include + #include "imx-common.h" +/* imx8/imx8x macros */ #define RESET_VECTOR_VADDR 0x596f8000 +/* imx8m macros */ +#define IMX8M_DAP_DEBUG 0x28800000 +#define IMX8M_DAP_DEBUG_SIZE (64 * 1024) +#define IMX8M_DAP_PWRCTL (0x4000 + 0x3020) +#define IMX8M_PWRCTL_CORERESET BIT(16) + +#define AudioDSP_REG0 0x100 +#define AudioDSP_REG1 0x104 +#define AudioDSP_REG2 0x108 +#define AudioDSP_REG3 0x10c + +#define AudioDSP_REG2_RUNSTALL BIT(5) + +struct imx8m_chip_data { + void __iomem *dap; + struct regmap *regmap; +}; + /* * DSP control. */ @@ -89,11 +111,83 @@ static int imx8_probe(struct snd_sof_dev *sdev) return 0; } +static int imx8m_reset(struct snd_sof_dev *sdev) +{ + struct imx8m_chip_data *chip; + u32 pwrctl; + + chip = get_chip_pdata(sdev); + + /* put DSP into reset and stall */ + pwrctl = readl(chip->dap + IMX8M_DAP_PWRCTL); + pwrctl |= IMX8M_PWRCTL_CORERESET; + writel(pwrctl, chip->dap + IMX8M_DAP_PWRCTL); + + /* keep reset asserted for 10 cycles */ + usleep_range(1, 2); + + regmap_update_bits(chip->regmap, AudioDSP_REG2, + AudioDSP_REG2_RUNSTALL, AudioDSP_REG2_RUNSTALL); + + /* take the DSP out of reset and keep stalled for FW loading */ + pwrctl = readl(chip->dap + IMX8M_DAP_PWRCTL); + pwrctl &= ~IMX8M_PWRCTL_CORERESET; + writel(pwrctl, chip->dap + IMX8M_DAP_PWRCTL); + + return 0; +} + +static int imx8m_run(struct snd_sof_dev *sdev) +{ + struct imx8m_chip_data *chip = get_chip_pdata(sdev); + + regmap_update_bits(chip->regmap, AudioDSP_REG2, AudioDSP_REG2_RUNSTALL, 0); + + return 0; +} + +static int imx8m_probe(struct snd_sof_dev *sdev) +{ + struct imx_common_data *common; + struct imx8m_chip_data *chip; + + common = sdev->pdata->hw_pdata; + + chip = devm_kzalloc(sdev->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return dev_err_probe(sdev->dev, -ENOMEM, + "failed to allocate chip data\n"); + + chip->dap = devm_ioremap(sdev->dev, IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE); + if (!chip->dap) + return dev_err_probe(sdev->dev, -ENODEV, + "failed to ioremap DAP\n"); + + chip->regmap = syscon_regmap_lookup_by_phandle(sdev->dev->of_node, "fsl,dsp-ctrl"); + if (IS_ERR(chip->regmap)) + return dev_err_probe(sdev->dev, PTR_ERR(chip->regmap), + "failed to fetch dsp ctrl regmap\n"); + + common->chip_pdata = chip; + + return 0; +} + static struct snd_soc_dai_driver imx8_dai[] = { IMX_SOF_DAI_DRV_ENTRY_BIDIR("esai0", 1, 8), IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai1", 1, 32), }; +static struct snd_soc_dai_driver imx8m_dai[] = { + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai1", 1, 32), + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai2", 1, 32), + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai3", 1, 32), + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai5", 1, 32), + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai6", 1, 32), + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai7", 1, 32), + IMX_SOF_DAI_DRV_ENTRY("micfil", 0, 0, 1, 8), +}; + static struct snd_sof_dsp_ops sof_imx8_ops; static int imx8_ops_init(struct snd_sof_dev *sdev) @@ -124,12 +218,24 @@ static const struct imx_chip_ops imx8x_chip_ops = { .core_kick = imx8x_run, }; +static const struct imx_chip_ops imx8m_chip_ops = { + .probe = imx8m_probe, + .core_kick = imx8m_run, + .core_reset = imx8m_reset, +}; + static struct imx_memory_info imx8_memory_regions[] = { { .name = "iram", .reserved = false }, { .name = "sram", .reserved = true }, { } }; +static struct imx_memory_info imx8m_memory_regions[] = { + { .name = "iram", .reserved = false }, + { .name = "sram", .reserved = true }, + { } +}; + static const struct imx_chip_info imx8_chip_info = { .ipc_info = { .has_panic_code = true, @@ -154,6 +260,18 @@ static const struct imx_chip_info imx8x_chip_info = { .ops = &imx8x_chip_ops, }; +static const struct imx_chip_info imx8m_chip_info = { + .ipc_info = { + .has_panic_code = true, + .boot_mbox_offset = 0x800000, + .window_offset = 0x800000, + }, + .memory = imx8m_memory_regions, + .drv = imx8m_dai, + .num_drv = ARRAY_SIZE(imx8m_dai), + .ops = &imx8m_chip_ops, +}; + static struct snd_sof_of_mach sof_imx8_machs[] = { { .compatible = "fsl,imx8qxp-mek", @@ -185,12 +303,22 @@ static struct snd_sof_of_mach sof_imx8_machs[] = { .sof_tplg_filename = "sof-imx8-cs42888.tplg", .drv_name = "asoc-audio-graph-card2", }, - + { + .compatible = "fsl,imx8mp-evk", + .sof_tplg_filename = "sof-imx8mp-wm8960.tplg", + .drv_name = "asoc-audio-graph-card2", + }, + { + .compatible = "fsl,imx8mp-evk-revb4", + .sof_tplg_filename = "sof-imx8mp-wm8962.tplg", + .drv_name = "asoc-audio-graph-card2", + }, {} }; IMX_SOF_DEV_DESC(imx8, sof_imx8_machs, &imx8_chip_info, &sof_imx8_ops, imx8_ops_init); IMX_SOF_DEV_DESC(imx8x, sof_imx8_machs, &imx8x_chip_info, &sof_imx8_ops, imx8_ops_init); +IMX_SOF_DEV_DESC(imx8m, sof_imx8_machs, &imx8m_chip_info, &sof_imx8_ops, imx8_ops_init); static const struct of_device_id sof_of_imx8_ids[] = { { @@ -201,6 +329,10 @@ static const struct of_device_id sof_of_imx8_ids[] = { .compatible = "fsl,imx8qm-dsp", .data = &IMX_SOF_DEV_DESC_NAME(imx8), }, + { + .compatible = "fsl,imx8mp-dsp", + .data = &IMX_SOF_DEV_DESC_NAME(imx8m), + }, { } }; MODULE_DEVICE_TABLE(of, sof_of_imx8_ids); diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c deleted file mode 100644 index 3cabdebac558..000000000000 --- a/sound/soc/sof/imx/imx8m.c +++ /dev/null @@ -1,567 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -// -// Copyright 2020 NXP -// -// Author: Daniel Baluta -// -// Hardware interface for audio DSP on i.MX8M - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "../ops.h" -#include "../sof-of-dev.h" -#include "imx-common.h" - -#define MBOX_OFFSET 0x800000 -#define MBOX_SIZE 0x1000 - -/* DAP registers */ -#define IMX8M_DAP_DEBUG 0x28800000 -#define IMX8M_DAP_DEBUG_SIZE (64 * 1024) -#define IMX8M_DAP_PWRCTL (0x4000 + 0x3020) -#define IMX8M_PWRCTL_CORERESET BIT(16) - -/* DSP audio mix registers */ -#define AudioDSP_REG0 0x100 -#define AudioDSP_REG1 0x104 -#define AudioDSP_REG2 0x108 -#define AudioDSP_REG3 0x10c - -#define AudioDSP_REG2_RUNSTALL BIT(5) - -struct imx8m_priv { - struct device *dev; - struct snd_sof_dev *sdev; - - /* DSP IPC handler */ - struct imx_dsp_ipc *dsp_ipc; - struct platform_device *ipc_dev; - - struct clk_bulk_data *clks; - int clk_num; - - void __iomem *dap; - struct regmap *regmap; -}; - -static int imx8m_get_mailbox_offset(struct snd_sof_dev *sdev) -{ - return MBOX_OFFSET; -} - -static int imx8m_get_window_offset(struct snd_sof_dev *sdev, u32 id) -{ - return MBOX_OFFSET; -} - -static void imx8m_dsp_handle_reply(struct imx_dsp_ipc *ipc) -{ - struct imx8m_priv *priv = imx_dsp_get_data(ipc); - unsigned long flags; - - spin_lock_irqsave(&priv->sdev->ipc_lock, flags); - snd_sof_ipc_process_reply(priv->sdev, 0); - spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); -} - -static void imx8m_dsp_handle_request(struct imx_dsp_ipc *ipc) -{ - struct imx8m_priv *priv = imx_dsp_get_data(ipc); - u32 p; /* Panic code */ - - /* Read the message from the debug box. */ - sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p)); - - /* Check to see if the message is a panic code (0x0dead***) */ - if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) - snd_sof_dsp_panic(priv->sdev, p, true); - else - snd_sof_ipc_msgs_rx(priv->sdev); -} - -static struct imx_dsp_ops imx8m_dsp_ops = { - .handle_reply = imx8m_dsp_handle_reply, - .handle_request = imx8m_dsp_handle_request, -}; - -static int imx8m_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) -{ - struct imx8m_priv *priv = sdev->pdata->hw_pdata; - - sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, - msg->msg_size); - imx_dsp_ring_doorbell(priv->dsp_ipc, 0); - - return 0; -} - -/* - * DSP control. - */ -static int imx8m_run(struct snd_sof_dev *sdev) -{ - struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; - - regmap_update_bits(priv->regmap, AudioDSP_REG2, AudioDSP_REG2_RUNSTALL, 0); - - return 0; -} - -static int imx8m_reset(struct snd_sof_dev *sdev) -{ - struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; - u32 pwrctl; - - /* put DSP into reset and stall */ - pwrctl = readl(priv->dap + IMX8M_DAP_PWRCTL); - pwrctl |= IMX8M_PWRCTL_CORERESET; - writel(pwrctl, priv->dap + IMX8M_DAP_PWRCTL); - - /* keep reset asserted for 10 cycles */ - usleep_range(1, 2); - - regmap_update_bits(priv->regmap, AudioDSP_REG2, - AudioDSP_REG2_RUNSTALL, AudioDSP_REG2_RUNSTALL); - - /* take the DSP out of reset and keep stalled for FW loading */ - pwrctl = readl(priv->dap + IMX8M_DAP_PWRCTL); - pwrctl &= ~IMX8M_PWRCTL_CORERESET; - writel(pwrctl, priv->dap + IMX8M_DAP_PWRCTL); - - return 0; -} - -static int imx8m_probe(struct snd_sof_dev *sdev) -{ - struct platform_device *pdev = to_platform_device(sdev->dev); - struct device_node *np = pdev->dev.of_node; - struct device_node *res_node; - struct resource *mmio; - struct imx8m_priv *priv; - struct resource res; - u32 base, size; - int ret = 0; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - sdev->num_cores = 1; - sdev->pdata->hw_pdata = priv; - priv->dev = sdev->dev; - priv->sdev = sdev; - - priv->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp", - PLATFORM_DEVID_NONE, - pdev, sizeof(*pdev)); - if (IS_ERR(priv->ipc_dev)) - return PTR_ERR(priv->ipc_dev); - - priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev); - if (!priv->dsp_ipc) { - /* DSP IPC driver not probed yet, try later */ - ret = -EPROBE_DEFER; - dev_err(sdev->dev, "Failed to get drvdata\n"); - goto exit_pdev_unregister; - } - - imx_dsp_set_data(priv->dsp_ipc, priv); - priv->dsp_ipc->ops = &imx8m_dsp_ops; - - /* DSP base */ - mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mmio) { - base = mmio->start; - size = resource_size(mmio); - } else { - dev_err(sdev->dev, "error: failed to get DSP base at idx 0\n"); - ret = -EINVAL; - goto exit_pdev_unregister; - } - - priv->dap = devm_ioremap(sdev->dev, IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE); - if (!priv->dap) { - dev_err(sdev->dev, "error: failed to map DAP debug memory area"); - ret = -ENODEV; - goto exit_pdev_unregister; - } - - sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, base, size); - if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { - dev_err(sdev->dev, "failed to ioremap base 0x%x size 0x%x\n", - base, size); - ret = -ENODEV; - goto exit_pdev_unregister; - } - sdev->mmio_bar = SOF_FW_BLK_TYPE_IRAM; - - res_node = of_parse_phandle(np, "memory-region", 0); - if (!res_node) { - dev_err(&pdev->dev, "failed to get memory region node\n"); - ret = -ENODEV; - goto exit_pdev_unregister; - } - - ret = of_address_to_resource(res_node, 0, &res); - of_node_put(res_node); - if (ret) { - dev_err(&pdev->dev, "failed to get reserved region address\n"); - goto exit_pdev_unregister; - } - - sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, res.start, - resource_size(&res)); - if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { - dev_err(sdev->dev, "failed to ioremap mem 0x%x size 0x%x\n", - base, size); - ret = -ENOMEM; - goto exit_pdev_unregister; - } - sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; - - /* set default mailbox offset for FW ready message */ - sdev->dsp_box.offset = MBOX_OFFSET; - - priv->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,dsp-ctrl"); - if (IS_ERR(priv->regmap)) { - dev_err(sdev->dev, "cannot find dsp-ctrl registers"); - ret = PTR_ERR(priv->regmap); - goto exit_pdev_unregister; - } - - ret = devm_clk_bulk_get_all(sdev->dev, &priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to fetch clocks: %d\n", ret); - goto exit_pdev_unregister; - } - priv->clk_num = ret; - - ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); - goto exit_pdev_unregister; - } - - return 0; - -exit_pdev_unregister: - platform_device_unregister(priv->ipc_dev); - return ret; -} - -static void imx8m_remove(struct snd_sof_dev *sdev) -{ - struct imx8m_priv *priv = sdev->pdata->hw_pdata; - - clk_bulk_disable_unprepare(priv->clk_num, priv->clks); - platform_device_unregister(priv->ipc_dev); -} - -/* on i.MX8 there is 1 to 1 match between type and BAR idx */ -static int imx8m_get_bar_index(struct snd_sof_dev *sdev, u32 type) -{ - /* Only IRAM and SRAM bars are valid */ - switch (type) { - case SOF_FW_BLK_TYPE_IRAM: - case SOF_FW_BLK_TYPE_SRAM: - return type; - default: - return -EINVAL; - } -} - -static struct snd_soc_dai_driver imx8m_dai[] = { -{ - .name = "sai1", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, -}, -{ - .name = "sai2", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, -}, -{ - .name = "sai3", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, -}, -{ - .name = "sai5", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, -}, -{ - .name = "sai6", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, -}, -{ - .name = "sai7", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, -}, -{ - .name = "micfil", - .capture = { - .channels_min = 1, - .channels_max = 8, - }, -}, -}; - -static int imx8m_dsp_set_power_state(struct snd_sof_dev *sdev, - const struct sof_dsp_power_state *target_state) -{ - sdev->dsp_power_state = *target_state; - - return 0; -} - -static int imx8m_resume(struct snd_sof_dev *sdev) -{ - struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; - int ret; - int i; - - ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); - return ret; - } - - for (i = 0; i < DSP_MU_CHAN_NUM; i++) - imx_dsp_request_channel(priv->dsp_ipc, i); - - return 0; -} - -static void imx8m_suspend(struct snd_sof_dev *sdev) -{ - struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; - int i; - - for (i = 0; i < DSP_MU_CHAN_NUM; i++) - imx_dsp_free_channel(priv->dsp_ipc, i); - - clk_bulk_disable_unprepare(priv->clk_num, priv->clks); -} - -static int imx8m_dsp_runtime_resume(struct snd_sof_dev *sdev) -{ - int ret; - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D0, - }; - - ret = imx8m_resume(sdev); - if (ret < 0) - return ret; - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8m_dsp_runtime_suspend(struct snd_sof_dev *sdev) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D3, - }; - - imx8m_suspend(sdev); - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8m_dsp_resume(struct snd_sof_dev *sdev) -{ - int ret; - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D0, - }; - - ret = imx8m_resume(sdev); - if (ret < 0) - return ret; - - if (pm_runtime_suspended(sdev->dev)) { - pm_runtime_disable(sdev->dev); - pm_runtime_set_active(sdev->dev); - pm_runtime_mark_last_busy(sdev->dev); - pm_runtime_enable(sdev->dev); - pm_runtime_idle(sdev->dev); - } - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8m_dsp_suspend(struct snd_sof_dev *sdev, unsigned int target_state) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = target_state, - }; - - if (!pm_runtime_suspended(sdev->dev)) - imx8m_suspend(sdev); - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -/* i.MX8 ops */ -static const struct snd_sof_dsp_ops sof_imx8m_ops = { - /* probe and remove */ - .probe = imx8m_probe, - .remove = imx8m_remove, - /* DSP core boot */ - .run = imx8m_run, - .reset = imx8m_reset, - - /* Block IO */ - .block_read = sof_block_read, - .block_write = sof_block_write, - - /* Mailbox IO */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - - /* ipc */ - .send_msg = imx8m_send_msg, - .get_mailbox_offset = imx8m_get_mailbox_offset, - .get_window_offset = imx8m_get_window_offset, - - .ipc_msg_data = sof_ipc_msg_data, - .set_stream_data_offset = sof_set_stream_data_offset, - - .get_bar_index = imx8m_get_bar_index, - - /* firmware loading */ - .load_firmware = snd_sof_load_firmware_memcpy, - - /* Debug information */ - .dbg_dump = imx8_dump, - .debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem, - - /* stream callbacks */ - .pcm_open = sof_stream_pcm_open, - .pcm_close = sof_stream_pcm_close, - /* Firmware ops */ - .dsp_arch_ops = &sof_xtensa_arch_ops, - - /* DAI drivers */ - .drv = imx8m_dai, - .num_drv = ARRAY_SIZE(imx8m_dai), - - .suspend = imx8m_dsp_suspend, - .resume = imx8m_dsp_resume, - - .runtime_suspend = imx8m_dsp_runtime_suspend, - .runtime_resume = imx8m_dsp_runtime_resume, - - .set_power_state = imx8m_dsp_set_power_state, - - .hw_info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_BATCH | - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, -}; - -static struct snd_sof_of_mach sof_imx8mp_machs[] = { - { - .compatible = "fsl,imx8mp-evk-revb4", - .sof_tplg_filename = "sof-imx8mp-wm8962.tplg", - .drv_name = "asoc-audio-graph-card2", - }, - { - .compatible = "fsl,imx8mp-evk", - .sof_tplg_filename = "sof-imx8mp-wm8960.tplg", - .drv_name = "asoc-audio-graph-card2", - }, - {} -}; - -static struct sof_dev_desc sof_of_imx8mp_desc = { - .of_machines = sof_imx8mp_machs, - .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), - .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8m.ri", - }, - .nocodec_tplg_filename = "sof-imx8-nocodec.tplg", - .ops = &sof_imx8m_ops, -}; - -static const struct of_device_id sof_of_imx8m_ids[] = { - { .compatible = "fsl,imx8mp-dsp", .data = &sof_of_imx8mp_desc}, - { } -}; -MODULE_DEVICE_TABLE(of, sof_of_imx8m_ids); - -/* DT driver definition */ -static struct platform_driver snd_sof_of_imx8m_driver = { - .probe = sof_of_probe, - .remove = sof_of_remove, - .driver = { - .name = "sof-audio-of-imx8m", - .pm = &sof_of_pm, - .of_match_table = sof_of_imx8m_ids, - }, -}; -module_platform_driver(snd_sof_of_imx8m_driver); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("SOF support for IMX8M platforms"); -MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); From 07e3e514dd385300bd08da4a8df09240d272821e Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:22:45 -0500 Subject: [PATCH 091/651] ASoC: SOF: imx: merge imx8 and imx8ulp drivers Now that the common interface for imx chip has been introduced, there's no longer a need to have a separate platform driver for imx8ulp. As such, merge the driver with the imx8 driver. Furthermore, delete the old driver as it's no longer useful. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Frank Li Link: https://patch.msgid.link/20250207162246.3104-7-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- sound/soc/sof/imx/Kconfig | 9 - sound/soc/sof/imx/Makefile | 2 - sound/soc/sof/imx/imx8.c | 113 ++++++++ sound/soc/sof/imx/imx8ulp.c | 520 ------------------------------------ 4 files changed, 113 insertions(+), 531 deletions(-) delete mode 100644 sound/soc/sof/imx/imx8ulp.c diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 92fdf80d6e51..2edf9de2c886 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -32,13 +32,4 @@ config SND_SOC_SOF_IMX8 Say Y if you have such a device. If unsure select "N". -config SND_SOC_SOF_IMX8ULP - tristate "SOF support for i.MX8ULP" - depends on IMX_DSP - select SND_SOC_SOF_IMX_COMMON - help - This adds support for Sound Open Firmware for NXP i.MX8ULP platforms. - Say Y if you have such a device. - If unsure select "N". - endif ## SND_SOC_SOF_IMX_TOPLEVEL diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile index 852140bb8104..36a3a67c6efb 100644 --- a/sound/soc/sof/imx/Makefile +++ b/sound/soc/sof/imx/Makefile @@ -1,9 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) snd-sof-imx8-y := imx8.o -snd-sof-imx8ulp-y := imx8ulp.o snd-sof-imx-common-y := imx-common.o obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o -obj-$(CONFIG_SND_SOC_SOF_IMX8ULP) += snd-sof-imx8ulp.o obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 7e08b239aac0..4be4c569b583 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -8,6 +8,7 @@ #include +#include #include #include @@ -29,6 +30,16 @@ #define AudioDSP_REG2_RUNSTALL BIT(5) +/* imx8ulp macros */ +#define FSL_SIP_HIFI_XRDC 0xc200000e +#define SYSCTRL0 0x8 +#define EXECUTE_BIT BIT(13) +#define RESET_BIT BIT(16) +#define HIFI4_CLK_BIT BIT(17) +#define PB_CLK_BIT BIT(18) +#define PLAT_CLK_BIT BIT(19) +#define DEBUG_LOGIC_BIT BIT(25) + struct imx8m_chip_data { void __iomem *dap; struct regmap *regmap; @@ -173,6 +184,68 @@ static int imx8m_probe(struct snd_sof_dev *sdev) return 0; } +static int imx8ulp_run(struct snd_sof_dev *sdev) +{ + struct regmap *regmap = get_chip_pdata(sdev); + + /* Controls the HiFi4 DSP Reset: 1 in reset, 0 out of reset */ + regmap_update_bits(regmap, SYSCTRL0, RESET_BIT, 0); + + /* Reset HiFi4 DSP Debug logic: 1 debug reset, 0 out of reset*/ + regmap_update_bits(regmap, SYSCTRL0, DEBUG_LOGIC_BIT, 0); + + /* Stall HIFI4 DSP Execution: 1 stall, 0 run */ + regmap_update_bits(regmap, SYSCTRL0, EXECUTE_BIT, 0); + + return 0; +} + +static int imx8ulp_reset(struct snd_sof_dev *sdev) +{ + struct arm_smccc_res smc_res; + struct regmap *regmap; + + regmap = get_chip_pdata(sdev); + + /* HiFi4 Platform Clock Enable: 1 enabled, 0 disabled */ + regmap_update_bits(regmap, SYSCTRL0, PLAT_CLK_BIT, PLAT_CLK_BIT); + + /* HiFi4 PBCLK clock enable: 1 enabled, 0 disabled */ + regmap_update_bits(regmap, SYSCTRL0, PB_CLK_BIT, PB_CLK_BIT); + + /* HiFi4 Clock Enable: 1 enabled, 0 disabled */ + regmap_update_bits(regmap, SYSCTRL0, HIFI4_CLK_BIT, HIFI4_CLK_BIT); + + regmap_update_bits(regmap, SYSCTRL0, RESET_BIT, RESET_BIT); + + usleep_range(1, 2); + + /* Stall HIFI4 DSP Execution: 1 stall, 0 not stall */ + regmap_update_bits(regmap, SYSCTRL0, EXECUTE_BIT, EXECUTE_BIT); + usleep_range(1, 2); + + arm_smccc_smc(FSL_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &smc_res); + + return smc_res.a0; +} + +static int imx8ulp_probe(struct snd_sof_dev *sdev) +{ + struct imx_common_data *common; + struct regmap *regmap; + + common = sdev->pdata->hw_pdata; + + regmap = syscon_regmap_lookup_by_phandle(sdev->dev->of_node, "fsl,dsp-ctrl"); + if (IS_ERR(regmap)) + return dev_err_probe(sdev->dev, PTR_ERR(regmap), + "failed to fetch dsp ctrl regmap\n"); + + common->chip_pdata = regmap; + + return 0; +} + static struct snd_soc_dai_driver imx8_dai[] = { IMX_SOF_DAI_DRV_ENTRY_BIDIR("esai0", 1, 8), IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai1", 1, 32), @@ -188,6 +261,11 @@ static struct snd_soc_dai_driver imx8m_dai[] = { IMX_SOF_DAI_DRV_ENTRY("micfil", 0, 0, 1, 8), }; +static struct snd_soc_dai_driver imx8ulp_dai[] = { + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai5", 1, 32), + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai6", 1, 32), +}; + static struct snd_sof_dsp_ops sof_imx8_ops; static int imx8_ops_init(struct snd_sof_dev *sdev) @@ -224,6 +302,12 @@ static const struct imx_chip_ops imx8m_chip_ops = { .core_reset = imx8m_reset, }; +static const struct imx_chip_ops imx8ulp_chip_ops = { + .probe = imx8ulp_probe, + .core_kick = imx8ulp_run, + .core_reset = imx8ulp_reset, +}; + static struct imx_memory_info imx8_memory_regions[] = { { .name = "iram", .reserved = false }, { .name = "sram", .reserved = true }, @@ -236,6 +320,12 @@ static struct imx_memory_info imx8m_memory_regions[] = { { } }; +static struct imx_memory_info imx8ulp_memory_regions[] = { + { .name = "iram", .reserved = false }, + { .name = "sram", .reserved = true }, + { } +}; + static const struct imx_chip_info imx8_chip_info = { .ipc_info = { .has_panic_code = true, @@ -272,6 +362,19 @@ static const struct imx_chip_info imx8m_chip_info = { .ops = &imx8m_chip_ops, }; +static const struct imx_chip_info imx8ulp_chip_info = { + .ipc_info = { + .has_panic_code = true, + .boot_mbox_offset = 0x800000, + .window_offset = 0x800000, + }, + .has_dma_reserved = true, + .memory = imx8ulp_memory_regions, + .drv = imx8ulp_dai, + .num_drv = ARRAY_SIZE(imx8ulp_dai), + .ops = &imx8ulp_chip_ops, +}; + static struct snd_sof_of_mach sof_imx8_machs[] = { { .compatible = "fsl,imx8qxp-mek", @@ -313,12 +416,18 @@ static struct snd_sof_of_mach sof_imx8_machs[] = { .sof_tplg_filename = "sof-imx8mp-wm8962.tplg", .drv_name = "asoc-audio-graph-card2", }, + { + .compatible = "fsl,imx8ulp-evk", + .sof_tplg_filename = "sof-imx8ulp-btsco.tplg", + .drv_name = "asoc-audio-graph-card2", + }, {} }; IMX_SOF_DEV_DESC(imx8, sof_imx8_machs, &imx8_chip_info, &sof_imx8_ops, imx8_ops_init); IMX_SOF_DEV_DESC(imx8x, sof_imx8_machs, &imx8x_chip_info, &sof_imx8_ops, imx8_ops_init); IMX_SOF_DEV_DESC(imx8m, sof_imx8_machs, &imx8m_chip_info, &sof_imx8_ops, imx8_ops_init); +IMX_SOF_DEV_DESC(imx8ulp, sof_imx8_machs, &imx8ulp_chip_info, &sof_imx8_ops, imx8_ops_init); static const struct of_device_id sof_of_imx8_ids[] = { { @@ -333,6 +442,10 @@ static const struct of_device_id sof_of_imx8_ids[] = { .compatible = "fsl,imx8mp-dsp", .data = &IMX_SOF_DEV_DESC_NAME(imx8m), }, + { + .compatible = "fsl,imx8ulp-dsp", + .data = &IMX_SOF_DEV_DESC_NAME(imx8ulp), + }, { } }; MODULE_DEVICE_TABLE(of, sof_of_imx8_ids); diff --git a/sound/soc/sof/imx/imx8ulp.c b/sound/soc/sof/imx/imx8ulp.c deleted file mode 100644 index 0704da27e69d..000000000000 --- a/sound/soc/sof/imx/imx8ulp.c +++ /dev/null @@ -1,520 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -// -// Copyright 2021-2022 NXP -// -// Author: Peng Zhang -// -// Hardware interface for audio DSP on i.MX8ULP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "../ops.h" -#include "../sof-of-dev.h" -#include "imx-common.h" - -#define FSL_SIP_HIFI_XRDC 0xc200000e - -/* SIM Domain register */ -#define SYSCTRL0 0x8 -#define EXECUTE_BIT BIT(13) -#define RESET_BIT BIT(16) -#define HIFI4_CLK_BIT BIT(17) -#define PB_CLK_BIT BIT(18) -#define PLAT_CLK_BIT BIT(19) -#define DEBUG_LOGIC_BIT BIT(25) - -#define MBOX_OFFSET 0x800000 -#define MBOX_SIZE 0x1000 - -struct imx8ulp_priv { - struct device *dev; - struct snd_sof_dev *sdev; - - /* DSP IPC handler */ - struct imx_dsp_ipc *dsp_ipc; - struct platform_device *ipc_dev; - - struct regmap *regmap; - struct clk_bulk_data *clks; - int clk_num; -}; - -static void imx8ulp_sim_lpav_start(struct imx8ulp_priv *priv) -{ - /* Controls the HiFi4 DSP Reset: 1 in reset, 0 out of reset */ - regmap_update_bits(priv->regmap, SYSCTRL0, RESET_BIT, 0); - - /* Reset HiFi4 DSP Debug logic: 1 debug reset, 0 out of reset*/ - regmap_update_bits(priv->regmap, SYSCTRL0, DEBUG_LOGIC_BIT, 0); - - /* Stall HIFI4 DSP Execution: 1 stall, 0 run */ - regmap_update_bits(priv->regmap, SYSCTRL0, EXECUTE_BIT, 0); -} - -static int imx8ulp_get_mailbox_offset(struct snd_sof_dev *sdev) -{ - return MBOX_OFFSET; -} - -static int imx8ulp_get_window_offset(struct snd_sof_dev *sdev, u32 id) -{ - return MBOX_OFFSET; -} - -static void imx8ulp_dsp_handle_reply(struct imx_dsp_ipc *ipc) -{ - struct imx8ulp_priv *priv = imx_dsp_get_data(ipc); - unsigned long flags; - - spin_lock_irqsave(&priv->sdev->ipc_lock, flags); - - snd_sof_ipc_process_reply(priv->sdev, 0); - - spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); -} - -static void imx8ulp_dsp_handle_request(struct imx_dsp_ipc *ipc) -{ - struct imx8ulp_priv *priv = imx_dsp_get_data(ipc); - u32 p; /* panic code */ - - /* Read the message from the debug box. */ - sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p)); - - /* Check to see if the message is a panic code (0x0dead***) */ - if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) - snd_sof_dsp_panic(priv->sdev, p, true); - else - snd_sof_ipc_msgs_rx(priv->sdev); -} - -static struct imx_dsp_ops dsp_ops = { - .handle_reply = imx8ulp_dsp_handle_reply, - .handle_request = imx8ulp_dsp_handle_request, -}; - -static int imx8ulp_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) -{ - struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; - - sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, - msg->msg_size); - imx_dsp_ring_doorbell(priv->dsp_ipc, 0); - - return 0; -} - -static int imx8ulp_run(struct snd_sof_dev *sdev) -{ - struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; - - imx8ulp_sim_lpav_start(priv); - - return 0; -} - -static int imx8ulp_reset(struct snd_sof_dev *sdev) -{ - struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; - struct arm_smccc_res smc_resource; - - /* HiFi4 Platform Clock Enable: 1 enabled, 0 disabled */ - regmap_update_bits(priv->regmap, SYSCTRL0, PLAT_CLK_BIT, PLAT_CLK_BIT); - - /* HiFi4 PBCLK clock enable: 1 enabled, 0 disabled */ - regmap_update_bits(priv->regmap, SYSCTRL0, PB_CLK_BIT, PB_CLK_BIT); - - /* HiFi4 Clock Enable: 1 enabled, 0 disabled */ - regmap_update_bits(priv->regmap, SYSCTRL0, HIFI4_CLK_BIT, HIFI4_CLK_BIT); - - regmap_update_bits(priv->regmap, SYSCTRL0, RESET_BIT, RESET_BIT); - usleep_range(1, 2); - - /* Stall HIFI4 DSP Execution: 1 stall, 0 not stall */ - regmap_update_bits(priv->regmap, SYSCTRL0, EXECUTE_BIT, EXECUTE_BIT); - usleep_range(1, 2); - - arm_smccc_smc(FSL_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &smc_resource); - - return 0; -} - -static int imx8ulp_probe(struct snd_sof_dev *sdev) -{ - struct platform_device *pdev = to_platform_device(sdev->dev); - struct device_node *np = pdev->dev.of_node; - struct device_node *res_node; - struct resource *mmio; - struct imx8ulp_priv *priv; - struct resource res; - u32 base, size; - int ret = 0; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - sdev->num_cores = 1; - sdev->pdata->hw_pdata = priv; - priv->dev = sdev->dev; - priv->sdev = sdev; - - /* System integration module(SIM) control dsp configuration */ - priv->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,dsp-ctrl"); - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - - priv->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp", - PLATFORM_DEVID_NONE, - pdev, sizeof(*pdev)); - if (IS_ERR(priv->ipc_dev)) - return PTR_ERR(priv->ipc_dev); - - priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev); - if (!priv->dsp_ipc) { - /* DSP IPC driver not probed yet, try later */ - ret = -EPROBE_DEFER; - dev_err(sdev->dev, "Failed to get drvdata\n"); - goto exit_pdev_unregister; - } - - imx_dsp_set_data(priv->dsp_ipc, priv); - priv->dsp_ipc->ops = &dsp_ops; - - /* DSP base */ - mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mmio) { - base = mmio->start; - size = resource_size(mmio); - } else { - dev_err(sdev->dev, "error: failed to get DSP base at idx 0\n"); - ret = -EINVAL; - goto exit_pdev_unregister; - } - - sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, base, size); - if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { - dev_err(sdev->dev, "failed to ioremap base 0x%x size 0x%x\n", - base, size); - ret = -ENODEV; - goto exit_pdev_unregister; - } - sdev->mmio_bar = SOF_FW_BLK_TYPE_IRAM; - - res_node = of_parse_phandle(np, "memory-reserved", 0); - if (!res_node) { - dev_err(&pdev->dev, "failed to get memory region node\n"); - ret = -ENODEV; - goto exit_pdev_unregister; - } - - ret = of_address_to_resource(res_node, 0, &res); - of_node_put(res_node); - if (ret) { - dev_err(&pdev->dev, "failed to get reserved region address\n"); - goto exit_pdev_unregister; - } - - sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, res.start, - resource_size(&res)); - if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { - dev_err(sdev->dev, "failed to ioremap mem 0x%x size 0x%x\n", - base, size); - ret = -ENOMEM; - goto exit_pdev_unregister; - } - sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; - - /* set default mailbox offset for FW ready message */ - sdev->dsp_box.offset = MBOX_OFFSET; - - ret = of_reserved_mem_device_init(sdev->dev); - if (ret) { - dev_err(&pdev->dev, "failed to init reserved memory region %d\n", ret); - goto exit_pdev_unregister; - } - - ret = devm_clk_bulk_get_all(sdev->dev, &priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to fetch clocks: %d\n", ret); - goto exit_pdev_unregister; - } - priv->clk_num = ret; - - ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); - goto exit_pdev_unregister; - } - - return 0; - -exit_pdev_unregister: - platform_device_unregister(priv->ipc_dev); - - return ret; -} - -static void imx8ulp_remove(struct snd_sof_dev *sdev) -{ - struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; - - clk_bulk_disable_unprepare(priv->clk_num, priv->clks); - platform_device_unregister(priv->ipc_dev); -} - -/* on i.MX8 there is 1 to 1 match between type and BAR idx */ -static int imx8ulp_get_bar_index(struct snd_sof_dev *sdev, u32 type) -{ - return type; -} - -static int imx8ulp_suspend(struct snd_sof_dev *sdev) -{ - int i; - struct imx8ulp_priv *priv = (struct imx8ulp_priv *)sdev->pdata->hw_pdata; - - /*Stall DSP, release in .run() */ - regmap_update_bits(priv->regmap, SYSCTRL0, EXECUTE_BIT, EXECUTE_BIT); - - for (i = 0; i < DSP_MU_CHAN_NUM; i++) - imx_dsp_free_channel(priv->dsp_ipc, i); - - clk_bulk_disable_unprepare(priv->clk_num, priv->clks); - - return 0; -} - -static int imx8ulp_resume(struct snd_sof_dev *sdev) -{ - struct imx8ulp_priv *priv = (struct imx8ulp_priv *)sdev->pdata->hw_pdata; - int i, ret; - - ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); - if (ret < 0) { - dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); - return ret; - } - - for (i = 0; i < DSP_MU_CHAN_NUM; i++) - imx_dsp_request_channel(priv->dsp_ipc, i); - - return 0; -} - -static int imx8ulp_dsp_runtime_resume(struct snd_sof_dev *sdev) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D0, - .substate = 0, - }; - - imx8ulp_resume(sdev); - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8ulp_dsp_runtime_suspend(struct snd_sof_dev *sdev) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D3, - .substate = 0, - }; - - imx8ulp_suspend(sdev); - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8ulp_dsp_suspend(struct snd_sof_dev *sdev, unsigned int target_state) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = target_state, - .substate = 0, - }; - - if (!pm_runtime_suspended(sdev->dev)) - imx8ulp_suspend(sdev); - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static int imx8ulp_dsp_resume(struct snd_sof_dev *sdev) -{ - const struct sof_dsp_power_state target_dsp_state = { - .state = SOF_DSP_PM_D0, - .substate = 0, - }; - - imx8ulp_resume(sdev); - - if (pm_runtime_suspended(sdev->dev)) { - pm_runtime_disable(sdev->dev); - pm_runtime_set_active(sdev->dev); - pm_runtime_mark_last_busy(sdev->dev); - pm_runtime_enable(sdev->dev); - pm_runtime_idle(sdev->dev); - } - - return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); -} - -static struct snd_soc_dai_driver imx8ulp_dai[] = { - { - .name = "sai5", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, - }, - { - .name = "sai6", - .playback = { - .channels_min = 1, - .channels_max = 32, - }, - .capture = { - .channels_min = 1, - .channels_max = 32, - }, - }, -}; - -static int imx8ulp_dsp_set_power_state(struct snd_sof_dev *sdev, - const struct sof_dsp_power_state *target_state) -{ - sdev->dsp_power_state = *target_state; - - return 0; -} - -/* i.MX8 ops */ -static const struct snd_sof_dsp_ops sof_imx8ulp_ops = { - /* probe and remove */ - .probe = imx8ulp_probe, - .remove = imx8ulp_remove, - /* DSP core boot */ - .run = imx8ulp_run, - .reset = imx8ulp_reset, - - /* Block IO */ - .block_read = sof_block_read, - .block_write = sof_block_write, - - /* Module IO */ - .read64 = sof_io_read64, - - /* Mailbox IO */ - .mailbox_read = sof_mailbox_read, - .mailbox_write = sof_mailbox_write, - - /* ipc */ - .send_msg = imx8ulp_send_msg, - .get_mailbox_offset = imx8ulp_get_mailbox_offset, - .get_window_offset = imx8ulp_get_window_offset, - - .ipc_msg_data = sof_ipc_msg_data, - .set_stream_data_offset = sof_set_stream_data_offset, - - /* stream callbacks */ - .pcm_open = sof_stream_pcm_open, - .pcm_close = sof_stream_pcm_close, - - /* module loading */ - .get_bar_index = imx8ulp_get_bar_index, - /* firmware loading */ - .load_firmware = snd_sof_load_firmware_memcpy, - - /* Debug information */ - .dbg_dump = imx8_dump, - - /* Firmware ops */ - .dsp_arch_ops = &sof_xtensa_arch_ops, - - /* DAI drivers */ - .drv = imx8ulp_dai, - .num_drv = ARRAY_SIZE(imx8ulp_dai), - - /* ALSA HW info flags */ - .hw_info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_BATCH | - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, - - /* PM */ - .runtime_suspend = imx8ulp_dsp_runtime_suspend, - .runtime_resume = imx8ulp_dsp_runtime_resume, - - .suspend = imx8ulp_dsp_suspend, - .resume = imx8ulp_dsp_resume, - - .set_power_state = imx8ulp_dsp_set_power_state, -}; - -static struct snd_sof_of_mach sof_imx8ulp_machs[] = { - { - .compatible = "fsl,imx8ulp-evk", - .sof_tplg_filename = "sof-imx8ulp-btsco.tplg", - .drv_name = "asoc-audio-graph-card2", - }, - {} -}; - -static struct sof_dev_desc sof_of_imx8ulp_desc = { - .of_machines = sof_imx8ulp_machs, - .ipc_supported_mask = BIT(SOF_IPC_TYPE_3), - .ipc_default = SOF_IPC_TYPE_3, - .default_fw_path = { - [SOF_IPC_TYPE_3] = "imx/sof", - }, - .default_tplg_path = { - [SOF_IPC_TYPE_3] = "imx/sof-tplg", - }, - .default_fw_filename = { - [SOF_IPC_TYPE_3] = "sof-imx8ulp.ri", - }, - .nocodec_tplg_filename = "sof-imx8ulp-nocodec.tplg", - .ops = &sof_imx8ulp_ops, -}; - -static const struct of_device_id sof_of_imx8ulp_ids[] = { - { .compatible = "fsl,imx8ulp-dsp", .data = &sof_of_imx8ulp_desc}, - { } -}; -MODULE_DEVICE_TABLE(of, sof_of_imx8ulp_ids); - -/* DT driver definition */ -static struct platform_driver snd_sof_of_imx8ulp_driver = { - .probe = sof_of_probe, - .remove = sof_of_remove, - .driver = { - .name = "sof-audio-of-imx8ulp", - .pm = &sof_of_pm, - .of_match_table = sof_of_imx8ulp_ids, - }, -}; -module_platform_driver(snd_sof_of_imx8ulp_driver); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("SOF support for IMX8ULP platforms"); -MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); From 6cf5df1040ba0694aea6a5edc6f31811a442ea36 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:22:46 -0500 Subject: [PATCH 092/651] ASoC: SOF: imx: add driver for the imx95 chip Add SOF support for the imx95 chip. Although the support is just for the imx95 chip, the driver is intended for all chips in the imx9 family. Note that the imx95 support could have just as easily been added to the imx8 platform driver but a new platform driver was created because the intention is to keep the families in separate drivers. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Frank Li Link: https://patch.msgid.link/20250207162246.3104-8-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- sound/soc/sof/imx/Kconfig | 9 +++ sound/soc/sof/imx/Makefile | 2 + sound/soc/sof/imx/imx9.c | 137 +++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 sound/soc/sof/imx/imx9.c diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 2edf9de2c886..327e2df94a58 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -32,4 +32,13 @@ config SND_SOC_SOF_IMX8 Say Y if you have such a device. If unsure select "N". +config SND_SOC_SOF_IMX9 + tristate "SOF support for i.MX9" + depends on IMX_DSP + select SND_SOC_SOF_IMX_COMMON + help + This adds support for Sound Open Firmware for NXP i.MX9 platforms. + Say Y if you need such a device. + If unsure select "N". + endif ## SND_SOC_SOF_IMX_TOPLEVEL diff --git a/sound/soc/sof/imx/Makefile b/sound/soc/sof/imx/Makefile index 36a3a67c6efb..74b5ecad8fe8 100644 --- a/sound/soc/sof/imx/Makefile +++ b/sound/soc/sof/imx/Makefile @@ -1,7 +1,9 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) snd-sof-imx8-y := imx8.o +snd-sof-imx9-y := imx9.o snd-sof-imx-common-y := imx-common.o obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o +obj-$(CONFIG_SND_SOC_SOF_IMX9) += snd-sof-imx9.o obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o diff --git a/sound/soc/sof/imx/imx9.c b/sound/soc/sof/imx/imx9.c new file mode 100644 index 000000000000..598675d4350a --- /dev/null +++ b/sound/soc/sof/imx/imx9.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Copyright 2025 NXP + */ + +#include + +#include "imx-common.h" + +#define IMX_SIP_SRC 0xC2000005 +#define IMX_SIP_SRC_M_RESET_ADDR_SET 0x03 + +#define IMX95_CPU_VEC_FLAGS_BOOT BIT(29) + +#define IMX_SIP_LMM 0xC200000F +#define IMX_SIP_LMM_BOOT 0x0 +#define IMX_SIP_LMM_SHUTDOWN 0x1 + +#define IMX95_M7_LM_ID 0x1 + +static struct snd_soc_dai_driver imx95_dai[] = { + IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai3", 1, 32), +}; + +static struct snd_sof_dsp_ops sof_imx9_ops; + +static int imx95_ops_init(struct snd_sof_dev *sdev) +{ + /* first copy from template */ + memcpy(&sof_imx9_ops, &sof_imx_ops, sizeof(sof_imx_ops)); + + /* ... and finally set DAI driver */ + sof_imx9_ops.drv = get_chip_info(sdev)->drv; + sof_imx9_ops.num_drv = get_chip_info(sdev)->num_drv; + + return 0; +} + +static int imx95_chip_probe(struct snd_sof_dev *sdev) +{ + struct arm_smccc_res smc_res; + struct platform_device *pdev; + struct resource *res; + + pdev = to_platform_device(sdev->dev); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); + if (!res) + return dev_err_probe(sdev->dev, -ENODEV, + "failed to fetch SRAM region\n"); + + /* set core boot reset address */ + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M_RESET_ADDR_SET, res->start, + IMX95_CPU_VEC_FLAGS_BOOT, 0, 0, 0, 0, &smc_res); + + return smc_res.a0; +} + +static int imx95_core_kick(struct snd_sof_dev *sdev) +{ + struct arm_smccc_res smc_res; + + arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_BOOT, + IMX95_M7_LM_ID, 0, 0, 0, 0, 0, &smc_res); + + return smc_res.a0; +} + +static int imx95_core_shutdown(struct snd_sof_dev *sdev) +{ + struct arm_smccc_res smc_res; + + arm_smccc_smc(IMX_SIP_LMM, IMX_SIP_LMM_SHUTDOWN, + IMX95_M7_LM_ID, 0, 0, 0, 0, 0, &smc_res); + + return smc_res.a0; +} + +static const struct imx_chip_ops imx95_chip_ops = { + .probe = imx95_chip_probe, + .core_kick = imx95_core_kick, + .core_shutdown = imx95_core_shutdown, +}; + +static struct imx_memory_info imx95_memory_regions[] = { + { .name = "sram", .reserved = false }, + { } +}; + +static const struct imx_chip_info imx95_chip_info = { + .ipc_info = { + .boot_mbox_offset = 0x6001000, + .window_offset = 0x6000000, + }, + .has_dma_reserved = true, + .memory = imx95_memory_regions, + .drv = imx95_dai, + .num_drv = ARRAY_SIZE(imx95_dai), + .ops = &imx95_chip_ops, +}; + +static struct snd_sof_of_mach sof_imx9_machs[] = { + { + .compatible = "fsl,imx95-19x19-evk", + .sof_tplg_filename = "sof-imx95-wm8962.tplg", + .drv_name = "asoc-audio-graph-card2", + }, + { + } +}; + +IMX_SOF_DEV_DESC(imx95, sof_imx9_machs, &imx95_chip_info, &sof_imx9_ops, imx95_ops_init); + +static const struct of_device_id sof_of_imx9_ids[] = { + { + .compatible = "fsl,imx95-cm7-sof", + .data = &IMX_SOF_DEV_DESC_NAME(imx95), + }, + { + }, +}; +MODULE_DEVICE_TABLE(of, sof_of_imx9_ids); + +static struct platform_driver snd_sof_of_imx9_driver = { + .probe = sof_of_probe, + .remove = sof_of_remove, + .driver = { + .name = "sof-audio-of-imx9", + .pm = &sof_of_pm, + .of_match_table = sof_of_imx9_ids, + }, +}; +module_platform_driver(snd_sof_of_imx9_driver); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("SOF driver for imx9 platforms"); +MODULE_AUTHOR("Laurentiu Mihalcea "); From 629dd55cf77bd3a8f80049150d3c05fef6d3b468 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:37:52 +0000 Subject: [PATCH 093/651] ASoC: SDCA: Minor formatting and naming tweaks Fix up some variable/struct member naming, add some missing kerneldoc and fix some minor formatting/whitespace issues. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca.h | 20 +++++------ include/sound/sdca_function.h | 64 +++++++++++++++++++++------------ sound/soc/sdca/sdca_device.c | 3 +- sound/soc/sdca/sdca_functions.c | 26 ++++++++++---- 4 files changed, 71 insertions(+), 42 deletions(-) diff --git a/include/sound/sdca.h b/include/sound/sdca.h index 973252d0adac..31b39f2297b9 100644 --- a/include/sound/sdca.h +++ b/include/sound/sdca.h @@ -17,10 +17,10 @@ struct sdw_slave; #define SDCA_MAX_FUNCTION_COUNT 8 /** - * sdca_device_desc - short descriptor for an SDCA Function - * @adr: ACPI address (used for SDCA register access) - * @type: Function topology type - * @name: human-readable string + * struct sdca_function_desc - short descriptor for an SDCA Function + * @name: Human-readable string. + * @type: Function topology type. + * @adr: ACPI address (used for SDCA register access). */ struct sdca_function_desc { const char *name; @@ -29,17 +29,17 @@ struct sdca_function_desc { }; /** - * sdca_device_data - structure containing all SDCA related information - * @sdca_interface_revision: value read from _DSD property, mainly to check - * for changes between silicon versions - * @num_functions: total number of supported SDCA functions. Invalid/unsupported + * struct sdca_device_data - structure containing all SDCA related information + * @interface_revision: Value read from _DSD property, mainly to check + * for changes between silicon versions. + * @num_functions: Total number of supported SDCA functions. Invalid/unsupported * functions will be skipped. - * @sdca_func: array of function descriptors + * @function: Array of function descriptors. */ struct sdca_device_data { u32 interface_revision; int num_functions; - struct sdca_function_desc sdca_func[SDCA_MAX_FUNCTION_COUNT]; + struct sdca_function_desc function[SDCA_MAX_FUNCTION_COUNT]; }; enum sdca_quirk { diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index c051c17903e8..1d1d3a1da52d 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -11,39 +11,57 @@ #include -/* +/** + * enum sdca_function_type - SDCA Function Type codes + * @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features. + * @SDCA_FUNCTION_TYPE_SIMPLE_AMP: Subset of SmartAmp. + * @SDCA_FUNCTION_TYPE_SMART_MIC: Smart microphone with acoustic triggers. + * @SDCA_FUNCTION_TYPE_SIMPLE_MIC: Subset of SmartMic. + * @SDCA_FUNCTION_TYPE_SPEAKER_MIC: Combination of SmartMic and SmartAmp. + * @SDCA_FUNCTION_TYPE_UAJ: 3.5mm Universal Audio jack. + * @SDCA_FUNCTION_TYPE_RJ: Retaskable jack. + * @SDCA_FUNCTION_TYPE_SIMPLE_JACK: Subset of UAJ. + * @SDCA_FUNCTION_TYPE_HID: Human Interface Device, for e.g. buttons. + * @SDCA_FUNCTION_TYPE_IMP_DEF: Implementation-defined function. + * * SDCA Function Types from SDCA specification v1.0a Section 5.1.2 - * all Function types not described are reserved + * all Function types not described are reserved. + * * Note that SIMPLE_AMP, SIMPLE_MIC and SIMPLE_JACK Function Types * are NOT defined in SDCA 1.0a, but they were defined in earlier * drafts and are planned for 1.1. */ - enum sdca_function_type { - SDCA_FUNCTION_TYPE_SMART_AMP = 0x01, /* Amplifier with protection features */ - SDCA_FUNCTION_TYPE_SIMPLE_AMP = 0x02, /* subset of SmartAmp */ - SDCA_FUNCTION_TYPE_SMART_MIC = 0x03, /* Smart microphone with acoustic triggers */ - SDCA_FUNCTION_TYPE_SIMPLE_MIC = 0x04, /* subset of SmartMic */ - SDCA_FUNCTION_TYPE_SPEAKER_MIC = 0x05, /* Combination of SmartMic and SmartAmp */ - SDCA_FUNCTION_TYPE_UAJ = 0x06, /* 3.5mm Universal Audio jack */ - SDCA_FUNCTION_TYPE_RJ = 0x07, /* Retaskable jack */ - SDCA_FUNCTION_TYPE_SIMPLE_JACK = 0x08, /* Subset of UAJ */ - SDCA_FUNCTION_TYPE_HID = 0x0A, /* Human Interface Device, for e.g. buttons */ - SDCA_FUNCTION_TYPE_IMP_DEF = 0x1F, /* Implementation-defined function */ + SDCA_FUNCTION_TYPE_SMART_AMP = 0x01, + SDCA_FUNCTION_TYPE_SIMPLE_AMP = 0x02, + SDCA_FUNCTION_TYPE_SMART_MIC = 0x03, + SDCA_FUNCTION_TYPE_SIMPLE_MIC = 0x04, + SDCA_FUNCTION_TYPE_SPEAKER_MIC = 0x05, + SDCA_FUNCTION_TYPE_UAJ = 0x06, + SDCA_FUNCTION_TYPE_RJ = 0x07, + SDCA_FUNCTION_TYPE_SIMPLE_JACK = 0x08, + SDCA_FUNCTION_TYPE_HID = 0x0A, + SDCA_FUNCTION_TYPE_IMP_DEF = 0x1F, }; /* Human-readable names used for kernel logs and Function device registration/bind */ -#define SDCA_FUNCTION_TYPE_SMART_AMP_NAME "SmartAmp" -#define SDCA_FUNCTION_TYPE_SIMPLE_AMP_NAME "SimpleAmp" -#define SDCA_FUNCTION_TYPE_SMART_MIC_NAME "SmartMic" -#define SDCA_FUNCTION_TYPE_SIMPLE_MIC_NAME "SimpleMic" -#define SDCA_FUNCTION_TYPE_SPEAKER_MIC_NAME "SpeakerMic" -#define SDCA_FUNCTION_TYPE_UAJ_NAME "UAJ" -#define SDCA_FUNCTION_TYPE_RJ_NAME "RJ" -#define SDCA_FUNCTION_TYPE_SIMPLE_NAME "SimpleJack" -#define SDCA_FUNCTION_TYPE_HID_NAME "HID" -#define SDCA_FUNCTION_TYPE_IMP_DEF_NAME "ImplementationDefined" +#define SDCA_FUNCTION_TYPE_SMART_AMP_NAME "SmartAmp" +#define SDCA_FUNCTION_TYPE_SIMPLE_AMP_NAME "SimpleAmp" +#define SDCA_FUNCTION_TYPE_SMART_MIC_NAME "SmartMic" +#define SDCA_FUNCTION_TYPE_SIMPLE_MIC_NAME "SimpleMic" +#define SDCA_FUNCTION_TYPE_SPEAKER_MIC_NAME "SpeakerMic" +#define SDCA_FUNCTION_TYPE_UAJ_NAME "UAJ" +#define SDCA_FUNCTION_TYPE_RJ_NAME "RJ" +#define SDCA_FUNCTION_TYPE_SIMPLE_NAME "SimpleJack" +#define SDCA_FUNCTION_TYPE_HID_NAME "HID" +#define SDCA_FUNCTION_TYPE_IMP_DEF_NAME "ImplementationDefined" +/** + * enum sdca_entity0_controls - SDCA Controls for Entity 0 + * + * Control Selectors for Entity 0 from SDCA specification v1.0 Section + * 6.7.1.1. + */ enum sdca_entity0_controls { SDCA_CTL_ENTITY_0_COMMIT_GROUP_MASK = 0x01, SDCA_CTL_ENTITY_0_FUNCTION_SDCA_VERSION = 0x04, diff --git a/sound/soc/sdca/sdca_device.c b/sound/soc/sdca/sdca_device.c index b6399b773986..0244cdcdd109 100644 --- a/sound/soc/sdca/sdca_device.c +++ b/sound/soc/sdca/sdca_device.c @@ -48,8 +48,7 @@ static bool sdca_device_quirk_rt712_vb(struct sdw_slave *slave) return false; for (i = 0; i < slave->sdca_data.num_functions; i++) { - if (slave->sdca_data.sdca_func[i].type == - SDCA_FUNCTION_TYPE_SMART_MIC) + if (slave->sdca_data.function[i].type == SDCA_FUNCTION_TYPE_SMART_MIC) return true; } diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 38071bc838b9..00d6d044c816 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,7 @@ static int patch_sdca_function_type(u32 interface_revision, u32 *function_type) { /* * Unfortunately early SDCA specifications used different indices for Functions, - * for backwards compatibility we have to reorder the values found + * for backwards compatibility we have to reorder the values found. */ if (interface_revision < 0x0801) { switch (*function_type) { @@ -85,7 +86,7 @@ static int find_sdca_function(struct acpi_device *adev, void *data) struct fwnode_handle *control5; /* used to identify function type */ const char *function_name; u32 function_type; - int func_index; + int function_index; u64 addr; int ret; @@ -145,24 +146,35 @@ static int find_sdca_function(struct acpi_device *adev, void *data) function_name, function_type, addr); /* store results */ - func_index = sdca_data->num_functions; - sdca_data->sdca_func[func_index].adr = addr; - sdca_data->sdca_func[func_index].type = function_type; - sdca_data->sdca_func[func_index].name = function_name; + function_index = sdca_data->num_functions; + sdca_data->function[function_index].adr = addr; + sdca_data->function[function_index].type = function_type; + sdca_data->function[function_index].name = function_name; sdca_data->num_functions++; return 0; } +/** + * sdca_lookup_functions - Parse sdca_device_desc for each Function + * @slave: SoundWire slave device to be processed. + * + * Iterate through the available SDCA Functions and fill in a short + * descriptor (struct sdca_function_desc) for each function, this + * information is stored along with the SoundWire slave device and + * used for adding drivers and quirks before the devices have fully + * probed. + */ void sdca_lookup_functions(struct sdw_slave *slave) { struct device *dev = &slave->dev; struct acpi_device *adev = to_acpi_device_node(dev->fwnode); if (!adev) { - dev_info(dev, "No matching ACPI device found, ignoring peripheral\n"); + dev_info(dev, "no matching ACPI device found, ignoring peripheral\n"); return; } + acpi_dev_for_each_child(adev, find_sdca_function, &slave->sdca_data); } EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA"); From 996bf834d0b61cb5a1389356c1ed7db1230139d7 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 5 Feb 2025 11:37:53 +0000 Subject: [PATCH 094/651] ASoC: SDCA: Add code to parse Function information Add a helper function to parse all the Function and Entity information from ACPI. In SDCA each device may have several Functions and each corresponds to a specific audio capability such as say amplifier playback or microphone capture. Each Function then contains a number of Entities that represent individual parts of the audio signal chain and are linked together in a graph similar to DAPM. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca.h | 2 + include/sound/sdca_function.h | 95 +++++++++++ sound/soc/sdca/sdca_functions.c | 268 ++++++++++++++++++++++++++++++++ 3 files changed, 365 insertions(+) diff --git a/include/sound/sdca.h b/include/sound/sdca.h index 31b39f2297b9..5a5d6de78d72 100644 --- a/include/sound/sdca.h +++ b/include/sound/sdca.h @@ -18,11 +18,13 @@ struct sdw_slave; /** * struct sdca_function_desc - short descriptor for an SDCA Function + * @node: firmware node for the Function. * @name: Human-readable string. * @type: Function topology type. * @adr: ACPI address (used for SDCA register access). */ struct sdca_function_desc { + struct fwnode_handle *node; const char *name; u32 type; u8 adr; diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 1d1d3a1da52d..3f4031d285d6 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -11,6 +11,15 @@ #include +struct device; +struct sdca_function_desc; + +/* + * The addressing space for SDCA relies on 7 bits for Entities, so a + * maximum of 128 Entities per function can be represented. + */ +#define SDCA_MAX_ENTITY_COUNT 128 + /** * enum sdca_function_type - SDCA Function Type codes * @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features. @@ -90,4 +99,90 @@ enum sdca_entity0_controls { SDCA_CTL_ENTITY_0_FUNCTION_BUSY = BIT(7), }; +/** + * enum sdca_entity_type - SDCA Entity Type codes + * @SDCA_ENTITY_TYPE_IT: Input Terminal. + * @SDCA_ENTITY_TYPE_OT: Output Terminal. + * @SDCA_ENTITY_TYPE_MU: Mixer Unit. + * @SDCA_ENTITY_TYPE_SU: Selector Unit. + * @SDCA_ENTITY_TYPE_FU: Feature Unit. + * @SDCA_ENTITY_TYPE_XU: Extension Unit. + * @SDCA_ENTITY_TYPE_CS: Clock Source. + * @SDCA_ENTITY_TYPE_CX: Clock selector. + * @SDCA_ENTITY_TYPE_PDE: Power-Domain Entity. + * @SDCA_ENTITY_TYPE_GE: Group Entity. + * @SDCA_ENTITY_TYPE_SPE: Security & Privacy Entity. + * @SDCA_ENTITY_TYPE_CRU: Channel Remapping Unit. + * @SDCA_ENTITY_TYPE_UDMPU: Up-Down Mixer Processing Unit. + * @SDCA_ENTITY_TYPE_MFPU: Multi-Function Processing Unit. + * @SDCA_ENTITY_TYPE_SMPU: Smart Microphone Processing Unit. + * @SDCA_ENTITY_TYPE_SAPU: Smart Amp Processing Unit. + * @SDCA_ENTITY_TYPE_PPU: Posture Processing Unit. + * @SDCA_ENTITY_TYPE_TG: Tone Generator. + * @SDCA_ENTITY_TYPE_HIDE: Human Interface Device Entity. + * + * SDCA Entity Types from SDCA specification v1.0 Section 6.1.2 + * all Entity Types not described are reserved. + */ +enum sdca_entity_type { + SDCA_ENTITY_TYPE_IT = 0x02, + SDCA_ENTITY_TYPE_OT = 0x03, + SDCA_ENTITY_TYPE_MU = 0x05, + SDCA_ENTITY_TYPE_SU = 0x06, + SDCA_ENTITY_TYPE_FU = 0x07, + SDCA_ENTITY_TYPE_XU = 0x0A, + SDCA_ENTITY_TYPE_CS = 0x0B, + SDCA_ENTITY_TYPE_CX = 0x0C, + SDCA_ENTITY_TYPE_PDE = 0x11, + SDCA_ENTITY_TYPE_GE = 0x12, + SDCA_ENTITY_TYPE_SPE = 0x13, + SDCA_ENTITY_TYPE_CRU = 0x20, + SDCA_ENTITY_TYPE_UDMPU = 0x21, + SDCA_ENTITY_TYPE_MFPU = 0x22, + SDCA_ENTITY_TYPE_SMPU = 0x23, + SDCA_ENTITY_TYPE_SAPU = 0x24, + SDCA_ENTITY_TYPE_PPU = 0x25, + SDCA_ENTITY_TYPE_TG = 0x30, + SDCA_ENTITY_TYPE_HIDE = 0x31, +}; + +/** + * struct sdca_entity - information for one SDCA Entity + * @label: String such as "OT 12". + * @id: Identifier used for addressing. + * @type: Type code for the Entity. + * @sources: Dynamically allocated array pointing to each input Entity + * connected to this Entity. + * @num_sources: Number of sources for the Entity. + */ +struct sdca_entity { + const char *label; + int id; + enum sdca_entity_type type; + + struct sdca_entity **sources; + int num_sources; +}; + +/** + * struct sdca_function_data - top-level information for one SDCA function + * @desc: Pointer to short descriptor from initial parsing. + * @entities: Dynamically allocated array of Entities. + * @num_entities: Number of Entities reported in this Function. + * @busy_max_delay: Maximum Function busy delay in microseconds, before an + * error should be reported. + */ +struct sdca_function_data { + struct sdca_function_desc *desc; + + struct sdca_entity *entities; + int num_entities; + + unsigned int busy_max_delay; +}; + +int sdca_parse_function(struct device *dev, + struct sdca_function_desc *desc, + struct sdca_function_data *function); + #endif diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 00d6d044c816..72b82280918d 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -18,6 +18,11 @@ #include #include +/* + * Should be long enough to encompass all the MIPI DisCo properties. + */ +#define SDCA_PROPERTY_LENGTH 64 + static int patch_sdca_function_type(u32 interface_revision, u32 *function_type) { /* @@ -150,6 +155,7 @@ static int find_sdca_function(struct acpi_device *adev, void *data) sdca_data->function[function_index].adr = addr; sdca_data->function[function_index].type = function_type; sdca_data->function[function_index].name = function_name; + sdca_data->function[function_index].node = function_node; sdca_data->num_functions++; return 0; @@ -179,5 +185,267 @@ void sdca_lookup_functions(struct sdw_slave *slave) } EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA"); +static int find_sdca_entity(struct device *dev, + struct fwnode_handle *function_node, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + u32 tmp; + int ret; + + ret = fwnode_property_read_string(entity_node, "mipi-sdca-entity-label", + &entity->label); + if (ret) { + dev_err(dev, "%pfwP: entity %#x: label missing: %d\n", + function_node, entity->id, ret); + return ret; + } + + ret = fwnode_property_read_u32(entity_node, "mipi-sdca-entity-type", &tmp); + if (ret) { + dev_err(dev, "%s: type missing: %d\n", entity->label, ret); + return ret; + } + + entity->type = tmp; + + dev_info(dev, "%s: entity %#x type %#x\n", + entity->label, entity->id, entity->type); + + return 0; +} + +static int find_sdca_entities(struct device *dev, + struct fwnode_handle *function_node, + struct sdca_function_data *function) +{ + struct sdca_entity *entities; + u32 *entity_list; + int num_entities; + int i, ret; + + num_entities = fwnode_property_count_u32(function_node, + "mipi-sdca-entity-id-list"); + if (num_entities <= 0) { + dev_err(dev, "%pfwP: entity id list missing: %d\n", + function_node, num_entities); + return -EINVAL; + } else if (num_entities > SDCA_MAX_ENTITY_COUNT) { + dev_err(dev, "%pfwP: maximum number of entities exceeded\n", + function_node); + return -EINVAL; + } + + entities = devm_kcalloc(dev, num_entities, sizeof(*entities), GFP_KERNEL); + if (!entities) + return -ENOMEM; + + entity_list = kcalloc(num_entities, sizeof(*entity_list), GFP_KERNEL); + if (!entity_list) + return -ENOMEM; + + fwnode_property_read_u32_array(function_node, "mipi-sdca-entity-id-list", + entity_list, num_entities); + + for (i = 0; i < num_entities; i++) + entities[i].id = entity_list[i]; + + kfree(entity_list); + + /* now read subproperties */ + for (i = 0; i < num_entities; i++) { + char entity_property[SDCA_PROPERTY_LENGTH]; + struct fwnode_handle *entity_node; + + /* DisCo uses upper-case for hex numbers */ + snprintf(entity_property, sizeof(entity_property), + "mipi-sdca-entity-id-0x%X-subproperties", entities[i].id); + + entity_node = fwnode_get_named_child_node(function_node, entity_property); + if (!entity_node) { + dev_err(dev, "%pfwP: entity node %s not found\n", + function_node, entity_property); + return -EINVAL; + } + + ret = find_sdca_entity(dev, function_node, entity_node, &entities[i]); + fwnode_handle_put(entity_node); + if (ret) + return ret; + } + + function->num_entities = num_entities; + function->entities = entities; + + return 0; +} + +static struct sdca_entity *find_sdca_entity_by_label(struct sdca_function_data *function, + const char *entity_label) +{ + int i; + + for (i = 0; i < function->num_entities; i++) { + struct sdca_entity *entity = &function->entities[i]; + + if (!strcmp(entity->label, entity_label)) + return entity; + } + + return NULL; +} + +static int find_sdca_entity_connection(struct device *dev, + struct sdca_function_data *function, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + struct sdca_entity **pins; + int num_pins, pin; + u64 pin_list; + int i, ret; + + ret = fwnode_property_read_u64(entity_node, "mipi-sdca-input-pin-list", &pin_list); + if (ret == -EINVAL) { + /* Allow missing pin lists, assume no pins. */ + dev_warn(dev, "%s: missing pin list\n", entity->label); + return 0; + } else if (ret) { + dev_err(dev, "%s: failed to read pin list: %d\n", entity->label, ret); + return ret; + } else if (pin_list & BIT(0)) { + /* + * Each bit set in the pin-list refers to an entity_id in this + * Function. Entity 0 is an illegal connection since it is used + * for Function-level configurations. + */ + dev_err(dev, "%s: pin 0 used as input\n", entity->label); + return -EINVAL; + } else if (!pin_list) { + return 0; + } + + num_pins = hweight64(pin_list); + pins = devm_kcalloc(dev, num_pins, sizeof(*pins), GFP_KERNEL); + if (!pins) + return -ENOMEM; + + i = 0; + for_each_set_bit(pin, (unsigned long *)&pin_list, BITS_PER_TYPE(pin_list)) { + char pin_property[SDCA_PROPERTY_LENGTH]; + struct fwnode_handle *connected_node; + struct sdca_entity *connected_entity; + const char *connected_label; + + snprintf(pin_property, sizeof(pin_property), "mipi-sdca-input-pin-%d", pin); + + connected_node = fwnode_get_named_child_node(entity_node, pin_property); + if (!connected_node) { + dev_err(dev, "%s: pin node %s not found\n", + entity->label, pin_property); + return -EINVAL; + } + + ret = fwnode_property_read_string(connected_node, "mipi-sdca-entity-label", + &connected_label); + if (ret) { + dev_err(dev, "%s: pin %d label missing: %d\n", + entity->label, pin, ret); + fwnode_handle_put(connected_node); + return ret; + } + + connected_entity = find_sdca_entity_by_label(function, connected_label); + if (!connected_entity) { + dev_err(dev, "%s: failed to find entity with label %s\n", + entity->label, connected_label); + fwnode_handle_put(connected_node); + return -EINVAL; + } + + pins[i] = connected_entity; + + dev_info(dev, "%s -> %s\n", connected_entity->label, entity->label); + + i++; + fwnode_handle_put(connected_node); + } + + entity->num_sources = num_pins; + entity->sources = pins; + + return 0; +} + +static int find_sdca_connections(struct device *dev, + struct fwnode_handle *function_node, + struct sdca_function_data *function) +{ + int i; + + for (i = 0; i < function->num_entities; i++) { + struct sdca_entity *entity = &function->entities[i]; + char entity_property[SDCA_PROPERTY_LENGTH]; + struct fwnode_handle *entity_node; + int ret; + + /* DisCo uses upper-case for hex numbers */ + snprintf(entity_property, sizeof(entity_property), + "mipi-sdca-entity-id-0x%X-subproperties", + entity->id); + + entity_node = fwnode_get_named_child_node(function_node, entity_property); + if (!entity_node) { + dev_err(dev, "%pfwP: entity node %s not found\n", + function_node, entity_property); + return -EINVAL; + } + + ret = find_sdca_entity_connection(dev, function, entity_node, entity); + fwnode_handle_put(entity_node); + if (ret) + return ret; + } + + return 0; +} + +/** + * sdca_parse_function - parse ACPI DisCo for a Function + * @dev: Pointer to device against which function data will be allocated. + * @function_desc: Pointer to the Function short descriptor. + * @function: Pointer to the Function information, to be populated. + * + * Return: Returns 0 for success. + */ +int sdca_parse_function(struct device *dev, + struct sdca_function_desc *function_desc, + struct sdca_function_data *function) +{ + u32 tmp; + int ret; + + function->desc = function_desc; + + ret = fwnode_property_read_u32(function_desc->node, + "mipi-sdca-function-busy-max-delay", &tmp); + if (!ret) + function->busy_max_delay = tmp; + + dev_info(dev, "%pfwP: name %s delay %dus\n", function->desc->node, + function->desc->name, function->busy_max_delay); + + ret = find_sdca_entities(dev, function_desc->node, function); + if (ret) + return ret; + + ret = find_sdca_connections(dev, function_desc->node, function); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL_NS(sdca_parse_function, "SND_SOC_SDCA"); + MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SDCA library"); From 19f6748abbab8523a7b32a5e371e39d4d8d4aba5 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 5 Feb 2025 11:37:54 +0000 Subject: [PATCH 095/651] ASoC: SDCA: Parse initialization write table Each SDCA Function may contain a table of register writes that should be written out before the Function is used. Add code to parse this table from the DisCo tables in ACPI. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 20 +++++++++++ sound/soc/sdca/sdca_functions.c | 61 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 3f4031d285d6..47fc1da8e4f3 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -10,6 +10,7 @@ #define __SDCA_FUNCTION_H__ #include +#include struct device; struct sdca_function_desc; @@ -20,6 +21,11 @@ struct sdca_function_desc; */ #define SDCA_MAX_ENTITY_COUNT 128 +/* + * Sanity check on number of initialization writes, can be expanded if needed. + */ +#define SDCA_MAX_INIT_COUNT 2048 + /** * enum sdca_function_type - SDCA Function Type codes * @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features. @@ -65,6 +71,16 @@ enum sdca_function_type { #define SDCA_FUNCTION_TYPE_HID_NAME "HID" #define SDCA_FUNCTION_TYPE_IMP_DEF_NAME "ImplementationDefined" +/** + * struct sdca_init_write - a single initialization write + * @addr: Register address to be written + * @val: Single byte value to be written + */ +struct sdca_init_write { + u32 addr; + u8 val; +}; + /** * enum sdca_entity0_controls - SDCA Controls for Entity 0 * @@ -167,7 +183,9 @@ struct sdca_entity { /** * struct sdca_function_data - top-level information for one SDCA function * @desc: Pointer to short descriptor from initial parsing. + * @init_table: Pointer to a table of initialization writes. * @entities: Dynamically allocated array of Entities. + * @num_init_table: Number of initialization writes. * @num_entities: Number of Entities reported in this Function. * @busy_max_delay: Maximum Function busy delay in microseconds, before an * error should be reported. @@ -175,7 +193,9 @@ struct sdca_entity { struct sdca_function_data { struct sdca_function_desc *desc; + struct sdca_init_write *init_table; struct sdca_entity *entities; + int num_init_table; int num_entities; unsigned int busy_max_delay; diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 72b82280918d..f914ec3f86c9 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -9,6 +9,7 @@ #define dev_fmt(fmt) "%s: " fmt, __func__ #include +#include #include #include #include @@ -185,6 +186,62 @@ void sdca_lookup_functions(struct sdw_slave *slave) } EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA"); +static int find_sdca_init_table(struct device *dev, + struct fwnode_handle *function_node, + struct sdca_function_data *function) +{ + struct sdca_init_write *init_write; + int write_size = sizeof(init_write->addr) + sizeof(init_write->val); + u8 *init_list, *init_iter; + int num_init_writes; + + num_init_writes = fwnode_property_count_u8(function_node, + "mipi-sdca-function-initialization-table"); + if (!num_init_writes || num_init_writes == -EINVAL) { + return 0; + } else if (num_init_writes < 0) { + dev_err(dev, "%pfwP: failed to read initialization table: %d\n", + function_node, num_init_writes); + return num_init_writes; + } else if (num_init_writes % write_size != 0) { + dev_err(dev, "%pfwP: init table size invalid\n", function_node); + return -EINVAL; + } else if (num_init_writes > SDCA_MAX_INIT_COUNT) { + dev_err(dev, "%pfwP: maximum init table size exceeded\n", function_node); + return -EINVAL; + } + + init_write = devm_kcalloc(dev, num_init_writes / write_size, + sizeof(*init_write), GFP_KERNEL); + if (!init_write) + return -ENOMEM; + + init_list = kcalloc(num_init_writes, sizeof(*init_list), GFP_KERNEL); + if (!init_list) + return -ENOMEM; + + fwnode_property_read_u8_array(function_node, + "mipi-sdca-function-initialization-table", + init_list, num_init_writes); + + function->num_init_table = num_init_writes; + function->init_table = init_write; + + for (init_iter = init_list; init_iter < init_list + num_init_writes;) { + u32 *addr = (u32 *)init_iter; + + init_write->addr = le32_to_cpu(*addr); + init_iter += sizeof(init_write->addr); + + init_write->val = *init_iter; + init_iter += sizeof(init_write->val); + } + + kfree(init_list); + + return 0; +} + static int find_sdca_entity(struct device *dev, struct fwnode_handle *function_node, struct fwnode_handle *entity_node, @@ -435,6 +492,10 @@ int sdca_parse_function(struct device *dev, dev_info(dev, "%pfwP: name %s delay %dus\n", function->desc->node, function->desc->name, function->busy_max_delay); + ret = find_sdca_init_table(dev, function_desc->node, function); + if (ret) + return ret; + ret = find_sdca_entities(dev, function_desc->node, function); if (ret) return ret; From 9ee6d50ae4b0fe14ed70a5265a05874d41e10848 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:37:55 +0000 Subject: [PATCH 096/651] ASoC: SDCA: Add support for Entity 0 Within SDCA there is a special Entity called Entity 0 which is used to hold Function level controls. Whilst Entity 0 isn't a full SDCA Entity, it is helpful to add an sdca_entity structure for it. This will allow it to be treated identically in the code that handles SDCA Controls. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 4 ++++ sound/soc/sdca/sdca_functions.c | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 47fc1da8e4f3..a51e3a459e36 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -117,6 +117,9 @@ enum sdca_entity0_controls { /** * enum sdca_entity_type - SDCA Entity Type codes + * @SDCA_ENTITY_TYPE_ENTITY_0: Entity 0, not actually from the + * specification but useful internally as an Entity structure + * is allocated for Entity 0, to hold Entity 0 controls. * @SDCA_ENTITY_TYPE_IT: Input Terminal. * @SDCA_ENTITY_TYPE_OT: Output Terminal. * @SDCA_ENTITY_TYPE_MU: Mixer Unit. @@ -141,6 +144,7 @@ enum sdca_entity0_controls { * all Entity Types not described are reserved. */ enum sdca_entity_type { + SDCA_ENTITY_TYPE_ENTITY_0 = 0x00, SDCA_ENTITY_TYPE_IT = 0x02, SDCA_ENTITY_TYPE_OT = 0x03, SDCA_ENTITY_TYPE_MU = 0x05, diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index f914ec3f86c9..b0ca92f1bc57 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -293,7 +293,8 @@ static int find_sdca_entities(struct device *dev, return -EINVAL; } - entities = devm_kcalloc(dev, num_entities, sizeof(*entities), GFP_KERNEL); + /* Add 1 to make space for Entity 0 */ + entities = devm_kcalloc(dev, num_entities + 1, sizeof(*entities), GFP_KERNEL); if (!entities) return -ENOMEM; @@ -331,7 +332,13 @@ static int find_sdca_entities(struct device *dev, return ret; } - function->num_entities = num_entities; + /* + * Add Entity 0 at end of the array, makes it easy to skip during + * all the Entity searches involved in creating connections. + */ + entities[num_entities].label = "entity0"; + + function->num_entities = num_entities + 1; function->entities = entities; return 0; @@ -440,7 +447,8 @@ static int find_sdca_connections(struct device *dev, { int i; - for (i = 0; i < function->num_entities; i++) { + /* Entity 0 cannot have connections */ + for (i = 0; i < function->num_entities - 1; i++) { struct sdca_entity *entity = &function->entities[i]; char entity_property[SDCA_PROPERTY_LENGTH]; struct fwnode_handle *entity_node; From 42b144cb6a2d87385fa0b124c975d6cf1e3ec630 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:37:56 +0000 Subject: [PATCH 097/651] ASoC: SDCA: Add SDCA Control parsing Each SDCA Entity will contain a number of Controls, these are basically equivalent to registers. Although a single Control will only ever contain a single field. Some of these would map directly to ALSA controls once more of the SDCA class driver is implemented. These controls are parsed out of the DisCo ACPI tables. One small todo here is that each Control can have multiple sub-entries (Control Numbers), these are typically used to represent channels. Whilst support is present for these, currently the ACPI properties that would allow differing defaults for each channel are not parsed. But there is nothing here that should prevent that being added in the future. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 534 +++++++++++++++++++++++++++++++ sound/soc/sdca/sdca_functions.c | 539 ++++++++++++++++++++++++++++++++ 2 files changed, 1073 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index a51e3a459e36..64043090fe76 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -81,6 +81,342 @@ struct sdca_init_write { u8 val; }; +/** + * define SDCA_CTL_TYPE - create a unique identifier for an SDCA Control + * @ent: Entity Type code. + * @sel: Control Selector code. + * + * Sometimes there is a need to identify a type of Control, for example to + * determine what name the control should have. SDCA Selectors are reused + * across Entity types, as such it is necessary to combine both the Entity + * Type and the Control Selector to obtain a unique identifier. + */ +#define SDCA_CTL_TYPE(ent, sel) ((ent) << 8 | (sel)) + +/** + * define SDCA_CTL_TYPE_S - static version of SDCA_CTL_TYPE + * @ent: Entity name, for example IT, MFPU, etc. this string can be read + * from the last characters of the SDCA_ENTITY_TYPE_* macros. + * @sel: Control Selector name, for example MIC_BIAS, MUTE, etc. this + * string can be read from the last characters of the SDCA_CTL_*_* + * macros. + * + * Short hand to specific a Control type statically for example: + * SDAC_CTL_TYPE_S(IT, MIC_BIAS). + */ +#define SDCA_CTL_TYPE_S(ent, sel) SDCA_CTL_TYPE(SDCA_ENTITY_TYPE_##ent, \ + SDCA_CTL_##ent##_##sel) + +/** + * enum sdca_it_controls - SDCA Controls for Input Terminal + * + * Control Selectors for Input Terminal from SDCA specification v1.0 + * section 6.2.1.3. + */ +enum sdca_it_controls { + SDCA_CTL_IT_MIC_BIAS = 0x03, + SDCA_CTL_IT_USAGE = 0x04, + SDCA_CTL_IT_LATENCY = 0x08, + SDCA_CTL_IT_CLUSTERINDEX = 0x10, + SDCA_CTL_IT_DATAPORT_SELECTOR = 0x11, + SDCA_CTL_IT_MATCHING_GUID = 0x12, + SDCA_CTL_IT_KEEP_ALIVE = 0x13, + SDCA_CTL_IT_NDAI_STREAM = 0x14, + SDCA_CTL_IT_NDAI_CATEGORY = 0x15, + SDCA_CTL_IT_NDAI_CODINGTYPE = 0x16, + SDCA_CTL_IT_NDAI_PACKETTYPE = 0x17, +}; + +/** + * enum sdca_ot_controls - SDCA Controls for Output Terminal + * + * Control Selectors for Output Terminal from SDCA specification v1.0 + * section 6.2.2.3. + */ +enum sdca_ot_controls { + SDCA_CTL_OT_USAGE = 0x04, + SDCA_CTL_OT_LATENCY = 0x08, + SDCA_CTL_OT_DATAPORT_SELECTOR = 0x11, + SDCA_CTL_OT_MATCHING_GUID = 0x12, + SDCA_CTL_OT_KEEP_ALIVE = 0x13, + SDCA_CTL_OT_NDAI_STREAM = 0x14, + SDCA_CTL_OT_NDAI_CATEGORY = 0x15, + SDCA_CTL_OT_NDAI_CODINGTYPE = 0x16, + SDCA_CTL_OT_NDAI_PACKETTYPE = 0x17, +}; + +/** + * enum sdca_mu_controls - SDCA Controls for Mixer Unit + * + * Control Selectors for Mixer Unit from SDCA specification v1.0 + * section 6.3.4.2. + */ +enum sdca_mu_controls { + SDCA_CTL_MU_MIXER = 0x01, + SDCA_CTL_MU_LATENCY = 0x06, +}; + +/** + * enum sdca_su_controls - SDCA Controls for Selector Unit + * + * Control Selectors for Selector Unit from SDCA specification v1.0 + * section 6.3.8.3. + */ +enum sdca_su_controls { + SDCA_CTL_SU_SELECTOR = 0x01, + SDCA_CTL_SU_LATENCY = 0x02, +}; + +/** + * enum sdca_fu_controls - SDCA Controls for Feature Unit + * + * Control Selectors for Feature Unit from SDCA specification v1.0 + * section 6.3.2.3. + */ +enum sdca_fu_controls { + SDCA_CTL_FU_MUTE = 0x01, + SDCA_CTL_FU_CHANNEL_VOLUME = 0x02, + SDCA_CTL_FU_AGC = 0x07, + SDCA_CTL_FU_BASS_BOOST = 0x09, + SDCA_CTL_FU_LOUDNESS = 0x0A, + SDCA_CTL_FU_GAIN = 0x0B, + SDCA_CTL_FU_LATENCY = 0x10, +}; + +/** + * enum sdca_xu_controls - SDCA Controls for Extension Unit + * + * Control Selectors for Extension Unit from SDCA specification v1.0 + * section 6.3.10.3. + */ +enum sdca_xu_controls { + SDCA_CTL_XU_BYPASS = 0x01, + SDCA_CTL_XU_LATENCY = 0x06, + SDCA_CTL_XU_XU_ID = 0x07, + SDCA_CTL_XU_XU_VERSION = 0x08, + SDCA_CTL_XU_FDL_CURRENTOWNER = 0x10, + SDCA_CTL_XU_FDL_MESSAGEOFFSET = 0x12, + SDCA_CTL_XU_FDL_MESSAGELENGTH = 0x13, + SDCA_CTL_XU_FDL_STATUS = 0x14, + SDCA_CTL_XU_FDL_SET_INDEX = 0x15, + SDCA_CTL_XU_FDL_HOST_REQUEST = 0x16, +}; + +/** + * enum sdca_cs_controls - SDCA Controls for Clock Source + * + * Control Selectors for Clock Source from SDCA specification v1.0 + * section 6.4.1.3. + */ +enum sdca_cs_controls { + SDCA_CTL_CS_CLOCK_VALID = 0x02, + SDCA_CTL_CS_SAMPLERATEINDEX = 0x10, +}; + +/** + * enum sdca_cx_controls - SDCA Controls for Clock Selector + * + * Control Selectors for Clock Selector from SDCA specification v1.0 + * section 6.4.2.3. + */ +enum sdca_cx_controls { + SDCA_CTL_CX_CLOCK_SELECT = 0x01, +}; + +/** + * enum sdca_pde_controls - SDCA Controls for Power Domain Entity + * + * Control Selectors for Power Domain Entity from SDCA specification + * v1.0 section 6.5.2.2. + */ +enum sdca_pde_controls { + SDCA_CTL_PDE_REQUESTED_PS = 0x01, + SDCA_CTL_PDE_ACTUAL_PS = 0x10, +}; + +/** + * enum sdca_ge_controls - SDCA Controls for Group Unit + * + * Control Selectors for Group Unit from SDCA specification v1.0 + * section 6.5.1.4. + */ +enum sdca_ge_controls { + SDCA_CTL_GE_SELECTED_MODE = 0x01, + SDCA_CTL_GE_DETECTED_MODE = 0x02, +}; + +/** + * enum sdca_spe_controls - SDCA Controls for Security & Privacy Unit + * + * Control Selectors for Security & Privacy Unit from SDCA + * specification v1.0 Section 6.5.3.2. + */ +enum sdca_spe_controls { + SDCA_CTL_SPE_PRIVATE = 0x01, + SDCA_CTL_SPE_PRIVACY_POLICY = 0x02, + SDCA_CTL_SPE_PRIVACY_LOCKSTATE = 0x03, + SDCA_CTL_SPE_PRIVACY_OWNER = 0x04, + SDCA_CTL_SPE_AUTHTX_CURRENTOWNER = 0x10, + SDCA_CTL_SPE_AUTHTX_MESSAGEOFFSET = 0x12, + SDCA_CTL_SPE_AUTHTX_MESSAGELENGTH = 0x13, + SDCA_CTL_SPE_AUTHRX_CURRENTOWNER = 0x14, + SDCA_CTL_SPE_AUTHRX_MESSAGEOFFSET = 0x16, + SDCA_CTL_SPE_AUTHRX_MESSAGELENGTH = 0x17, +}; + +/** + * enum sdca_cru_controls - SDCA Controls for Channel Remapping Unit + * + * Control Selectors for Channel Remapping Unit from SDCA + * specification v1.0 Section 6.3.1.3. + */ +enum sdca_cru_controls { + SDCA_CTL_CRU_LATENCY = 0x06, + SDCA_CTL_CRU_CLUSTERINDEX = 0x10, +}; + +/** + * enum sdca_udmpu_controls - SDCA Controls for Up-Down Mixer Processing Unit + * + * Control Selectors for Up-Down Mixer Processing Unit from SDCA + * specification v1.0 Section 6.3.9.3. + */ +enum sdca_udmpu_controls { + SDCA_CTL_UDMPU_LATENCY = 0x06, + SDCA_CTL_UDMPU_CLUSTERINDEX = 0x10, + SDCA_CTL_UDMPU_ACOUSTIC_ENERGY_LEVEL_MONITOR = 0x11, + SDCA_CTL_UDMPU_ULTRASOUND_LOOP_GAIN = 0x12, + SDCA_CTL_UDMPU_OPAQUESET_0 = 0x18, + SDCA_CTL_UDMPU_OPAQUESET_1 = 0x19, + SDCA_CTL_UDMPU_OPAQUESET_2 = 0x1A, + SDCA_CTL_UDMPU_OPAQUESET_3 = 0x1B, + SDCA_CTL_UDMPU_OPAQUESET_4 = 0x1C, + SDCA_CTL_UDMPU_OPAQUESET_5 = 0x1D, + SDCA_CTL_UDMPU_OPAQUESET_6 = 0x1E, + SDCA_CTL_UDMPU_OPAQUESET_7 = 0x1F, + SDCA_CTL_UDMPU_OPAQUESET_8 = 0x20, + SDCA_CTL_UDMPU_OPAQUESET_9 = 0x21, + SDCA_CTL_UDMPU_OPAQUESET_10 = 0x22, + SDCA_CTL_UDMPU_OPAQUESET_11 = 0x23, + SDCA_CTL_UDMPU_OPAQUESET_12 = 0x24, + SDCA_CTL_UDMPU_OPAQUESET_13 = 0x25, + SDCA_CTL_UDMPU_OPAQUESET_14 = 0x26, + SDCA_CTL_UDMPU_OPAQUESET_15 = 0x27, + SDCA_CTL_UDMPU_OPAQUESET_16 = 0x28, + SDCA_CTL_UDMPU_OPAQUESET_17 = 0x29, + SDCA_CTL_UDMPU_OPAQUESET_18 = 0x2A, + SDCA_CTL_UDMPU_OPAQUESET_19 = 0x2B, + SDCA_CTL_UDMPU_OPAQUESET_20 = 0x2C, + SDCA_CTL_UDMPU_OPAQUESET_21 = 0x2D, + SDCA_CTL_UDMPU_OPAQUESET_22 = 0x2E, + SDCA_CTL_UDMPU_OPAQUESET_23 = 0x2F, +}; + +/** + * enum sdca_mfpu_controls - SDCA Controls for Multi-Function Processing Unit + * + * Control Selectors for Multi-Function Processing Unit from SDCA + * specification v1.0 Section 6.3.3.4. + */ +enum sdca_mfpu_controls { + SDCA_CTL_MFPU_BYPASS = 0x01, + SDCA_CTL_MFPU_ALGORITHM_READY = 0x04, + SDCA_CTL_MFPU_ALGORITHM_ENABLE = 0x05, + SDCA_CTL_MFPU_LATENCY = 0x08, + SDCA_CTL_MFPU_ALGORITHM_PREPARE = 0x09, + SDCA_CTL_MFPU_CLUSTERINDEX = 0x10, + SDCA_CTL_MFPU_CENTER_FREQUENCY_INDEX = 0x11, + SDCA_CTL_MFPU_ULTRASOUND_LEVEL = 0x12, + SDCA_CTL_MFPU_AE_NUMBER = 0x13, + SDCA_CTL_MFPU_AE_CURRENTOWNER = 0x14, + SDCA_CTL_MFPU_AE_MESSAGEOFFSET = 0x16, + SDCA_CTL_MFPU_AE_MESSAGELENGTH = 0x17, +}; + +/** + * enum sdca_smpu_controls - SDCA Controls for Smart Mic Processing Unit + * + * Control Selectors for Smart Mic Processing Unit from SDCA + * specification v1.0 Section 6.3.7.3. + */ +enum sdca_smpu_controls { + SDCA_CTL_SMPU_LATENCY = 0x06, + SDCA_CTL_SMPU_TRIGGER_ENABLE = 0x10, + SDCA_CTL_SMPU_TRIGGER_STATUS = 0x11, + SDCA_CTL_SMPU_HIST_BUFFER_MODE = 0x12, + SDCA_CTL_SMPU_HIST_BUFFER_PREAMBLE = 0x13, + SDCA_CTL_SMPU_HIST_ERROR = 0x14, + SDCA_CTL_SMPU_TRIGGER_EXTENSION = 0x15, + SDCA_CTL_SMPU_TRIGGER_READY = 0x16, + SDCA_CTL_SMPU_HIST_CURRENTOWNER = 0x18, + SDCA_CTL_SMPU_HIST_MESSAGEOFFSET = 0x1A, + SDCA_CTL_SMPU_HIST_MESSAGELENGTH = 0x1B, + SDCA_CTL_SMPU_DTODTX_CURRENTOWNER = 0x1C, + SDCA_CTL_SMPU_DTODTX_MESSAGEOFFSET = 0x1E, + SDCA_CTL_SMPU_DTODTX_MESSAGELENGTH = 0x1F, + SDCA_CTL_SMPU_DTODRX_CURRENTOWNER = 0x20, + SDCA_CTL_SMPU_DTODRX_MESSAGEOFFSET = 0x22, + SDCA_CTL_SMPU_DTODRX_MESSAGELENGTH = 0x23, +}; + +/** + * enum sdca_sapu_controls - SDCA Controls for Smart Amp Processing Unit + * + * Control Selectors for Smart Amp Processing Unit from SDCA + * specification v1.0 Section 6.3.6.3. + */ +enum sdca_sapu_controls { + SDCA_CTL_SAPU_LATENCY = 0x05, + SDCA_CTL_SAPU_PROTECTION_MODE = 0x10, + SDCA_CTL_SAPU_PROTECTION_STATUS = 0x11, + SDCA_CTL_SAPU_OPAQUESETREQ_INDEX = 0x12, + SDCA_CTL_SAPU_DTODTX_CURRENTOWNER = 0x14, + SDCA_CTL_SAPU_DTODTX_MESSAGEOFFSET = 0x16, + SDCA_CTL_SAPU_DTODTX_MESSAGELENGTH = 0x17, + SDCA_CTL_SAPU_DTODRX_CURRENTOWNER = 0x18, + SDCA_CTL_SAPU_DTODRX_MESSAGEOFFSET = 0x1A, + SDCA_CTL_SAPU_DTODRX_MESSAGELENGTH = 0x1B, +}; + +/** + * enum sdca_ppu_controls - SDCA Controls for Post Processing Unit + * + * Control Selectors for Post Processing Unit from SDCA specification + * v1.0 Section 6.3.5.3. + */ +enum sdca_ppu_controls { + SDCA_CTL_PPU_LATENCY = 0x06, + SDCA_CTL_PPU_POSTURENUMBER = 0x10, + SDCA_CTL_PPU_POSTUREEXTENSION = 0x11, + SDCA_CTL_PPU_HORIZONTALBALANCE = 0x12, + SDCA_CTL_PPU_VERTICALBALANCE = 0x13, +}; + +/** + * enum sdca_tg_controls - SDCA Controls for Tone Generator Entity + * + * Control Selectors for Tone Generator from SDCA specification v1.0 + * Section 6.5.4.4. + */ +enum sdca_tg_controls { + SDCA_CTL_TG_TONE_DIVIDER = 0x10, +}; + +/** + * enum sdca_hide_controls - SDCA Controls for HIDE Entity + * + * Control Selectors for HIDE from SDCA specification v1.0 Section + * 6.6.1.2. + */ +enum sdca_hide_controls { + SDCA_CTL_HIDE_HIDTX_CURRENTOWNER = 0x10, + SDCA_CTL_HIDE_HIDTX_MESSAGEOFFSET = 0x12, + SDCA_CTL_HIDE_HIDTX_MESSAGELENGTH = 0x13, + SDCA_CTL_HIDE_HIDRX_CURRENTOWNER = 0x14, + SDCA_CTL_HIDE_HIDRX_MESSAGEOFFSET = 0x16, + SDCA_CTL_HIDE_HIDRX_MESSAGELENGTH = 0x17, +}; + /** * enum sdca_entity0_controls - SDCA Controls for Entity 0 * @@ -115,6 +451,200 @@ enum sdca_entity0_controls { SDCA_CTL_ENTITY_0_FUNCTION_BUSY = BIT(7), }; +#define SDCA_CTL_MIC_BIAS_NAME "Mic Bias" +#define SDCA_CTL_USAGE_NAME "Usage" +#define SDCA_CTL_LATENCY_NAME "Latency" +#define SDCA_CTL_CLUSTERINDEX_NAME "Cluster Index" +#define SDCA_CTL_DATAPORT_SELECTOR_NAME "Dataport Selector" +#define SDCA_CTL_MATCHING_GUID_NAME "Matching GUID" +#define SDCA_CTL_KEEP_ALIVE_NAME "Keep Alive" +#define SDCA_CTL_NDAI_STREAM_NAME "NDAI Stream" +#define SDCA_CTL_NDAI_CATEGORY_NAME "NDAI Category" +#define SDCA_CTL_NDAI_CODINGTYPE_NAME "NDAI Coding Type" +#define SDCA_CTL_NDAI_PACKETTYPE_NAME "NDAI Packet Type" +#define SDCA_CTL_MIXER_NAME "Mixer" +#define SDCA_CTL_SELECTOR_NAME "Selector" +#define SDCA_CTL_MUTE_NAME "Mute" +#define SDCA_CTL_CHANNEL_VOLUME_NAME "Channel Volume" +#define SDCA_CTL_AGC_NAME "AGC" +#define SDCA_CTL_BASS_BOOST_NAME "Bass Boost" +#define SDCA_CTL_LOUDNESS_NAME "Loudness" +#define SDCA_CTL_GAIN_NAME "Gain" +#define SDCA_CTL_BYPASS_NAME "Bypass" +#define SDCA_CTL_XU_ID_NAME "XU ID" +#define SDCA_CTL_XU_VERSION_NAME "XU Version" +#define SDCA_CTL_FDL_CURRENTOWNER_NAME "FDL Current Owner" +#define SDCA_CTL_FDL_MESSAGEOFFSET_NAME "FDL Message Offset" +#define SDCA_CTL_FDL_MESSAGELENGTH_NAME "FDL Message Length" +#define SDCA_CTL_FDL_STATUS_NAME "FDL Status" +#define SDCA_CTL_FDL_SET_INDEX_NAME "FDL Set Index" +#define SDCA_CTL_FDL_HOST_REQUEST_NAME "FDL Host Request" +#define SDCA_CTL_CLOCK_VALID_NAME "Clock Valid" +#define SDCA_CTL_SAMPLERATEINDEX_NAME "Sample Rate Index" +#define SDCA_CTL_CLOCK_SELECT_NAME "Clock Select" +#define SDCA_CTL_REQUESTED_PS_NAME "Requested PS" +#define SDCA_CTL_ACTUAL_PS_NAME "Actual PS" +#define SDCA_CTL_SELECTED_MODE_NAME "Selected Mode" +#define SDCA_CTL_DETECTED_MODE_NAME "Detected Mode" +#define SDCA_CTL_PRIVATE_NAME "Private" +#define SDCA_CTL_PRIVACY_POLICY_NAME "Privacy Policy" +#define SDCA_CTL_PRIVACY_LOCKSTATE_NAME "Privacy Lockstate" +#define SDCA_CTL_PRIVACY_OWNER_NAME "Privacy Owner" +#define SDCA_CTL_AUTHTX_CURRENTOWNER_NAME "AuthTX Current Owner" +#define SDCA_CTL_AUTHTX_MESSAGEOFFSET_NAME "AuthTX Message Offset" +#define SDCA_CTL_AUTHTX_MESSAGELENGTH_NAME "AuthTX Message Length" +#define SDCA_CTL_AUTHRX_CURRENTOWNER_NAME "AuthRX Current Owner" +#define SDCA_CTL_AUTHRX_MESSAGEOFFSET_NAME "AuthRX Message Offset" +#define SDCA_CTL_AUTHRX_MESSAGELENGTH_NAME "AuthRX Message Length" +#define SDCA_CTL_ACOUSTIC_ENERGY_LEVEL_MONITOR_NAME "Acoustic Energy Level Monitor" +#define SDCA_CTL_ULTRASOUND_LOOP_GAIN_NAME "Ultrasound Loop Gain" +#define SDCA_CTL_OPAQUESET_0_NAME "Opaqueset 0" +#define SDCA_CTL_OPAQUESET_1_NAME "Opaqueset 1" +#define SDCA_CTL_OPAQUESET_2_NAME "Opaqueset 2" +#define SDCA_CTL_OPAQUESET_3_NAME "Opaqueset 3" +#define SDCA_CTL_OPAQUESET_4_NAME "Opaqueset 4" +#define SDCA_CTL_OPAQUESET_5_NAME "Opaqueset 5" +#define SDCA_CTL_OPAQUESET_6_NAME "Opaqueset 6" +#define SDCA_CTL_OPAQUESET_7_NAME "Opaqueset 7" +#define SDCA_CTL_OPAQUESET_8_NAME "Opaqueset 8" +#define SDCA_CTL_OPAQUESET_9_NAME "Opaqueset 9" +#define SDCA_CTL_OPAQUESET_10_NAME "Opaqueset 10" +#define SDCA_CTL_OPAQUESET_11_NAME "Opaqueset 11" +#define SDCA_CTL_OPAQUESET_12_NAME "Opaqueset 12" +#define SDCA_CTL_OPAQUESET_13_NAME "Opaqueset 13" +#define SDCA_CTL_OPAQUESET_14_NAME "Opaqueset 14" +#define SDCA_CTL_OPAQUESET_15_NAME "Opaqueset 15" +#define SDCA_CTL_OPAQUESET_16_NAME "Opaqueset 16" +#define SDCA_CTL_OPAQUESET_17_NAME "Opaqueset 17" +#define SDCA_CTL_OPAQUESET_18_NAME "Opaqueset 18" +#define SDCA_CTL_OPAQUESET_19_NAME "Opaqueset 19" +#define SDCA_CTL_OPAQUESET_20_NAME "Opaqueset 20" +#define SDCA_CTL_OPAQUESET_21_NAME "Opaqueset 21" +#define SDCA_CTL_OPAQUESET_22_NAME "Opaqueset 22" +#define SDCA_CTL_OPAQUESET_23_NAME "Opaqueset 23" +#define SDCA_CTL_ALGORITHM_READY_NAME "Algorithm Ready" +#define SDCA_CTL_ALGORITHM_ENABLE_NAME "Algorithm Enable" +#define SDCA_CTL_ALGORITHM_PREPARE_NAME "Algorithm Prepare" +#define SDCA_CTL_CENTER_FREQUENCY_INDEX_NAME "Center Frequency Index" +#define SDCA_CTL_ULTRASOUND_LEVEL_NAME "Ultrasound Level" +#define SDCA_CTL_AE_NUMBER_NAME "AE Number" +#define SDCA_CTL_AE_CURRENTOWNER_NAME "AE Current Owner" +#define SDCA_CTL_AE_MESSAGEOFFSET_NAME "AE Message Offset" +#define SDCA_CTL_AE_MESSAGELENGTH_NAME "AE Message Length" +#define SDCA_CTL_TRIGGER_ENABLE_NAME "Trigger Enable" +#define SDCA_CTL_TRIGGER_STATUS_NAME "Trigger Status" +#define SDCA_CTL_HIST_BUFFER_MODE_NAME "Hist Buffer Mode" +#define SDCA_CTL_HIST_BUFFER_PREAMBLE_NAME "Hist Buffer Preamble" +#define SDCA_CTL_HIST_ERROR_NAME "Hist Error" +#define SDCA_CTL_TRIGGER_EXTENSION_NAME "Trigger Extension" +#define SDCA_CTL_TRIGGER_READY_NAME "Trigger Ready" +#define SDCA_CTL_HIST_CURRENTOWNER_NAME "Hist Current Owner" +#define SDCA_CTL_HIST_MESSAGEOFFSET_NAME "Hist Message Offset" +#define SDCA_CTL_HIST_MESSAGELENGTH_NAME "Hist Message Length" +#define SDCA_CTL_DTODTX_CURRENTOWNER_NAME "DTODTX Current Owner" +#define SDCA_CTL_DTODTX_MESSAGEOFFSET_NAME "DTODTX Message Offset" +#define SDCA_CTL_DTODTX_MESSAGELENGTH_NAME "DTODTX Message Length" +#define SDCA_CTL_DTODRX_CURRENTOWNER_NAME "DTODRX Current Owner" +#define SDCA_CTL_DTODRX_MESSAGEOFFSET_NAME "DTODRX Message Offset" +#define SDCA_CTL_DTODRX_MESSAGELENGTH_NAME "DTODRX Message Length" +#define SDCA_CTL_PROTECTION_MODE_NAME "Protection Mode" +#define SDCA_CTL_PROTECTION_STATUS_NAME "Protection Status" +#define SDCA_CTL_OPAQUESETREQ_INDEX_NAME "Opaqueset Req Index" +#define SDCA_CTL_DTODTX_CURRENTOWNER_NAME "DTODTX Current Owner" +#define SDCA_CTL_DTODTX_MESSAGEOFFSET_NAME "DTODTX Message Offset" +#define SDCA_CTL_DTODTX_MESSAGELENGTH_NAME "DTODTX Message Length" +#define SDCA_CTL_DTODRX_CURRENTOWNER_NAME "DTODRX Current Owner" +#define SDCA_CTL_DTODRX_MESSAGEOFFSET_NAME "DTODRX Message Offset" +#define SDCA_CTL_DTODRX_MESSAGELENGTH_NAME "DTODRX Message Length" +#define SDCA_CTL_POSTURENUMBER_NAME "Posture Number" +#define SDCA_CTL_POSTUREEXTENSION_NAME "Posture Extension" +#define SDCA_CTL_HORIZONTALBALANCE_NAME "Horizontal Balance" +#define SDCA_CTL_VERTICALBALANCE_NAME "Vertical Balance" +#define SDCA_CTL_TONE_DIVIDER_NAME "Tone Divider" +#define SDCA_CTL_HIDTX_CURRENTOWNER_NAME "HIDTX Current Owner" +#define SDCA_CTL_HIDTX_MESSAGEOFFSET_NAME "HIDTX Message Offset" +#define SDCA_CTL_HIDTX_MESSAGELENGTH_NAME "HIDTX Message Length" +#define SDCA_CTL_HIDRX_CURRENTOWNER_NAME "HIDRX Current Owner" +#define SDCA_CTL_HIDRX_MESSAGEOFFSET_NAME "HIDRX Message Offset" +#define SDCA_CTL_HIDRX_MESSAGELENGTH_NAME "HIDRX Message Length" +#define SDCA_CTL_COMMIT_GROUP_MASK_NAME "Commit Group Mask" +#define SDCA_CTL_FUNCTION_SDCA_VERSION_NAME "Function SDCA Version" +#define SDCA_CTL_FUNCTION_TYPE_NAME "Function Type" +#define SDCA_CTL_FUNCTION_MANUFACTURER_ID_NAME "Function Manufacturer ID" +#define SDCA_CTL_FUNCTION_ID_NAME "Function ID" +#define SDCA_CTL_FUNCTION_VERSION_NAME "Function Version" +#define SDCA_CTL_FUNCTION_EXTENSION_ID_NAME "Function Extension ID" +#define SDCA_CTL_FUNCTION_EXTENSION_VERSION_NAME "Function Extension Version" +#define SDCA_CTL_FUNCTION_STATUS_NAME "Function Status" +#define SDCA_CTL_FUNCTION_ACTION_NAME "Function Action" +#define SDCA_CTL_DEVICE_MANUFACTURER_ID_NAME "Device Manufacturer ID" +#define SDCA_CTL_DEVICE_PART_ID_NAME "Device Part ID" +#define SDCA_CTL_DEVICE_VERSION_NAME "Device Version" +#define SDCA_CTL_DEVICE_SDCA_VERSION_NAME "Device SDCA Version" + +/** + * enum sdca_access_mode - SDCA Control access mode + * + * Access modes as described in the SDCA specification v1.0 section + * 7.1.8.2. + */ +enum sdca_access_mode { + SDCA_ACCESS_MODE_RW = 0x0, + SDCA_ACCESS_MODE_DUAL = 0x1, + SDCA_ACCESS_MODE_RW1C = 0x2, + SDCA_ACCESS_MODE_RO = 0x3, + SDCA_ACCESS_MODE_RW1S = 0x4, + SDCA_ACCESS_MODE_DC = 0x5, +}; + +/** + * enum sdca_access_layer - SDCA Control access layer + * + * Access layers as described in the SDCA specification v1.0 section + * 7.1.9. + */ +enum sdca_access_layer { + SDCA_ACCESS_LAYER_USER = 1 << 0, + SDCA_ACCESS_LAYER_APPLICATION = 1 << 1, + SDCA_ACCESS_LAYER_CLASS = 1 << 2, + SDCA_ACCESS_LAYER_PLATFORM = 1 << 3, + SDCA_ACCESS_LAYER_DEVICE = 1 << 4, + SDCA_ACCESS_LAYER_EXTENSION = 1 << 5, +}; + +/** + * struct sdca_control - information for one SDCA Control + * @label: Name for the Control, from SDCA Specification v1.0, section 7.1.7. + * @sel: Identifier used for addressing. + * @value: Holds the Control value for constants and defaults. + * @nbits: Number of bits used in the Control. + * @interrupt_position: SCDA interrupt line that will alert to changes on this + * Control. + * @cn_list: A bitmask showing the valid Control Numbers within this Control, + * Control Numbers typically represent channels. + * @mode: Access mode of the Control. + * @layers: Bitmask of access layers of the Control. + * @deferrable: Indicates if the access to the Control can be deferred. + * @has_default: Indicates the Control has a default value to be written. + * @has_fixed: Indicates the Control only supports a single value. + */ +struct sdca_control { + const char *label; + int sel; + + int value; + int nbits; + int interrupt_position; + u64 cn_list; + + enum sdca_access_mode mode; + u8 layers; + + bool deferrable; + bool has_default; + bool has_fixed; +}; + /** * enum sdca_entity_type - SDCA Entity Type codes * @SDCA_ENTITY_TYPE_ENTITY_0: Entity 0, not actually from the @@ -173,7 +703,9 @@ enum sdca_entity_type { * @type: Type code for the Entity. * @sources: Dynamically allocated array pointing to each input Entity * connected to this Entity. + * @controls: Dynamically allocated array of Controls. * @num_sources: Number of sources for the Entity. + * @num_controls: Number of Controls for the Entity. */ struct sdca_entity { const char *label; @@ -181,7 +713,9 @@ struct sdca_entity { enum sdca_entity_type type; struct sdca_entity **sources; + struct sdca_control *controls; int num_sources; + int num_controls; }; /** diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index b0ca92f1bc57..e495ccc5b4b6 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -242,6 +242,537 @@ static int find_sdca_init_table(struct device *dev, return 0; } +static const char *find_sdca_control_label(const struct sdca_entity *entity, + const struct sdca_control *control) +{ + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { + case SDCA_CTL_TYPE_S(IT, MIC_BIAS): + return SDCA_CTL_MIC_BIAS_NAME; + case SDCA_CTL_TYPE_S(IT, USAGE): + case SDCA_CTL_TYPE_S(OT, USAGE): + return SDCA_CTL_USAGE_NAME; + case SDCA_CTL_TYPE_S(IT, LATENCY): + case SDCA_CTL_TYPE_S(OT, LATENCY): + case SDCA_CTL_TYPE_S(MU, LATENCY): + case SDCA_CTL_TYPE_S(SU, LATENCY): + case SDCA_CTL_TYPE_S(FU, LATENCY): + case SDCA_CTL_TYPE_S(XU, LATENCY): + case SDCA_CTL_TYPE_S(CRU, LATENCY): + case SDCA_CTL_TYPE_S(UDMPU, LATENCY): + case SDCA_CTL_TYPE_S(MFPU, LATENCY): + case SDCA_CTL_TYPE_S(SMPU, LATENCY): + case SDCA_CTL_TYPE_S(SAPU, LATENCY): + case SDCA_CTL_TYPE_S(PPU, LATENCY): + return SDCA_CTL_LATENCY_NAME; + case SDCA_CTL_TYPE_S(IT, CLUSTERINDEX): + case SDCA_CTL_TYPE_S(CRU, CLUSTERINDEX): + case SDCA_CTL_TYPE_S(UDMPU, CLUSTERINDEX): + case SDCA_CTL_TYPE_S(MFPU, CLUSTERINDEX): + return SDCA_CTL_CLUSTERINDEX_NAME; + case SDCA_CTL_TYPE_S(IT, DATAPORT_SELECTOR): + case SDCA_CTL_TYPE_S(OT, DATAPORT_SELECTOR): + return SDCA_CTL_DATAPORT_SELECTOR_NAME; + case SDCA_CTL_TYPE_S(IT, MATCHING_GUID): + case SDCA_CTL_TYPE_S(OT, MATCHING_GUID): + case SDCA_CTL_TYPE_S(ENTITY_0, MATCHING_GUID): + return SDCA_CTL_MATCHING_GUID_NAME; + case SDCA_CTL_TYPE_S(IT, KEEP_ALIVE): + case SDCA_CTL_TYPE_S(OT, KEEP_ALIVE): + return SDCA_CTL_KEEP_ALIVE_NAME; + case SDCA_CTL_TYPE_S(IT, NDAI_STREAM): + case SDCA_CTL_TYPE_S(OT, NDAI_STREAM): + return SDCA_CTL_NDAI_STREAM_NAME; + case SDCA_CTL_TYPE_S(IT, NDAI_CATEGORY): + case SDCA_CTL_TYPE_S(OT, NDAI_CATEGORY): + return SDCA_CTL_NDAI_CATEGORY_NAME; + case SDCA_CTL_TYPE_S(IT, NDAI_CODINGTYPE): + case SDCA_CTL_TYPE_S(OT, NDAI_CODINGTYPE): + return SDCA_CTL_NDAI_CODINGTYPE_NAME; + case SDCA_CTL_TYPE_S(IT, NDAI_PACKETTYPE): + case SDCA_CTL_TYPE_S(OT, NDAI_PACKETTYPE): + return SDCA_CTL_NDAI_PACKETTYPE_NAME; + case SDCA_CTL_TYPE_S(MU, MIXER): + return SDCA_CTL_MIXER_NAME; + case SDCA_CTL_TYPE_S(SU, SELECTOR): + return SDCA_CTL_SELECTOR_NAME; + case SDCA_CTL_TYPE_S(FU, MUTE): + return SDCA_CTL_MUTE_NAME; + case SDCA_CTL_TYPE_S(FU, CHANNEL_VOLUME): + return SDCA_CTL_CHANNEL_VOLUME_NAME; + case SDCA_CTL_TYPE_S(FU, AGC): + return SDCA_CTL_AGC_NAME; + case SDCA_CTL_TYPE_S(FU, BASS_BOOST): + return SDCA_CTL_BASS_BOOST_NAME; + case SDCA_CTL_TYPE_S(FU, LOUDNESS): + return SDCA_CTL_LOUDNESS_NAME; + case SDCA_CTL_TYPE_S(FU, GAIN): + return SDCA_CTL_GAIN_NAME; + case SDCA_CTL_TYPE_S(XU, BYPASS): + case SDCA_CTL_TYPE_S(MFPU, BYPASS): + return SDCA_CTL_BYPASS_NAME; + case SDCA_CTL_TYPE_S(XU, XU_ID): + return SDCA_CTL_XU_ID_NAME; + case SDCA_CTL_TYPE_S(XU, XU_VERSION): + return SDCA_CTL_XU_VERSION_NAME; + case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): + return SDCA_CTL_FDL_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGEOFFSET): + return SDCA_CTL_FDL_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGELENGTH): + return SDCA_CTL_FDL_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(XU, FDL_STATUS): + return SDCA_CTL_FDL_STATUS_NAME; + case SDCA_CTL_TYPE_S(XU, FDL_SET_INDEX): + return SDCA_CTL_FDL_SET_INDEX_NAME; + case SDCA_CTL_TYPE_S(XU, FDL_HOST_REQUEST): + return SDCA_CTL_FDL_HOST_REQUEST_NAME; + case SDCA_CTL_TYPE_S(CS, CLOCK_VALID): + return SDCA_CTL_CLOCK_VALID_NAME; + case SDCA_CTL_TYPE_S(CS, SAMPLERATEINDEX): + return SDCA_CTL_SAMPLERATEINDEX_NAME; + case SDCA_CTL_TYPE_S(CX, CLOCK_SELECT): + return SDCA_CTL_CLOCK_SELECT_NAME; + case SDCA_CTL_TYPE_S(PDE, REQUESTED_PS): + return SDCA_CTL_REQUESTED_PS_NAME; + case SDCA_CTL_TYPE_S(PDE, ACTUAL_PS): + return SDCA_CTL_ACTUAL_PS_NAME; + case SDCA_CTL_TYPE_S(GE, SELECTED_MODE): + return SDCA_CTL_SELECTED_MODE_NAME; + case SDCA_CTL_TYPE_S(GE, DETECTED_MODE): + return SDCA_CTL_DETECTED_MODE_NAME; + case SDCA_CTL_TYPE_S(SPE, PRIVATE): + return SDCA_CTL_PRIVATE_NAME; + case SDCA_CTL_TYPE_S(SPE, PRIVACY_POLICY): + return SDCA_CTL_PRIVACY_POLICY_NAME; + case SDCA_CTL_TYPE_S(SPE, PRIVACY_LOCKSTATE): + return SDCA_CTL_PRIVACY_LOCKSTATE_NAME; + case SDCA_CTL_TYPE_S(SPE, PRIVACY_OWNER): + return SDCA_CTL_PRIVACY_OWNER_NAME; + case SDCA_CTL_TYPE_S(SPE, AUTHTX_CURRENTOWNER): + return SDCA_CTL_AUTHTX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGEOFFSET): + return SDCA_CTL_AUTHTX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGELENGTH): + return SDCA_CTL_AUTHTX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(SPE, AUTHRX_CURRENTOWNER): + return SDCA_CTL_AUTHRX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGEOFFSET): + return SDCA_CTL_AUTHRX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGELENGTH): + return SDCA_CTL_AUTHRX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(UDMPU, ACOUSTIC_ENERGY_LEVEL_MONITOR): + return SDCA_CTL_ACOUSTIC_ENERGY_LEVEL_MONITOR_NAME; + case SDCA_CTL_TYPE_S(UDMPU, ULTRASOUND_LOOP_GAIN): + return SDCA_CTL_ULTRASOUND_LOOP_GAIN_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_0): + return SDCA_CTL_OPAQUESET_0_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_1): + return SDCA_CTL_OPAQUESET_1_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_2): + return SDCA_CTL_OPAQUESET_2_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_3): + return SDCA_CTL_OPAQUESET_3_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_4): + return SDCA_CTL_OPAQUESET_4_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_5): + return SDCA_CTL_OPAQUESET_5_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_6): + return SDCA_CTL_OPAQUESET_6_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_7): + return SDCA_CTL_OPAQUESET_7_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_8): + return SDCA_CTL_OPAQUESET_8_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_9): + return SDCA_CTL_OPAQUESET_9_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_10): + return SDCA_CTL_OPAQUESET_10_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_11): + return SDCA_CTL_OPAQUESET_11_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_12): + return SDCA_CTL_OPAQUESET_12_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_13): + return SDCA_CTL_OPAQUESET_13_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_14): + return SDCA_CTL_OPAQUESET_14_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_15): + return SDCA_CTL_OPAQUESET_15_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_16): + return SDCA_CTL_OPAQUESET_16_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_17): + return SDCA_CTL_OPAQUESET_17_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_18): + return SDCA_CTL_OPAQUESET_18_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_19): + return SDCA_CTL_OPAQUESET_19_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_20): + return SDCA_CTL_OPAQUESET_20_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_21): + return SDCA_CTL_OPAQUESET_21_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_22): + return SDCA_CTL_OPAQUESET_22_NAME; + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_23): + return SDCA_CTL_OPAQUESET_23_NAME; + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_READY): + return SDCA_CTL_ALGORITHM_READY_NAME; + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_ENABLE): + return SDCA_CTL_ALGORITHM_ENABLE_NAME; + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_PREPARE): + return SDCA_CTL_ALGORITHM_PREPARE_NAME; + case SDCA_CTL_TYPE_S(MFPU, CENTER_FREQUENCY_INDEX): + return SDCA_CTL_CENTER_FREQUENCY_INDEX_NAME; + case SDCA_CTL_TYPE_S(MFPU, ULTRASOUND_LEVEL): + return SDCA_CTL_ULTRASOUND_LEVEL_NAME; + case SDCA_CTL_TYPE_S(MFPU, AE_NUMBER): + return SDCA_CTL_AE_NUMBER_NAME; + case SDCA_CTL_TYPE_S(MFPU, AE_CURRENTOWNER): + return SDCA_CTL_AE_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGEOFFSET): + return SDCA_CTL_AE_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGELENGTH): + return SDCA_CTL_AE_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_ENABLE): + return SDCA_CTL_TRIGGER_ENABLE_NAME; + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_STATUS): + return SDCA_CTL_TRIGGER_STATUS_NAME; + case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_MODE): + return SDCA_CTL_HIST_BUFFER_MODE_NAME; + case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_PREAMBLE): + return SDCA_CTL_HIST_BUFFER_PREAMBLE_NAME; + case SDCA_CTL_TYPE_S(SMPU, HIST_ERROR): + return SDCA_CTL_HIST_ERROR_NAME; + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_EXTENSION): + return SDCA_CTL_TRIGGER_EXTENSION_NAME; + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_READY): + return SDCA_CTL_TRIGGER_READY_NAME; + case SDCA_CTL_TYPE_S(SMPU, HIST_CURRENTOWNER): + return SDCA_CTL_HIST_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGEOFFSET): + return SDCA_CTL_HIST_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGELENGTH): + return SDCA_CTL_HIST_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(SMPU, DTODTX_CURRENTOWNER): + return SDCA_CTL_DTODTX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGEOFFSET): + return SDCA_CTL_DTODTX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGELENGTH): + return SDCA_CTL_DTODTX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(SMPU, DTODRX_CURRENTOWNER): + return SDCA_CTL_DTODRX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGEOFFSET): + return SDCA_CTL_DTODRX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGELENGTH): + return SDCA_CTL_DTODRX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(SAPU, PROTECTION_MODE): + return SDCA_CTL_PROTECTION_MODE_NAME; + case SDCA_CTL_TYPE_S(SAPU, PROTECTION_STATUS): + return SDCA_CTL_PROTECTION_STATUS_NAME; + case SDCA_CTL_TYPE_S(SAPU, OPAQUESETREQ_INDEX): + return SDCA_CTL_OPAQUESETREQ_INDEX_NAME; + case SDCA_CTL_TYPE_S(SAPU, DTODTX_CURRENTOWNER): + return SDCA_CTL_DTODTX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGEOFFSET): + return SDCA_CTL_DTODTX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGELENGTH): + return SDCA_CTL_DTODTX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(SAPU, DTODRX_CURRENTOWNER): + return SDCA_CTL_DTODRX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGEOFFSET): + return SDCA_CTL_DTODRX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGELENGTH): + return SDCA_CTL_DTODRX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(PPU, POSTURENUMBER): + return SDCA_CTL_POSTURENUMBER_NAME; + case SDCA_CTL_TYPE_S(PPU, POSTUREEXTENSION): + return SDCA_CTL_POSTUREEXTENSION_NAME; + case SDCA_CTL_TYPE_S(PPU, HORIZONTALBALANCE): + return SDCA_CTL_HORIZONTALBALANCE_NAME; + case SDCA_CTL_TYPE_S(PPU, VERTICALBALANCE): + return SDCA_CTL_VERTICALBALANCE_NAME; + case SDCA_CTL_TYPE_S(TG, TONE_DIVIDER): + return SDCA_CTL_TONE_DIVIDER_NAME; + case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER): + return SDCA_CTL_HIDTX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGEOFFSET): + return SDCA_CTL_HIDTX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGELENGTH): + return SDCA_CTL_HIDTX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(HIDE, HIDRX_CURRENTOWNER): + return SDCA_CTL_HIDRX_CURRENTOWNER_NAME; + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGEOFFSET): + return SDCA_CTL_HIDRX_MESSAGEOFFSET_NAME; + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGELENGTH): + return SDCA_CTL_HIDRX_MESSAGELENGTH_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, COMMIT_GROUP_MASK): + return SDCA_CTL_COMMIT_GROUP_MASK_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_SDCA_VERSION): + return SDCA_CTL_FUNCTION_SDCA_VERSION_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_TYPE): + return SDCA_CTL_FUNCTION_TYPE_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_MANUFACTURER_ID): + return SDCA_CTL_FUNCTION_MANUFACTURER_ID_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ID): + return SDCA_CTL_FUNCTION_ID_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_VERSION): + return SDCA_CTL_FUNCTION_VERSION_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_ID): + return SDCA_CTL_FUNCTION_EXTENSION_ID_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_VERSION): + return SDCA_CTL_FUNCTION_EXTENSION_VERSION_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_STATUS): + return SDCA_CTL_FUNCTION_STATUS_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ACTION): + return SDCA_CTL_FUNCTION_ACTION_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_MANUFACTURER_ID): + return SDCA_CTL_DEVICE_MANUFACTURER_ID_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_PART_ID): + return SDCA_CTL_DEVICE_PART_ID_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_VERSION): + return SDCA_CTL_DEVICE_VERSION_NAME; + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_SDCA_VERSION): + return SDCA_CTL_DEVICE_SDCA_VERSION_NAME; + default: + return NULL; + } +} + +static unsigned int find_sdca_control_bits(const struct sdca_entity *entity, + const struct sdca_control *control) +{ + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { + case SDCA_CTL_TYPE_S(IT, LATENCY): + case SDCA_CTL_TYPE_S(OT, LATENCY): + case SDCA_CTL_TYPE_S(MU, LATENCY): + case SDCA_CTL_TYPE_S(SU, LATENCY): + case SDCA_CTL_TYPE_S(FU, LATENCY): + case SDCA_CTL_TYPE_S(XU, LATENCY): + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(CRU, LATENCY): + case SDCA_CTL_TYPE_S(UDMPU, LATENCY): + case SDCA_CTL_TYPE_S(MFPU, LATENCY): + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SMPU, LATENCY): + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SAPU, LATENCY): + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(PPU, LATENCY): + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGELENGTH): + return 32; + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_MANUFACTURER_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_MANUFACTURER_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_PART_ID): + case SDCA_CTL_TYPE_S(IT, DATAPORT_SELECTOR): + case SDCA_CTL_TYPE_S(OT, DATAPORT_SELECTOR): + case SDCA_CTL_TYPE_S(MU, MIXER): + case SDCA_CTL_TYPE_S(FU, CHANNEL_VOLUME): + case SDCA_CTL_TYPE_S(FU, GAIN): + case SDCA_CTL_TYPE_S(XU, XU_ID): + case SDCA_CTL_TYPE_S(UDMPU, ACOUSTIC_ENERGY_LEVEL_MONITOR): + case SDCA_CTL_TYPE_S(UDMPU, ULTRASOUND_LOOP_GAIN): + case SDCA_CTL_TYPE_S(MFPU, ULTRASOUND_LEVEL): + case SDCA_CTL_TYPE_S(PPU, HORIZONTALBALANCE): + case SDCA_CTL_TYPE_S(PPU, VERTICALBALANCE): + return 16; + case SDCA_CTL_TYPE_S(FU, MUTE): + case SDCA_CTL_TYPE_S(FU, AGC): + case SDCA_CTL_TYPE_S(FU, BASS_BOOST): + case SDCA_CTL_TYPE_S(FU, LOUDNESS): + case SDCA_CTL_TYPE_S(XU, BYPASS): + case SDCA_CTL_TYPE_S(MFPU, BYPASS): + return 1; + default: + return 8; + } +} + +/* + * TODO: Add support for -cn- properties, allowing different channels to have + * different defaults etc. + */ +static int find_sdca_entity_control(struct device *dev, struct sdca_entity *entity, + struct fwnode_handle *control_node, + struct sdca_control *control) +{ + u32 tmp; + int ret; + + ret = fwnode_property_read_u32(control_node, "mipi-sdca-control-access-mode", &tmp); + if (ret) { + dev_err(dev, "%s: control %#x: access mode missing: %d\n", + entity->label, control->sel, ret); + return ret; + } + + control->mode = tmp; + + ret = fwnode_property_read_u32(control_node, "mipi-sdca-control-access-layer", &tmp); + if (ret) { + dev_err(dev, "%s: control %#x: access layer missing: %d\n", + entity->label, control->sel, ret); + return ret; + } + + control->layers = tmp; + + switch (control->mode) { + case SDCA_ACCESS_MODE_DC: + ret = fwnode_property_read_u32(control_node, + "mipi-sdca-control-dc-value", + &tmp); + if (ret) { + dev_err(dev, "%s: control %#x: dc value missing: %d\n", + entity->label, control->sel, ret); + return ret; + } + + control->value = tmp; + control->has_fixed = true; + break; + case SDCA_ACCESS_MODE_RW: + case SDCA_ACCESS_MODE_DUAL: + ret = fwnode_property_read_u32(control_node, + "mipi-sdca-control-default-value", + &tmp); + if (!ret) { + control->value = tmp; + control->has_default = true; + } + + ret = fwnode_property_read_u32(control_node, + "mipi-sdca-control-fixed-value", + &tmp); + if (!ret) { + if (control->has_default && control->value != tmp) { + dev_err(dev, + "%s: control %#x: default and fixed value don't match\n", + entity->label, control->sel); + return -EINVAL; + } + + control->value = tmp; + control->has_fixed = true; + } + + control->deferrable = fwnode_property_read_bool(control_node, + "mipi-sdca-control-deferrable"); + break; + default: + break; + } + + ret = fwnode_property_read_u64(control_node, "mipi-sdca-control-cn-list", + &control->cn_list); + if (ret == -EINVAL) { + /* Spec allows not specifying cn-list if only the first number is used */ + control->cn_list = 0x1; + } else if (ret || !control->cn_list) { + dev_err(dev, "%s: control %#x: cn list missing: %d\n", + entity->label, control->sel, ret); + return ret; + } + + ret = fwnode_property_read_u32(control_node, + "mipi-sdca-control-interrupt-position", + &tmp); + if (!ret) + control->interrupt_position = tmp; + + control->label = find_sdca_control_label(entity, control); + if (!control->label) { + dev_err(dev, "%s: control %#x: name not found\n", + entity->label, control->sel); + return -EINVAL; + } + + control->nbits = find_sdca_control_bits(entity, control); + + dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d value %#x %s\n", + entity->label, control->label, control->sel, + control->mode, control->layers, control->cn_list, + control->interrupt_position, control->value, + control->deferrable ? "deferrable" : ""); + + return 0; +} + +static int find_sdca_entity_controls(struct device *dev, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + struct sdca_control *controls; + int num_controls; + u64 control_list; + int control_sel; + int i, ret; + + ret = fwnode_property_read_u64(entity_node, "mipi-sdca-control-list", &control_list); + if (ret == -EINVAL) { + /* Allow missing control lists, assume no controls. */ + dev_warn(dev, "%s: missing control list\n", entity->label); + return 0; + } else if (ret) { + dev_err(dev, "%s: failed to read control list: %d\n", entity->label, ret); + return ret; + } else if (!control_list) { + return 0; + } + + num_controls = hweight64(control_list); + controls = devm_kcalloc(dev, num_controls, sizeof(*controls), GFP_KERNEL); + if (!controls) + return -ENOMEM; + + i = 0; + for_each_set_bit(control_sel, (unsigned long *)&control_list, + BITS_PER_TYPE(control_list)) { + struct fwnode_handle *control_node; + char control_property[SDCA_PROPERTY_LENGTH]; + + /* DisCo uses upper-case for hex numbers */ + snprintf(control_property, sizeof(control_property), + "mipi-sdca-control-0x%X-subproperties", control_sel); + + control_node = fwnode_get_named_child_node(entity_node, control_property); + if (!control_node) { + dev_err(dev, "%s: control node %s not found\n", + entity->label, control_property); + return -EINVAL; + } + + controls[i].sel = control_sel; + + ret = find_sdca_entity_control(dev, entity, control_node, &controls[i]); + fwnode_handle_put(control_node); + if (ret) + return ret; + + i++; + } + + entity->num_controls = num_controls; + entity->controls = controls; + + return 0; +} + static int find_sdca_entity(struct device *dev, struct fwnode_handle *function_node, struct fwnode_handle *entity_node, @@ -269,6 +800,10 @@ static int find_sdca_entity(struct device *dev, dev_info(dev, "%s: entity %#x type %#x\n", entity->label, entity->id, entity->type); + ret = find_sdca_entity_controls(dev, entity_node, entity); + if (ret) + return ret; + return 0; } @@ -338,6 +873,10 @@ static int find_sdca_entities(struct device *dev, */ entities[num_entities].label = "entity0"; + ret = find_sdca_entity_controls(dev, function_node, &entities[num_entities]); + if (ret) + return ret; + function->num_entities = num_entities + 1; function->entities = entities; From 64fb5af1d1bbcf1b808e9bb092b22fa1b691ae63 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:37:57 +0000 Subject: [PATCH 098/651] ASoC: SDCA: Add parsing for Control range structures DisCo/SDCA contains small buffers of data that hold ranges of valid values for the various SDCA Controls. Add support for parsing these from ACPI. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 14 ++++++++++ sound/soc/sdca/sdca_functions.c | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 64043090fe76..769ae6841064 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -612,6 +612,18 @@ enum sdca_access_layer { SDCA_ACCESS_LAYER_EXTENSION = 1 << 5, }; +/** + * struct sdca_control_range - SDCA Control range table + * @cols: Number of columns in the range table. + * @rows: Number of rows in the range table. + * @data: Array of values contained in the range table. + */ +struct sdca_control_range { + unsigned int cols; + unsigned int rows; + u32 *data; +}; + /** * struct sdca_control - information for one SDCA Control * @label: Name for the Control, from SDCA Specification v1.0, section 7.1.7. @@ -622,6 +634,7 @@ enum sdca_access_layer { * Control. * @cn_list: A bitmask showing the valid Control Numbers within this Control, * Control Numbers typically represent channels. + * @range: Buffer describing valid range of values for the Control. * @mode: Access mode of the Control. * @layers: Bitmask of access layers of the Control. * @deferrable: Indicates if the access to the Control can be deferred. @@ -637,6 +650,7 @@ struct sdca_control { int interrupt_position; u64 cn_list; + struct sdca_control_range range; enum sdca_access_mode mode; u8 layers; diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index e495ccc5b4b6..d65b413f6d2f 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -603,6 +603,44 @@ static unsigned int find_sdca_control_bits(const struct sdca_entity *entity, } } +static int find_sdca_control_range(struct device *dev, + struct fwnode_handle *control_node, + struct sdca_control_range *range) +{ + u8 *range_list; + int num_range; + u16 *limits; + int i; + + num_range = fwnode_property_count_u8(control_node, "mipi-sdca-control-range"); + if (!num_range || num_range == -EINVAL) + return 0; + else if (num_range < 0) + return num_range; + + range_list = devm_kcalloc(dev, num_range, sizeof(*range_list), GFP_KERNEL); + if (!range_list) + return -ENOMEM; + + fwnode_property_read_u8_array(control_node, "mipi-sdca-control-range", + range_list, num_range); + + limits = (u16 *)range_list; + + range->cols = le16_to_cpu(limits[0]); + range->rows = le16_to_cpu(limits[1]); + range->data = (u32 *)&limits[2]; + + num_range = (num_range - (2 * sizeof(*limits))) / sizeof(*range->data); + if (num_range != range->cols * range->rows) + return -EINVAL; + + for (i = 0; i < num_range; i++) + range->data[i] = le32_to_cpu(range->data[i]); + + return 0; +} + /* * TODO: Add support for -cn- properties, allowing different channels to have * different defaults etc. @@ -678,6 +716,13 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti break; } + ret = find_sdca_control_range(dev, control_node, &control->range); + if (ret) { + dev_err(dev, "%s: control %#x: range missing: %d\n", + entity->label, control->sel, ret); + return ret; + } + ret = fwnode_property_read_u64(control_node, "mipi-sdca-control-cn-list", &control->cn_list); if (ret == -EINVAL) { From f87c2a275033120e15213f3d65234d98e726c4b7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:37:58 +0000 Subject: [PATCH 099/651] ASoC: SDCA: Add Channel Cluster parsing Within SDCA collections of Channels are referred to as Clusters, each Channel within a Cluster can have various properties attached to it. For example a stereo audio stream, would have a Cluster with 2 Channels one marked as left and the other as right. Various Clusters are specified in DisCo/ACPI and controls then allow the class driver to select between these channel configurations. Add support for parsing these Cluster definitions. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-8-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 170 ++++++++++++++++++++++++++++++++ sound/soc/sdca/sdca_functions.c | 165 +++++++++++++++++++++++++++++++ 2 files changed, 335 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index 769ae6841064..bc6e12b2211d 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -26,6 +26,18 @@ struct sdca_function_desc; */ #define SDCA_MAX_INIT_COUNT 2048 +/* + * The Cluster IDs are 16-bit, so a maximum of 65535 Clusters per + * function can be represented, however limit this to a slightly + * more reasonable value. Can be expanded if needed. + */ +#define SDCA_MAX_CLUSTER_COUNT 256 + +/* + * Sanity check on number of channels per Cluster, can be expanded if needed. + */ +#define SDCA_MAX_CHANNEL_COUNT 32 + /** * enum sdca_function_type - SDCA Function Type codes * @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features. @@ -732,13 +744,169 @@ struct sdca_entity { int num_controls; }; +/** + * enum sdca_channel_purpose - SDCA Channel Purpose code + * + * Channel Purpose codes as described in the SDCA specification v1.0 + * section 11.4.3. + */ +enum sdca_channel_purpose { + /* Table 210 - Purpose */ + SDCA_CHAN_PURPOSE_GENERIC_AUDIO = 0x01, + SDCA_CHAN_PURPOSE_VOICE = 0x02, + SDCA_CHAN_PURPOSE_SPEECH = 0x03, + SDCA_CHAN_PURPOSE_AMBIENT = 0x04, + SDCA_CHAN_PURPOSE_REFERENCE = 0x05, + SDCA_CHAN_PURPOSE_ULTRASOUND = 0x06, + SDCA_CHAN_PURPOSE_SENSE = 0x08, + SDCA_CHAN_PURPOSE_SILENCE = 0xFE, + SDCA_CHAN_PURPOSE_NON_AUDIO = 0xFF, + /* Table 211 - Amp Sense */ + SDCA_CHAN_PURPOSE_SENSE_V1 = 0x09, + SDCA_CHAN_PURPOSE_SENSE_V2 = 0x0A, + SDCA_CHAN_PURPOSE_SENSE_V12_INTERLEAVED = 0x10, + SDCA_CHAN_PURPOSE_SENSE_V21_INTERLEAVED = 0x11, + SDCA_CHAN_PURPOSE_SENSE_V12_PACKED = 0x12, + SDCA_CHAN_PURPOSE_SENSE_V21_PACKED = 0x13, + SDCA_CHAN_PURPOSE_SENSE_V1212_INTERLEAVED = 0x14, + SDCA_CHAN_PURPOSE_SENSE_V2121_INTERLEAVED = 0x15, + SDCA_CHAN_PURPOSE_SENSE_V1122_INTERLEAVED = 0x16, + SDCA_CHAN_PURPOSE_SENSE_V2211_INTERLEAVED = 0x17, + SDCA_CHAN_PURPOSE_SENSE_V1212_PACKED = 0x18, + SDCA_CHAN_PURPOSE_SENSE_V2121_PACKED = 0x19, + SDCA_CHAN_PURPOSE_SENSE_V1122_PACKED = 0x1A, + SDCA_CHAN_PURPOSE_SENSE_V2211_PACKED = 0x1B, +}; + +/** + * enum sdca_channel_relationship - SDCA Channel Relationship code + * + * Channel Relationship codes as described in the SDCA specification + * v1.0 section 11.4.2. + */ +enum sdca_channel_relationship { + /* Table 206 - Streaming */ + SDCA_CHAN_REL_UNDEFINED = 0x00, + SDCA_CHAN_REL_GENERIC_MONO = 0x01, + SDCA_CHAN_REL_GENERIC_LEFT = 0x02, + SDCA_CHAN_REL_GENERIC_RIGHT = 0x03, + SDCA_CHAN_REL_GENERIC_TOP = 0x48, + SDCA_CHAN_REL_GENERIC_BOTTOM = 0x49, + SDCA_CHAN_REL_CAPTURE_DIRECT = 0x4E, + SDCA_CHAN_REL_RENDER_DIRECT = 0x4F, + SDCA_CHAN_REL_FRONT_LEFT = 0x0B, + SDCA_CHAN_REL_FRONT_RIGHT = 0x0C, + SDCA_CHAN_REL_FRONT_CENTER = 0x0D, + SDCA_CHAN_REL_SIDE_LEFT = 0x12, + SDCA_CHAN_REL_SIDE_RIGHT = 0x13, + SDCA_CHAN_REL_BACK_LEFT = 0x16, + SDCA_CHAN_REL_BACK_RIGHT = 0x17, + SDCA_CHAN_REL_LOW_FREQUENCY_EFFECTS = 0x43, + SDCA_CHAN_REL_SOUNDWIRE_MIC = 0x55, + SDCA_CHAN_REL_SENSE_TRANSDUCER_1 = 0x58, + SDCA_CHAN_REL_SENSE_TRANSDUCER_2 = 0x59, + SDCA_CHAN_REL_SENSE_TRANSDUCER_12 = 0x5A, + SDCA_CHAN_REL_SENSE_TRANSDUCER_21 = 0x5B, + SDCA_CHAN_REL_ECHOREF_NONE = 0x70, + SDCA_CHAN_REL_ECHOREF_1 = 0x71, + SDCA_CHAN_REL_ECHOREF_2 = 0x72, + SDCA_CHAN_REL_ECHOREF_3 = 0x73, + SDCA_CHAN_REL_ECHOREF_4 = 0x74, + SDCA_CHAN_REL_ECHOREF_ALL = 0x75, + SDCA_CHAN_REL_ECHOREF_LFE_ALL = 0x76, + /* Table 207 - Speaker */ + SDCA_CHAN_REL_PRIMARY_TRANSDUCER = 0x50, + SDCA_CHAN_REL_SECONDARY_TRANSDUCER = 0x51, + SDCA_CHAN_REL_TERTIARY_TRANSDUCER = 0x52, + SDCA_CHAN_REL_LOWER_LEFT_ALLTRANSDUCER = 0x60, + SDCA_CHAN_REL_LOWER_RIGHT_ALLTRANSDUCER = 0x61, + SDCA_CHAN_REL_UPPER_LEFT_ALLTRANSDUCER = 0x62, + SDCA_CHAN_REL_UPPER_RIGHT_ALLTRANSDUCER = 0x63, + SDCA_CHAN_REL_LOWER_LEFT_PRIMARY = 0x64, + SDCA_CHAN_REL_LOWER_RIGHT_PRIMARY = 0x65, + SDCA_CHAN_REL_UPPER_LEFT_PRIMARY = 0x66, + SDCA_CHAN_REL_UPPER_RIGHT_PRIMARY = 0x67, + SDCA_CHAN_REL_LOWER_LEFT_SECONDARY = 0x68, + SDCA_CHAN_REL_LOWER_RIGHT_SECONDARY = 0x69, + SDCA_CHAN_REL_UPPER_LEFT_SECONDARY = 0x6A, + SDCA_CHAN_REL_UPPER_RIGHT_SECONDARY = 0x6B, + SDCA_CHAN_REL_LOWER_LEFT_TERTIARY = 0x6C, + SDCA_CHAN_REL_LOWER_RIGHT_TERTIARY = 0x6D, + SDCA_CHAN_REL_UPPER_LEFT_TERTIARY = 0x6E, + SDCA_CHAN_REL_UPPER_RIGHT_TERTIARY = 0x6F, + SDCA_CHAN_REL_DERIVED_LOWER_LEFT_PRIMARY = 0x94, + SDCA_CHAN_REL_DERIVED_LOWER_RIGHT_PRIMARY = 0x95, + SDCA_CHAN_REL_DERIVED_UPPER_LEFT_PRIMARY = 0x96, + SDCA_CHAN_REL_DERIVED_UPPER_RIGHT_PRIMARY = 0x97, + SDCA_CHAN_REL_DERIVED_LOWER_LEFT_SECONDARY = 0x98, + SDCA_CHAN_REL_DERIVED_LOWER_RIGHT_SECONDARY = 0x99, + SDCA_CHAN_REL_DERIVED_UPPER_LEFT_SECONDARY = 0x9A, + SDCA_CHAN_REL_DERIVED_UPPER_RIGHT_SECONDARY = 0x9B, + SDCA_CHAN_REL_DERIVED_LOWER_LEFT_TERTIARY = 0x9C, + SDCA_CHAN_REL_DERIVED_LOWER_RIGHT_TERTIARY = 0x9D, + SDCA_CHAN_REL_DERIVED_UPPER_LEFT_TERTIARY = 0x9E, + SDCA_CHAN_REL_DERIVED_UPPER_RIGHT_TERTIARY = 0x9F, + SDCA_CHAN_REL_DERIVED_MONO_PRIMARY = 0xA0, + SDCA_CHAN_REL_DERIVED_MONO_SECONDARY = 0xAB, + SDCA_CHAN_REL_DERIVED_MONO_TERTIARY = 0xAC, + /* Table 208 - Equipment */ + SDCA_CHAN_REL_EQUIPMENT_LEFT = 0x02, + SDCA_CHAN_REL_EQUIPMENT_RIGHT = 0x03, + SDCA_CHAN_REL_EQUIPMENT_COMBINED = 0x47, + SDCA_CHAN_REL_EQUIPMENT_TOP = 0x48, + SDCA_CHAN_REL_EQUIPMENT_BOTTOM = 0x49, + SDCA_CHAN_REL_EQUIPMENT_TOP_LEFT = 0x4A, + SDCA_CHAN_REL_EQUIPMENT_BOTTOM_LEFT = 0x4B, + SDCA_CHAN_REL_EQUIPMENT_TOP_RIGHT = 0x4C, + SDCA_CHAN_REL_EQUIPMENT_BOTTOM_RIGHT = 0x4D, + SDCA_CHAN_REL_EQUIPMENT_SILENCED_OUTPUT = 0x57, + /* Table 209 - Other */ + SDCA_CHAN_REL_ARRAY = 0x04, + SDCA_CHAN_REL_MIC = 0x53, + SDCA_CHAN_REL_RAW = 0x54, + SDCA_CHAN_REL_SILENCED_MIC = 0x56, + SDCA_CHAN_REL_MULTI_SOURCE_1 = 0x78, + SDCA_CHAN_REL_MULTI_SOURCE_2 = 0x79, + SDCA_CHAN_REL_MULTI_SOURCE_3 = 0x7A, + SDCA_CHAN_REL_MULTI_SOURCE_4 = 0x7B, +}; + +/** + * struct sdca_channel - a single Channel with a Cluster + * @id: Identifier used for addressing. + * @purpose: Indicates the purpose of the Channel, usually to give + * semantic meaning to the audio, eg. voice, ultrasound. + * @relationship: Indicates the relationship of this Channel to others + * in the Cluster, often used to identify the physical position of the + * Channel eg. left. + */ +struct sdca_channel { + int id; + enum sdca_channel_purpose purpose; + enum sdca_channel_relationship relationship; +}; + +/** + * struct sdca_cluster - information about an SDCA Channel Cluster + * @id: Identifier used for addressing. + * @num_channels: Number of Channels within this Cluster. + * @channels: Dynamically allocated array of Channels. + */ +struct sdca_cluster { + int id; + int num_channels; + struct sdca_channel *channels; +}; + /** * struct sdca_function_data - top-level information for one SDCA function * @desc: Pointer to short descriptor from initial parsing. * @init_table: Pointer to a table of initialization writes. * @entities: Dynamically allocated array of Entities. + * @clusters: Dynamically allocated array of Channel Clusters. * @num_init_table: Number of initialization writes. * @num_entities: Number of Entities reported in this Function. + * @num_clusters: Number of Channel Clusters reported in this Function. * @busy_max_delay: Maximum Function busy delay in microseconds, before an * error should be reported. */ @@ -747,8 +915,10 @@ struct sdca_function_data { struct sdca_init_write *init_table; struct sdca_entity *entities; + struct sdca_cluster *clusters; int num_init_table; int num_entities; + int num_clusters; unsigned int busy_max_delay; }; diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index d65b413f6d2f..4de25f485755 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -1059,6 +1059,167 @@ static int find_sdca_connections(struct device *dev, return 0; } +static int find_sdca_cluster_channel(struct device *dev, + struct sdca_cluster *cluster, + struct fwnode_handle *channel_node, + struct sdca_channel *channel) +{ + u32 tmp; + int ret; + + ret = fwnode_property_read_u32(channel_node, "mipi-sdca-cluster-channel-id", &tmp); + if (ret) { + dev_err(dev, "cluster %#x: missing channel id: %d\n", + cluster->id, ret); + return ret; + } + + channel->id = tmp; + + ret = fwnode_property_read_u32(channel_node, + "mipi-sdca-cluster-channel-purpose", + &tmp); + if (ret) { + dev_err(dev, "cluster %#x: channel %#x: missing purpose: %d\n", + cluster->id, channel->id, ret); + return ret; + } + + channel->purpose = tmp; + + ret = fwnode_property_read_u32(channel_node, + "mipi-sdca-cluster-channel-relationship", + &tmp); + if (ret) { + dev_err(dev, "cluster %#x: channel %#x: missing relationship: %d\n", + cluster->id, channel->id, ret); + return ret; + } + + channel->relationship = tmp; + + dev_info(dev, "cluster %#x: channel id %#x purpose %#x relationship %#x\n", + cluster->id, channel->id, channel->purpose, channel->relationship); + + return 0; +} + +static int find_sdca_cluster_channels(struct device *dev, + struct fwnode_handle *cluster_node, + struct sdca_cluster *cluster) +{ + struct sdca_channel *channels; + u32 num_channels; + int i, ret; + + ret = fwnode_property_read_u32(cluster_node, "mipi-sdca-channel-count", + &num_channels); + if (ret < 0) { + dev_err(dev, "cluster %#x: failed to read channel list: %d\n", + cluster->id, ret); + return ret; + } else if (num_channels > SDCA_MAX_CHANNEL_COUNT) { + dev_err(dev, "cluster %#x: maximum number of channels exceeded\n", + cluster->id); + return -EINVAL; + } + + channels = devm_kcalloc(dev, num_channels, sizeof(*channels), GFP_KERNEL); + if (!channels) + return -ENOMEM; + + for (i = 0; i < num_channels; i++) { + char channel_property[SDCA_PROPERTY_LENGTH]; + struct fwnode_handle *channel_node; + + /* DisCo uses upper-case for hex numbers */ + snprintf(channel_property, sizeof(channel_property), + "mipi-sdca-channel-%d-subproperties", i + 1); + + channel_node = fwnode_get_named_child_node(cluster_node, channel_property); + if (!channel_node) { + dev_err(dev, "cluster %#x: channel node %s not found\n", + cluster->id, channel_property); + return -EINVAL; + } + + ret = find_sdca_cluster_channel(dev, cluster, channel_node, &channels[i]); + fwnode_handle_put(channel_node); + if (ret) + return ret; + } + + cluster->num_channels = num_channels; + cluster->channels = channels; + + return 0; +} + +static int find_sdca_clusters(struct device *dev, + struct fwnode_handle *function_node, + struct sdca_function_data *function) +{ + struct sdca_cluster *clusters; + int num_clusters; + u32 *cluster_list; + int i, ret; + + num_clusters = fwnode_property_count_u32(function_node, "mipi-sdca-cluster-id-list"); + if (!num_clusters || num_clusters == -EINVAL) { + return 0; + } else if (num_clusters < 0) { + dev_err(dev, "%pfwP: failed to read cluster id list: %d\n", + function_node, num_clusters); + return num_clusters; + } else if (num_clusters > SDCA_MAX_CLUSTER_COUNT) { + dev_err(dev, "%pfwP: maximum number of clusters exceeded\n", function_node); + return -EINVAL; + } + + clusters = devm_kcalloc(dev, num_clusters, sizeof(*clusters), GFP_KERNEL); + if (!clusters) + return -ENOMEM; + + cluster_list = kcalloc(num_clusters, sizeof(*cluster_list), GFP_KERNEL); + if (!cluster_list) + return -ENOMEM; + + fwnode_property_read_u32_array(function_node, "mipi-sdca-cluster-id-list", + cluster_list, num_clusters); + + for (i = 0; i < num_clusters; i++) + clusters[i].id = cluster_list[i]; + + kfree(cluster_list); + + /* now read subproperties */ + for (i = 0; i < num_clusters; i++) { + char cluster_property[SDCA_PROPERTY_LENGTH]; + struct fwnode_handle *cluster_node; + + /* DisCo uses upper-case for hex numbers */ + snprintf(cluster_property, sizeof(cluster_property), + "mipi-sdca-cluster-id-0x%X-subproperties", clusters[i].id); + + cluster_node = fwnode_get_named_child_node(function_node, cluster_property); + if (!cluster_node) { + dev_err(dev, "%pfwP: cluster node %s not found\n", + function_node, cluster_property); + return -EINVAL; + } + + ret = find_sdca_cluster_channels(dev, cluster_node, &clusters[i]); + fwnode_handle_put(cluster_node); + if (ret) + return ret; + } + + function->num_clusters = num_clusters; + function->clusters = clusters; + + return 0; +} + /** * sdca_parse_function - parse ACPI DisCo for a Function * @dev: Pointer to device against which function data will be allocated. @@ -1096,6 +1257,10 @@ int sdca_parse_function(struct device *dev, if (ret) return ret; + ret = find_sdca_clusters(dev, function_desc->node, function); + if (ret < 0) + return ret; + return 0; } EXPORT_SYMBOL_NS(sdca_parse_function, "SND_SOC_SDCA"); From 5c93b20f6de4478e1fbcfb38eb46738bca74180e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:37:59 +0000 Subject: [PATCH 100/651] ASoC: SDCA: Add support for IT/OT Entity properties Add support for parsing the Input/Output Terminal Entity properties from DisCo/ACPI. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250205113801.3699902-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 117 +++++++++++++++++++++++++++++ sound/soc/sdca/sdca_functions.c | 127 ++++++++++++++++++++++++++++++++ 2 files changed, 244 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index bc6e12b2211d..6cb5ab79ee54 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -13,6 +13,7 @@ #include struct device; +struct sdca_entity; struct sdca_function_desc; /* @@ -671,6 +672,118 @@ struct sdca_control { bool has_fixed; }; +/** + * enum sdca_terminal_type - SDCA Terminal Types + * + * Indicate what a Terminal Entity is used for, see in section 6.2.3 + * of the SDCA v1.0 specification. + */ +enum sdca_terminal_type { + /* Table 77 - Data Port*/ + SDCA_TERM_TYPE_GENERIC = 0x101, + SDCA_TERM_TYPE_ULTRASOUND = 0x180, + SDCA_TERM_TYPE_CAPTURE_DIRECT_PCM_MIC = 0x181, + SDCA_TERM_TYPE_RAW_PDM_MIC = 0x182, + SDCA_TERM_TYPE_SPEECH = 0x183, + SDCA_TERM_TYPE_VOICE = 0x184, + SDCA_TERM_TYPE_SECONDARY_PCM_MIC = 0x185, + SDCA_TERM_TYPE_ACOUSTIC_CONTEXT_AWARENESS = 0x186, + SDCA_TERM_TYPE_DTOD_STREAM = 0x187, + SDCA_TERM_TYPE_REFERENCE_STREAM = 0x188, + SDCA_TERM_TYPE_SENSE_CAPTURE = 0x189, + SDCA_TERM_TYPE_STREAMING_MIC = 0x18A, + SDCA_TERM_TYPE_OPTIMIZATION_STREAM = 0x190, + SDCA_TERM_TYPE_PDM_RENDER_STREAM = 0x191, + SDCA_TERM_TYPE_COMPANION_DATA = 0x192, + /* Table 78 - Transducer */ + SDCA_TERM_TYPE_MICROPHONE_TRANSDUCER = 0x201, + SDCA_TERM_TYPE_MICROPHONE_ARRAY_TRANSDUCER = 0x205, + SDCA_TERM_TYPE_PRIMARY_FULL_RANGE_SPEAKER = 0x380, + SDCA_TERM_TYPE_PRIMARY_LFE_SPEAKER = 0x381, + SDCA_TERM_TYPE_PRIMARY_TWEETER_SPEAKER = 0x382, + SDCA_TERM_TYPE_PRIMARY_ULTRASOUND_SPEAKER = 0x383, + SDCA_TERM_TYPE_SECONDARY_FULL_RANGE_SPEAKER = 0x390, + SDCA_TERM_TYPE_SECONDARY_LFE_SPEAKER = 0x391, + SDCA_TERM_TYPE_SECONDARY_TWEETER_SPEAKER = 0x392, + SDCA_TERM_TYPE_SECONDARY_ULTRASOUND_SPEAKER = 0x393, + SDCA_TERM_TYPE_TERTIARY_FULL_RANGE_SPEAKER = 0x3A0, + SDCA_TERM_TYPE_TERTIARY_LFE_SPEAKER = 0x3A1, + SDCA_TERM_TYPE_TERTIARY_TWEETER_SPEAKER = 0x3A2, + SDCA_TERM_TYPE_TERTIARY_ULTRASOUND_SPEAKER = 0x3A3, + SDCA_TERM_TYPE_SPDIF = 0x605, + SDCA_TERM_TYPE_NDAI_DISPLAY_AUDIO = 0x610, + SDCA_TERM_TYPE_NDAI_USB = 0x612, + SDCA_TERM_TYPE_NDAI_BLUETOOTH_MAIN = 0x614, + SDCA_TERM_TYPE_NDAI_BLUETOOTH_ALTERNATE = 0x615, + SDCA_TERM_TYPE_NDAI_BLUETOOTH_BOTH = 0x616, + SDCA_TERM_TYPE_LINEIN_STEREO = 0x680, + SDCA_TERM_TYPE_LINEIN_FRONT_LR = 0x681, + SDCA_TERM_TYPE_LINEIN_CENTER_LFE = 0x682, + SDCA_TERM_TYPE_LINEIN_SURROUND_LR = 0x683, + SDCA_TERM_TYPE_LINEIN_REAR_LR = 0x684, + SDCA_TERM_TYPE_LINEOUT_STEREO = 0x690, + SDCA_TERM_TYPE_LINEOUT_FRONT_LR = 0x691, + SDCA_TERM_TYPE_LINEOUT_CENTER_LFE = 0x692, + SDCA_TERM_TYPE_LINEOUT_SURROUND_LR = 0x693, + SDCA_TERM_TYPE_LINEOUT_REAR_LR = 0x694, + SDCA_TERM_TYPE_MIC_JACK = 0x6A0, + SDCA_TERM_TYPE_STEREO_JACK = 0x6B0, + SDCA_TERM_TYPE_FRONT_LR_JACK = 0x6B1, + SDCA_TERM_TYPE_CENTER_LFE_JACK = 0x6B2, + SDCA_TERM_TYPE_SURROUND_LR_JACK = 0x6B3, + SDCA_TERM_TYPE_REAR_LR_JACK = 0x6B4, + SDCA_TERM_TYPE_HEADPHONE_JACK = 0x6C0, + SDCA_TERM_TYPE_HEADSET_JACK = 0x6D0, + /* Table 79 - System */ + SDCA_TERM_TYPE_SENSE_DATA = 0x280, + SDCA_TERM_TYPE_PRIVACY_SIGNALING = 0x741, + SDCA_TERM_TYPE_PRIVACY_INDICATORS = 0x747, +}; + +/** + * enum sdca_connector_type - SDCA Connector Types + * + * Indicate the type of Connector that a Terminal Entity represents, + * see section 6.2.4 of the SDCA v1.0 specification. + */ +enum sdca_connector_type { + SDCA_CONN_TYPE_UNKNOWN = 0x00, + SDCA_CONN_TYPE_2P5MM_JACK = 0x01, + SDCA_CONN_TYPE_3P5MM_JACK = 0x02, + SDCA_CONN_TYPE_QUARTER_INCH_JACK = 0x03, + SDCA_CONN_TYPE_XLR = 0x05, + SDCA_CONN_TYPE_SPDIF_OPTICAL = 0x06, + SDCA_CONN_TYPE_RCA = 0x07, + SDCA_CONN_TYPE_DIN = 0x0E, + SDCA_CONN_TYPE_MINI_DIN = 0x0F, + SDCA_CONN_TYPE_EIAJ_OPTICAL = 0x13, + SDCA_CONN_TYPE_HDMI = 0x14, + SDCA_CONN_TYPE_DISPLAYPORT = 0x17, + SDCA_CONN_TYPE_LIGHTNING = 0x1B, + SDCA_CONN_TYPE_USB_C = 0x1E, + SDCA_CONN_TYPE_OTHER = 0xFF, +}; + +/** + * struct sdca_entity_iot - information specific to Input/Output Entities + * @clock: Pointer to the Entity providing this Terminal's clock. + * @type: Usage of the Terminal Entity. + * @connector: Physical Connector of the Terminal Entity. + * @reference: Physical Jack number of the Terminal Entity. + * @num_transducer: Number of transducers attached to the Terminal Entity. + * @is_dataport: Boolean indicating if this Terminal represents a Dataport. + */ +struct sdca_entity_iot { + struct sdca_entity *clock; + + enum sdca_terminal_type type; + enum sdca_connector_type connector; + int reference; + int num_transducer; + + bool is_dataport; +}; + /** * enum sdca_entity_type - SDCA Entity Type codes * @SDCA_ENTITY_TYPE_ENTITY_0: Entity 0, not actually from the @@ -732,6 +845,7 @@ enum sdca_entity_type { * @controls: Dynamically allocated array of Controls. * @num_sources: Number of sources for the Entity. * @num_controls: Number of Controls for the Entity. + * @iot: Input/Output Terminal specific Entity properties. */ struct sdca_entity { const char *label; @@ -742,6 +856,9 @@ struct sdca_entity { struct sdca_control *controls; int num_sources; int num_controls; + union { + struct sdca_entity_iot iot; + }; }; /** diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 4de25f485755..8a143048a0ab 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -818,6 +818,69 @@ static int find_sdca_entity_controls(struct device *dev, return 0; } +static bool find_sdca_iot_dataport(struct sdca_entity_iot *terminal) +{ + switch (terminal->type) { + case SDCA_TERM_TYPE_GENERIC: + case SDCA_TERM_TYPE_ULTRASOUND: + case SDCA_TERM_TYPE_CAPTURE_DIRECT_PCM_MIC: + case SDCA_TERM_TYPE_RAW_PDM_MIC: + case SDCA_TERM_TYPE_SPEECH: + case SDCA_TERM_TYPE_VOICE: + case SDCA_TERM_TYPE_SECONDARY_PCM_MIC: + case SDCA_TERM_TYPE_ACOUSTIC_CONTEXT_AWARENESS: + case SDCA_TERM_TYPE_DTOD_STREAM: + case SDCA_TERM_TYPE_REFERENCE_STREAM: + case SDCA_TERM_TYPE_SENSE_CAPTURE: + case SDCA_TERM_TYPE_STREAMING_MIC: + case SDCA_TERM_TYPE_OPTIMIZATION_STREAM: + case SDCA_TERM_TYPE_PDM_RENDER_STREAM: + case SDCA_TERM_TYPE_COMPANION_DATA: + return true; + default: + return false; + } +} + +static int find_sdca_entity_iot(struct device *dev, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + struct sdca_entity_iot *terminal = &entity->iot; + u32 tmp; + int ret; + + ret = fwnode_property_read_u32(entity_node, "mipi-sdca-terminal-type", &tmp); + if (ret) { + dev_err(dev, "%s: terminal type missing: %d\n", entity->label, ret); + return ret; + } + + terminal->type = tmp; + terminal->is_dataport = find_sdca_iot_dataport(terminal); + + ret = fwnode_property_read_u32(entity_node, + "mipi-sdca-terminal-reference-number", &tmp); + if (!ret) + terminal->reference = tmp; + + ret = fwnode_property_read_u32(entity_node, + "mipi-sdca-terminal-connector-type", &tmp); + if (!ret) + terminal->connector = tmp; + + ret = fwnode_property_read_u32(entity_node, + "mipi-sdca-terminal-transducer-count", &tmp); + if (!ret) + terminal->num_transducer = tmp; + + dev_info(dev, "%s: terminal type %#x ref %#x conn %#x count %d\n", + entity->label, terminal->type, terminal->reference, + terminal->connector, terminal->num_transducer); + + return 0; +} + static int find_sdca_entity(struct device *dev, struct fwnode_handle *function_node, struct fwnode_handle *entity_node, @@ -845,6 +908,17 @@ static int find_sdca_entity(struct device *dev, dev_info(dev, "%s: entity %#x type %#x\n", entity->label, entity->id, entity->type); + switch (entity->type) { + case SDCA_ENTITY_TYPE_IT: + case SDCA_ENTITY_TYPE_OT: + ret = find_sdca_entity_iot(dev, entity_node, entity); + break; + default: + break; + } + if (ret) + return ret; + ret = find_sdca_entity_controls(dev, entity_node, entity); if (ret) return ret; @@ -943,6 +1017,46 @@ static struct sdca_entity *find_sdca_entity_by_label(struct sdca_function_data * return NULL; } +static int find_sdca_entity_connection_iot(struct device *dev, + struct sdca_function_data *function, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + struct sdca_entity_iot *terminal = &entity->iot; + struct fwnode_handle *clock_node; + struct sdca_entity *clock_entity; + const char *clock_label; + int ret; + + clock_node = fwnode_get_named_child_node(entity_node, + "mipi-sdca-terminal-clock-connection"); + if (!clock_node) + return 0; + + ret = fwnode_property_read_string(clock_node, "mipi-sdca-entity-label", + &clock_label); + if (ret) { + dev_err(dev, "%s: clock label missing: %d\n", entity->label, ret); + fwnode_handle_put(clock_node); + return ret; + } + + clock_entity = find_sdca_entity_by_label(function, clock_label); + if (!clock_entity) { + dev_err(dev, "%s: failed to find clock with label %s\n", + entity->label, clock_label); + fwnode_handle_put(clock_node); + return -EINVAL; + } + + terminal->clock = clock_entity; + + dev_info(dev, "%s -> %s\n", clock_entity->label, entity->label); + + fwnode_handle_put(clock_node); + return 0; +} + static int find_sdca_entity_connection(struct device *dev, struct sdca_function_data *function, struct fwnode_handle *entity_node, @@ -953,6 +1067,19 @@ static int find_sdca_entity_connection(struct device *dev, u64 pin_list; int i, ret; + switch (entity->type) { + case SDCA_ENTITY_TYPE_IT: + case SDCA_ENTITY_TYPE_OT: + ret = find_sdca_entity_connection_iot(dev, function, + entity_node, entity); + break; + default: + ret = 0; + break; + } + if (ret) + return ret; + ret = fwnode_property_read_u64(entity_node, "mipi-sdca-input-pin-list", &pin_list); if (ret == -EINVAL) { /* Allow missing pin lists, assume no pins. */ From e80b8e5c53c30df1cba45258d10b04872b7eea67 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:38:00 +0000 Subject: [PATCH 101/651] 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; } From 9da195880f167ab7c2d595388decf783c9920121 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 5 Feb 2025 11:38:01 +0000 Subject: [PATCH 102/651] 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; From 2b360ba9a4936486380bc30d1eabceb40a714d98 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Sat, 8 Feb 2025 23:46:01 +0200 Subject: [PATCH 103/651] ALSA: hda: intel: Fix Optimus when GPU has no sound quirk_nvidia_hda() forcefully enables HDA controller on all NVIDIA GPUs, because some buggy BIOSes leave it disabled. However, some dual-GPU laptops do not have a functional HDA controller in DGPU, and BIOS disables it on purpose. After quirk_nvidia_hda() reenables this dummy HDA controller, attempting to probe it fails at azx_first_init(), which is too late to cancel the probe, as it happens in azx_probe_continue(). The sna_hda_intel driver calls azx_free() and stops the chip, however, it stays probed, and from the runtime PM point of view, the device remains active (it was set as active by the PCI subsystem on probe). It prevents vga_switcheroo from turning off the DGPU, because pci_create_device_link() syncs power management for video and audio devices. Affected devices should be added to driver_denylist to prevent them from probing early. This patch helps identify such devices by printing a warning, and also forces the device to the suspended state to allow vga_switcheroo turn off DGPU. Signed-off-by: Maxim Mikityanskiy Link: https://patch.msgid.link/20250208214602.39607-2-maxtram95@gmail.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7d7f9aac50a9..4155e010064b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1352,8 +1352,21 @@ static void azx_free(struct azx *chip) if (use_vga_switcheroo(hda)) { if (chip->disabled && hda->probe_continued) snd_hda_unlock_devices(&chip->bus); - if (hda->vga_switcheroo_registered) + if (hda->vga_switcheroo_registered) { vga_switcheroo_unregister_client(chip->pci); + + /* Some GPUs don't have sound, and azx_first_init fails, + * leaving the device probed but non-functional. As long + * as it's probed, the PCI subsystem keeps its runtime + * PM status as active. Force it to suspended (as we + * actually stop the chip) to allow GPU to suspend via + * vga_switcheroo, and print a warning. + */ + dev_warn(&pci->dev, "GPU sound probed, but not operational: please add a quirk to driver_denylist\n"); + pm_runtime_disable(&pci->dev); + pm_runtime_set_suspended(&pci->dev); + pm_runtime_enable(&pci->dev); + } } if (bus->chip_init) { From becc794c5e46f4dfca59f2385f78d83fc9e84700 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Sat, 8 Feb 2025 23:46:02 +0200 Subject: [PATCH 104/651] ALSA: hda: intel: Add Lenovo IdeaPad Z570 to probe denylist Lenovo IdeaPad Z570 with NVIDIA GeForce Ge 540M doesn't have sound on the discrete GPU. The HDA controller in DGPU is disabled by BIOS, but then reenabled by quirk_nvidia_hda(). The probe fails and ends up with the "GPU sound probed, but not operational" error. Add this laptop to DMI-based denylist to prevent probe early. DMI is used, because the audio device has zero subsystem IDs, and this entry would be too much, blocking all 540M chips: PCI_DEVICE_SUB(0x10de, 0x0bea, 0x0000, 0x0000) Also, this laptop comes in a variety of modifications with different NVIDIA GPUs, so the DMI check will cover them all. Signed-off-by: Maxim Mikityanskiy Link: https://patch.msgid.link/20250208214602.39607-3-maxtram95@gmail.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 4155e010064b..3f11f169fe4a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef CONFIG_X86 /* for snoop control */ @@ -2074,6 +2075,27 @@ static const struct pci_device_id driver_denylist[] = { {} }; +static struct pci_device_id driver_denylist_ideapad_z570[] = { + { PCI_DEVICE_SUB(0x10de, 0x0bea, 0x0000, 0x0000) }, /* NVIDIA GF108 HDA */ + {} +}; + +/* DMI-based denylist, to be used when: + * - PCI subsystem IDs are zero, impossible to distinguish from valid sound cards. + * - Different modifications of the same laptop use different GPU models. + */ +static const struct dmi_system_id driver_denylist_dmi[] = { + { + /* No HDA in NVIDIA DGPU. BIOS disables it, but quirk_nvidia_hda() reenables. */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Ideapad Z570"), + }, + .driver_data = &driver_denylist_ideapad_z570, + }, + {} +}; + static const struct hda_controller_ops pci_hda_ops = { .disable_msi_reset_irq = disable_msi_reset_irq, .position_check = azx_position_check, @@ -2084,6 +2106,7 @@ static DECLARE_BITMAP(probed_devs, SNDRV_CARDS); static int azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { + const struct dmi_system_id *dmi; struct snd_card *card; struct hda_intel *hda; struct azx *chip; @@ -2096,6 +2119,12 @@ static int azx_probe(struct pci_dev *pci, return -ENODEV; } + dmi = dmi_first_match(driver_denylist_dmi); + if (dmi && pci_match_id(dmi->driver_data, pci)) { + dev_info(&pci->dev, "Skipping the device on the DMI denylist\n"); + return -ENODEV; + } + dev = find_first_zero_bit(probed_devs, SNDRV_CARDS); if (dev >= SNDRV_CARDS) return -ENODEV; From 330cbb40bb3664a18a19760bd6dc6003d6624041 Mon Sep 17 00:00:00 2001 From: Alexey Charkov Date: Mon, 20 Jan 2025 13:01:27 +0400 Subject: [PATCH 105/651] 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 From e97d06cb4386af4e069a2dc713de70500538d0bd Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 10 Feb 2025 12:59:37 +0100 Subject: [PATCH 106/651] 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; } From c5528214c7c0a753c908a7b353309ba665985fb4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 10 Feb 2025 14:21:28 +0100 Subject: [PATCH 107/651] 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", From 21aa330fec31bb530a4ef6c9555fb157d0711112 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 6 Feb 2025 11:03:06 +0800 Subject: [PATCH 108/651] 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 From f22ba3561daa792dd138ed543e0bf48efe0b999c Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 11 Feb 2025 17:50:18 -0500 Subject: [PATCH 109/651] 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; From ad0fbcebb5f6e093d433a0873758a2778d747eb8 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 10 Feb 2025 16:33:41 -0600 Subject: [PATCH 110/651] 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; From 828c0aa63706410503526d0ee522b9ac3232c86b Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Thu, 13 Feb 2025 16:06:52 +0530 Subject: [PATCH 111/651] 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; } From ae575d2145d1a2c8bb5d2835d7d54751f3b0bace Mon Sep 17 00:00:00 2001 From: Sheetal Date: Thu, 13 Feb 2025 11:12:16 +0000 Subject: [PATCH 112/651] 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"); From 994719ed6d81a6f4677875ab6730254c0bc484ea Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Wed, 12 Feb 2025 10:12:26 +0100 Subject: [PATCH 113/651] 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; } From 11c1967f1a796bf2ff56a7118147f1d39d9f5ee0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:23:20 +0000 Subject: [PATCH 114/651] 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); From 238c863eb3d3c6ed58493bacfd1f4b36bdcfa92f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:23:52 +0000 Subject: [PATCH 115/651] 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); From 1248d29464cc682c2a1793cfc5d4ebeb374c6738 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:24:06 +0000 Subject: [PATCH 116/651] 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) From 7e1caa679686dde5c24d60b139f234568045758f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:24:17 +0000 Subject: [PATCH 117/651] 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, From 7f1186a8d738661b941b298fd6d1d5725ed71428 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:24:38 +0000 Subject: [PATCH 118/651] ASoC: soc-dai: check return value at snd_soc_dai_set_tdm_slot() snd_soc_dai_set_tdm_slot() calls .xlate_tdm_slot_mask() or snd_soc_xlate_tdm_slot_mask(), but didn't check its return value. Let's check it. This patch might break existing driver. In such case, let's makes each func to void instead of int. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6z7yk61.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-dai.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index 7c4c9127e5f3..8f2b5b840bb0 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -261,10 +261,11 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, if (dai->driver->ops && dai->driver->ops->xlate_tdm_slot_mask) - dai->driver->ops->xlate_tdm_slot_mask(slots, - &tx_mask, &rx_mask); + ret = dai->driver->ops->xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); else - snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); + ret = snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); + if (ret) + goto err; for_each_pcm_streams(stream) snd_soc_dai_tdm_mask_set(dai, stream, *tdm_mask[stream]); @@ -273,6 +274,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, dai->driver->ops->set_tdm_slot) ret = dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, slots, slot_width); +err: return soc_dai_ret(dai, ret); } EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); From 0c4a06395156d16ea33e959fccea84e4cfec04c4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:24:54 +0000 Subject: [PATCH 119/651] ASoC: soc-pcm: remove duplicate param from __soc_pcm_hw_params() We can get struct snd_soc_pcm_runtime from struct snd_pcm_substream, no need to have both as function parameter. Let's shrink it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mseryk5l.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a206a25451f7..062e2cc467cd 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1062,10 +1062,10 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) * function can also be called multiple times and can allocate buffers * (using snd_pcm_lib_* ). It's non-atomic. */ -static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_substream *substream, +static int __soc_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai; struct snd_soc_dai *codec_dai; struct snd_pcm_hw_params tmp_params; @@ -1171,7 +1171,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, int ret; snd_soc_dpcm_mutex_lock(rtd); - ret = __soc_pcm_hw_params(rtd, substream, params); + ret = __soc_pcm_hw_params(substream, params); snd_soc_dpcm_mutex_unlock(rtd); return ret; } @@ -2123,7 +2123,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) dev_dbg(be->dev, "ASoC: hw_params BE %s\n", be->dai_link->name); - ret = __soc_pcm_hw_params(be, be_substream, &hw_params); + ret = __soc_pcm_hw_params(be_substream, &hw_params); if (ret < 0) goto unwind; @@ -2179,7 +2179,7 @@ static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, params_channels(params), params_format(params)); /* call hw_params on the frontend */ - ret = __soc_pcm_hw_params(fe, substream, params); + ret = __soc_pcm_hw_params(substream, params); if (ret < 0) dpcm_be_dai_hw_free(fe, stream); else From 257a060fe219bb0dcb98f12ce34f04eca6d08352 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:28:43 +0000 Subject: [PATCH 120/651] ASoC: remove update from snd_soc_card snd_soc_card :: update is used only for passing parameters to dapm_widget_update() like below. card->update = update; ret = soc_dapm_xxx(card, ...); card->update = NULL; Let's passing it via function parameter and remove update from snd_soc_card. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldubyjz9.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc.h | 1 - sound/soc/soc-dapm.c | 48 +++++++++++++++++++------------------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 62c90ef40f1a..644cfe26022e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1106,7 +1106,6 @@ struct snd_soc_card { /* Generic DAPM context for the card */ struct snd_soc_dapm_context dapm; struct snd_soc_dapm_stats dapm_stats; - struct snd_soc_dapm_update *update; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_card_root; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 420fe7dea31e..b7818388984e 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1743,9 +1743,8 @@ static void dapm_seq_run(struct snd_soc_card *card, soc_dapm_async_complete(d); } -static void dapm_widget_update(struct snd_soc_card *card) +static void dapm_widget_update(struct snd_soc_card *card, struct snd_soc_dapm_update *update) { - struct snd_soc_dapm_update *update = card->update; struct snd_soc_dapm_widget_list *wlist; struct snd_soc_dapm_widget *w = NULL; unsigned int wi; @@ -1951,7 +1950,8 @@ static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm) * o Input pin to Output pin (bypass, sidetone) * o DAC to ADC (loopback). */ -static int dapm_power_widgets(struct snd_soc_card *card, int event) +static int dapm_power_widgets(struct snd_soc_card *card, int event, + struct snd_soc_dapm_update *update) { struct snd_soc_dapm_widget *w; struct snd_soc_dapm_context *d; @@ -2059,7 +2059,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) /* Power down widgets first; try to avoid amplifying pops. */ dapm_seq_run(card, &down_list, event, false); - dapm_widget_update(card); + dapm_widget_update(card, update); /* Now power up. */ dapm_seq_run(card, &up_list, event, true); @@ -2332,7 +2332,9 @@ static void soc_dapm_connect_path(struct snd_soc_dapm_path *path, /* test and update the power status of a mux widget */ static int soc_dapm_mux_update_power(struct snd_soc_card *card, - struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) + struct snd_kcontrol *kcontrol, + struct snd_soc_dapm_update *update, + int mux, struct soc_enum *e) { struct snd_soc_dapm_path *path; int found = 0; @@ -2353,7 +2355,7 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card, } if (found) - dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP, update); return found; } @@ -2366,9 +2368,7 @@ int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm, int ret; snd_soc_dapm_mutex_lock(card); - card->update = update; - ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); - card->update = NULL; + ret = soc_dapm_mux_update_power(card, kcontrol, update, mux, e); snd_soc_dapm_mutex_unlock(card); if (ret > 0) snd_soc_dpcm_runtime_update(card); @@ -2379,6 +2379,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power); /* test and update the power status of a mixer or switch widget */ static int soc_dapm_mixer_update_power(struct snd_soc_card *card, struct snd_kcontrol *kcontrol, + struct snd_soc_dapm_update *update, int connect, int rconnect) { struct snd_soc_dapm_path *path; @@ -2418,7 +2419,7 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card, } if (found) - dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP, update); return found; } @@ -2431,9 +2432,7 @@ int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm, int ret; snd_soc_dapm_mutex_lock(card); - card->update = update; - ret = soc_dapm_mixer_update_power(card, kcontrol, connect, -1); - card->update = NULL; + ret = soc_dapm_mixer_update_power(card, kcontrol, update, connect, -1); snd_soc_dapm_mutex_unlock(card); if (ret > 0) snd_soc_dpcm_runtime_update(card); @@ -2689,7 +2688,7 @@ int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm) if (!snd_soc_card_is_instantiated(dapm->card)) return 0; - return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP); + return dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP, NULL); } EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_unlocked); @@ -3358,7 +3357,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) dapm_debugfs_add_widget(w); } - dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP, NULL); snd_soc_dapm_mutex_unlock(card); return 0; } @@ -3447,6 +3446,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, unsigned int val, rval = 0; int connect, rconnect = -1, change, reg_change = 0; struct snd_soc_dapm_update update = {}; + struct snd_soc_dapm_update *pupdate = NULL; int ret = 0; val = (ucontrol->value.integer.value[0] & mask); @@ -3495,13 +3495,9 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, update.reg = reg; update.mask = mask << shift; update.val = val; - card->update = &update; + pupdate = &update; } - - ret = soc_dapm_mixer_update_power(card, kcontrol, connect, - rconnect); - - card->update = NULL; + ret = soc_dapm_mixer_update_power(card, kcontrol, pupdate, connect, rconnect); } snd_soc_dapm_mutex_unlock(card); @@ -3568,6 +3564,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, unsigned int val, change, reg_change = 0; unsigned int mask; struct snd_soc_dapm_update update = {}; + struct snd_soc_dapm_update *pupdate = NULL; int ret = 0; if (item[0] >= e->items) @@ -3595,12 +3592,9 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, update.reg = e->reg; update.mask = mask; update.val = val; - card->update = &update; + pupdate = &update; } - - ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e); - - card->update = NULL; + ret = soc_dapm_mux_update_power(card, kcontrol, pupdate, item[0], e); } snd_soc_dapm_mutex_unlock(card); @@ -4526,7 +4520,7 @@ static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, for_each_rtd_dais(rtd, i, dai) soc_dapm_dai_stream_event(dai, stream, event); - dapm_power_widgets(rtd->card, event); + dapm_power_widgets(rtd->card, event, NULL); } /** From 40b1f89a1691c4b7740bec2c868f1e4c60346353 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:28:57 +0000 Subject: [PATCH 121/651] ASoC: remove dpcm_process_paths() dpcm_process_paths() will call dpcm_add_paths() (A) or dpcm_prune_paths() (B) dpcm_process_paths(..., new) { if (new) (A) return dpcm_add_paths(...); else (B) return dpcm_prune_paths(...); } but the user who need to call dpcm_prune_paths() (B) is only soc_dpcm_fe_runtime_update(), all other user want to call is dpcm_add_paths() (A). We don't need to have confusing dpcm_process_paths(). Let's remove it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jz9vyjyu.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dpcm.h | 4 ++-- sound/soc/soc-compress.c | 2 +- sound/soc/soc-pcm.c | 28 +++++++++++----------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h index c1b88c3b7835..af24665e37e8 100644 --- a/include/sound/soc-dpcm.h +++ b/include/sound/soc-dpcm.h @@ -132,8 +132,8 @@ static inline void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) int dpcm_path_get(struct snd_soc_pcm_runtime *fe, int stream, struct snd_soc_dapm_widget_list **list_); void dpcm_path_put(struct snd_soc_dapm_widget_list **list); -int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, - int stream, struct snd_soc_dapm_widget_list **list, int new); +int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, + struct snd_soc_dapm_widget_list **list_); int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream); void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, int do_hw_free, struct snd_soc_dpcm *last); diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 563dc0767c17..01d1d6bee28c 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -148,7 +148,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) snd_soc_dpcm_mutex_lock(fe); /* calculate valid and active FE <-> BE dpcms */ - dpcm_process_paths(fe, stream, &list, 1); + dpcm_add_paths(fe, stream, &list); fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 062e2cc467cd..96776824d9da 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1550,8 +1550,8 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, return prune; } -static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, - struct snd_soc_dapm_widget_list **list_) +int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, + struct snd_soc_dapm_widget_list **list_) { struct snd_soc_card *card = fe->card; struct snd_soc_dapm_widget_list *list = *list_; @@ -1616,19 +1616,6 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, return new; } -/* - * Find the corresponding BE DAIs that source or sink audio to this - * FE substream. - */ -int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, - int stream, struct snd_soc_dapm_widget_list **list, int new) -{ - if (new) - return dpcm_add_paths(fe, stream, list); - else - return dpcm_prune_paths(fe, stream, list); -} - void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; @@ -2706,7 +2693,14 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new) return paths; /* update any playback/capture paths */ - count = dpcm_process_paths(fe, stream, &list, new); + /* + * Find the corresponding BE DAIs that source or sink audio to this + * FE substream. + */ + if (new) + count = dpcm_add_paths(fe, stream, &list); + else + count = dpcm_prune_paths(fe, stream, &list); if (count) { dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE); if (new) @@ -2798,7 +2792,7 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) goto open_end; /* calculate valid and active FE <-> BE dpcms */ - dpcm_process_paths(fe, stream, &list, 1); + dpcm_add_paths(fe, stream, &list); ret = dpcm_fe_dai_startup(fe_substream); if (ret < 0) From 3aebbcba4baaa81bc8c83f2229ed8e774cf40618 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:29:03 +0000 Subject: [PATCH 122/651] ASoC: soc-pcm: cleanup dpcm_dai_trigger_fe_be() DPCM is already difficult to read, but now dpcm_dai_trigger_fe_be() even difficult to read. static int dpcm_dai_trigger_fe_be(.., fe_first) { ^ if (fe_first) { (A) ... |(x) goto end; v } ^ (B) ... v end: return ... } It want to switch function call order by using "fe_first" for fe->be order part (A), or be->fe order part (B). But the code is using "goto" in last of (A) (=x). Just use "if..else" for (A) (B) is easy to read and understand what it want to do. static int dpcm_dai_trigger_fe_be(.., fe_first) { ^ if (fe_first) { (A) ... v } ^ else { (B) ... v } return ... } Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikpfyjyo.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 96776824d9da..8a3073a506aa 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2365,18 +2365,18 @@ static int dpcm_dai_trigger_fe_be(struct snd_pcm_substream *substream, goto end; ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); - goto end; } - /* call trigger on the frontend after the backend. */ - ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); - if (ret < 0) - goto end; + else { + ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); + if (ret < 0) + goto end; - dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n", - fe->dai_link->name, cmd); + dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n", + fe->dai_link->name, cmd); - ret = soc_pcm_trigger(substream, cmd); + ret = soc_pcm_trigger(substream, cmd); + } end: return snd_soc_ret(fe->dev, ret, "trigger FE cmd: %d failed\n", cmd); } From 42da18e62652b58ba5ecd1524c146b202cda9bb7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Feb 2025 02:29:14 +0000 Subject: [PATCH 123/651] ASoC: soc-pcm: cleanup dpcm_fe_dai_do_trigger() dpcm_fe_dai_do_trigger() has big duplicate code. Let's makes code more simple. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64zyjyd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 52 +++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 8a3073a506aa..2a53a2eb4acd 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2386,46 +2386,17 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_soc_pcm_runtime *fe = snd_soc_substream_to_rtd(substream); int stream = substream->stream; int ret = 0; + int fe_first; enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; switch (trigger) { case SND_SOC_DPCM_TRIGGER_PRE: - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_DRAIN: - ret = dpcm_dai_trigger_fe_be(substream, cmd, true); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ret = dpcm_dai_trigger_fe_be(substream, cmd, false); - break; - default: - ret = -EINVAL; - break; - } + fe_first = true; break; case SND_SOC_DPCM_TRIGGER_POST: - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_DRAIN: - ret = dpcm_dai_trigger_fe_be(substream, cmd, false); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ret = dpcm_dai_trigger_fe_be(substream, cmd, true); - break; - default: - ret = -EINVAL; - break; - } + fe_first = false; break; default: dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd, @@ -2434,6 +2405,23 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd) goto out; } + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_DRAIN: + ret = dpcm_dai_trigger_fe_be(substream, cmd, fe_first); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret = dpcm_dai_trigger_fe_be(substream, cmd, !fe_first); + break; + default: + ret = -EINVAL; + break; + } + if (ret < 0) goto out; From 1c3b5f37409682184669457a5bdf761268eafbe5 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 8 Feb 2025 01:03:24 +0000 Subject: [PATCH 124/651] ASoC: tas2764: Power up/down amp on mute ops The ASoC convention is that clocks are removed after codec mute, and power up/down is more about top level power management. For these chips, the "mute" state still expects a TDM clock, and yanking the clock in this state will trigger clock errors. So, do the full shutdown<->mute<->active transition on the mute operation, so the amp is in software shutdown by the time the clocks are removed. This fixes TDM clock errors when streams are stopped. Signed-off-by: Hector Martin Signed-off-by: Mark Brown Link: https://patch.msgid.link/20250208-asoc-tas2764-v1-1-dbab892a69b5@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas2764.c | 51 ++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index d482cd194c08..60d660a88fab 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -180,33 +180,6 @@ static SOC_ENUM_SINGLE_DECL( static const struct snd_kcontrol_new tas2764_asi1_mux = SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum); -static int tas2764_dac_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); - int ret; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - tas2764->dac_powered = true; - ret = tas2764_update_pwr_ctrl(tas2764); - break; - case SND_SOC_DAPM_PRE_PMD: - tas2764->dac_powered = false; - ret = tas2764_update_pwr_ctrl(tas2764); - break; - default: - dev_err(tas2764->dev, "Unsupported event\n"); - return -EINVAL; - } - - if (ret < 0) - return ret; - - return 0; -} - static const struct snd_kcontrol_new isense_switch = SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 1, 1); static const struct snd_kcontrol_new vsense_switch = @@ -219,8 +192,7 @@ static const struct snd_soc_dapm_widget tas2764_dapm_widgets[] = { 1, &isense_switch), SND_SOC_DAPM_SWITCH("VSENSE", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, 1, &vsense_switch), - SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2764_dac_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_OUTPUT("OUT"), SND_SOC_DAPM_SIGGEN("VMON"), SND_SOC_DAPM_SIGGEN("IMON") @@ -241,9 +213,28 @@ static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction) { struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(dai->component); + int ret; + + if (!mute) { + tas2764->dac_powered = true; + ret = tas2764_update_pwr_ctrl(tas2764); + if (ret) + return ret; + } tas2764->unmuted = !mute; - return tas2764_update_pwr_ctrl(tas2764); + ret = tas2764_update_pwr_ctrl(tas2764); + if (ret) + return ret; + + if (mute) { + tas2764->dac_powered = false; + ret = tas2764_update_pwr_ctrl(tas2764); + if (ret) + return ret; + } + + return 0; } static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth) From 08a66f55f7246d477b19620a953476dfc02beefc Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 8 Feb 2025 01:03:25 +0000 Subject: [PATCH 125/651] ASoC: tas2764: Wait for ramp-down after shutdown When we shut down the amp, we need to wait for the built-in ramp-down before we can remove the TDM clocks. There is no documented status regiter to poll, so the best we can do is a delay. Datasheet says 5.9ms for ramp-down and 1.5ms between shutdown and next startup, so let's do 6ms after mute and 2ms after shutdown. That gives us a cumulative 8ms for ramp-down and guaratees the required minimum shutdown time. Signed-off-by: Hector Martin Signed-off-by: Mark Brown Link: https://patch.msgid.link/20250208-asoc-tas2764-v1-2-dbab892a69b5@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas2764.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index 60d660a88fab..0b033ab51f7f 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -142,6 +142,8 @@ static int tas2764_codec_suspend(struct snd_soc_component *component) regcache_cache_only(tas2764->regmap, true); regcache_mark_dirty(tas2764->regmap); + usleep_range(6000, 7000); + return 0; } @@ -228,10 +230,16 @@ static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction) return ret; if (mute) { + /* Wait for ramp-down */ + usleep_range(6000, 7000); + tas2764->dac_powered = false; ret = tas2764_update_pwr_ctrl(tas2764); if (ret) return ret; + + /* Wait a bit after shutdown */ + usleep_range(2000, 3000); } return 0; From f37f1748564ac51d32f7588bd7bfc99913ccab8e Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 8 Feb 2025 01:03:26 +0000 Subject: [PATCH 126/651] ASoC: tas2764: Mark SW_RESET as volatile Since the bit is self-clearing. Signed-off-by: Hector Martin Signed-off-by: Mark Brown Link: https://patch.msgid.link/20250208-asoc-tas2764-v1-3-dbab892a69b5@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas2764.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index 0b033ab51f7f..d01333c7dd93 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -642,6 +642,7 @@ static const struct regmap_range_cfg tas2764_regmap_ranges[] = { static bool tas2764_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { + case TAS2764_SW_RST: case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4: case TAS2764_INT_CLK_CFG: return true; From d64c4c3d1c578f98d70db1c5e2535b47adce9d07 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 8 Feb 2025 01:03:27 +0000 Subject: [PATCH 127/651] ASoC: tas2764: Add reg defaults for TAS2764_INT_CLK_CFG Signed-off-by: Hector Martin Signed-off-by: Mark Brown Link: https://patch.msgid.link/20250208-asoc-tas2764-v1-4-dbab892a69b5@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas2764.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index d01333c7dd93..49d32e957789 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -625,6 +625,7 @@ static const struct reg_default tas2764_reg_defaults[] = { { TAS2764_TDM_CFG2, 0x0a }, { TAS2764_TDM_CFG3, 0x10 }, { TAS2764_TDM_CFG5, 0x42 }, + { TAS2764_INT_CLK_CFG, 0x19 }, }; static const struct regmap_range_cfg tas2764_regmap_ranges[] = { From 735049b801cf3d597752017385cfc8768ce44303 Mon Sep 17 00:00:00 2001 From: Yazen Ghannam Date: Thu, 30 Jan 2025 19:48:55 +0000 Subject: [PATCH 128/651] x86/amd_node, platform/x86/amd/hsmp: Have HSMP use SMN through AMD_NODE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HSMP interface is just an SMN interface with different offsets. Define an HSMP wrapper in the SMN code and have the HSMP platform driver use that rather than a local solution. Also, remove the "root" member from AMD_NB, since there are no more users of it. Signed-off-by: Yazen Ghannam Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Carlos Bilbao Acked-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20250130-wip-x86-amd-nb-cleanup-v4-1-b5cc997e471b@amd.com --- arch/x86/include/asm/amd_nb.h | 1 - arch/x86/include/asm/amd_node.h | 13 ++++++++++ arch/x86/kernel/amd_nb.c | 1 - arch/x86/kernel/amd_node.c | 9 +++++++ drivers/platform/x86/amd/hsmp/Kconfig | 2 +- drivers/platform/x86/amd/hsmp/acpi.c | 7 +++--- drivers/platform/x86/amd/hsmp/hsmp.c | 1 - drivers/platform/x86/amd/hsmp/hsmp.h | 3 --- drivers/platform/x86/amd/hsmp/plat.c | 36 +++++++++------------------ 9 files changed, 39 insertions(+), 34 deletions(-) diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 4c4efb93045e..adfa0854cf2d 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -27,7 +27,6 @@ struct amd_l3_cache { }; struct amd_northbridge { - struct pci_dev *root; struct pci_dev *misc; struct pci_dev *link; struct amd_l3_cache l3_cache; diff --git a/arch/x86/include/asm/amd_node.h b/arch/x86/include/asm/amd_node.h index 113ad3e8ee40..002c3afbd30f 100644 --- a/arch/x86/include/asm/amd_node.h +++ b/arch/x86/include/asm/amd_node.h @@ -30,7 +30,20 @@ static inline u16 amd_num_nodes(void) return topology_amd_nodes_per_pkg() * topology_max_packages(); } +#ifdef CONFIG_AMD_NODE int __must_check amd_smn_read(u16 node, u32 address, u32 *value); int __must_check amd_smn_write(u16 node, u32 address, u32 value); +/* Should only be used by the HSMP driver. */ +int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write); +#else +static inline int __must_check amd_smn_read(u16 node, u32 address, u32 *value) { return -ENODEV; } +static inline int __must_check amd_smn_write(u16 node, u32 address, u32 value) { return -ENODEV; } + +static inline int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write) +{ + return -ENODEV; +} +#endif /* CONFIG_AMD_NODE */ + #endif /*_ASM_X86_AMD_NODE_H_*/ diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 11fac09e3a8c..24d7a87edf9c 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -73,7 +73,6 @@ static int amd_cache_northbridges(void) amd_northbridges.nb = nb; for (i = 0; i < amd_northbridges.num; i++) { - node_to_amd_nb(i)->root = amd_node_get_root(i); node_to_amd_nb(i)->misc = amd_node_get_func(i, 3); /* diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c index d2ec7fd555c5..65045f223c10 100644 --- a/arch/x86/kernel/amd_node.c +++ b/arch/x86/kernel/amd_node.c @@ -97,6 +97,9 @@ static DEFINE_MUTEX(smn_mutex); #define SMN_INDEX_OFFSET 0x60 #define SMN_DATA_OFFSET 0x64 +#define HSMP_INDEX_OFFSET 0xc4 +#define HSMP_DATA_OFFSET 0xc8 + /* * SMN accesses may fail in ways that are difficult to detect here in the called * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do @@ -179,6 +182,12 @@ int __must_check amd_smn_write(u16 node, u32 address, u32 value) } EXPORT_SYMBOL_GPL(amd_smn_write); +int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write) +{ + return __amd_smn_rw(HSMP_INDEX_OFFSET, HSMP_DATA_OFFSET, node, address, value, write); +} +EXPORT_SYMBOL_GPL(amd_smn_hsmp_rdwr); + static int amd_cache_roots(void) { u16 node, num_nodes = amd_num_nodes(); diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig index 7d10d4462a45..d6f7a62d55b5 100644 --- a/drivers/platform/x86/amd/hsmp/Kconfig +++ b/drivers/platform/x86/amd/hsmp/Kconfig @@ -7,7 +7,7 @@ config AMD_HSMP tristate menu "AMD HSMP Driver" - depends on AMD_NB || COMPILE_TEST + depends on AMD_NODE || COMPILE_TEST config AMD_HSMP_ACPI tristate "AMD HSMP ACPI device driver" diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c index 444b43be35a2..c1eccb3c80c5 100644 --- a/drivers/platform/x86/amd/hsmp/acpi.c +++ b/drivers/platform/x86/amd/hsmp/acpi.c @@ -10,7 +10,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include #include #include @@ -24,6 +23,8 @@ #include +#include + #include "hsmp.h" #define DRIVER_NAME "amd_hsmp" @@ -321,8 +322,8 @@ static int hsmp_acpi_probe(struct platform_device *pdev) return -ENOMEM; if (!hsmp_pdev->is_probed) { - hsmp_pdev->num_sockets = amd_nb_num(); - if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS) + hsmp_pdev->num_sockets = amd_num_nodes(); + if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES) return -ENODEV; hsmp_pdev->sock = devm_kcalloc(&pdev->dev, hsmp_pdev->num_sockets, diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c index 03164e30b3a5..a3ac09a90de4 100644 --- a/drivers/platform/x86/amd/hsmp/hsmp.c +++ b/drivers/platform/x86/amd/hsmp/hsmp.c @@ -8,7 +8,6 @@ */ #include -#include #include #include diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h index e852f0a947e4..af8b21f821d6 100644 --- a/drivers/platform/x86/amd/hsmp/hsmp.h +++ b/drivers/platform/x86/amd/hsmp/hsmp.h @@ -21,8 +21,6 @@ #define HSMP_ATTR_GRP_NAME_SIZE 10 -#define MAX_AMD_SOCKETS 8 - #define HSMP_CDEV_NAME "hsmp_cdev" #define HSMP_DEVNODE_NAME "hsmp" @@ -41,7 +39,6 @@ struct hsmp_socket { void __iomem *virt_base_addr; struct semaphore hsmp_sem; char name[HSMP_ATTR_GRP_NAME_SIZE]; - struct pci_dev *root; struct device *dev; u16 sock_ind; int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw); diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c index 02ca85762b68..b9782a078dbd 100644 --- a/drivers/platform/x86/amd/hsmp/plat.c +++ b/drivers/platform/x86/amd/hsmp/plat.c @@ -10,14 +10,16 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include +#include #include #include #include #include #include +#include + #include "hsmp.h" #define DRIVER_NAME "amd_hsmp" @@ -34,28 +36,12 @@ #define SMN_HSMP_MSG_RESP 0x0010980 #define SMN_HSMP_MSG_DATA 0x00109E0 -#define HSMP_INDEX_REG 0xc4 -#define HSMP_DATA_REG 0xc8 - static struct hsmp_plat_device *hsmp_pdev; static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset, u32 *value, bool write) { - int ret; - - if (!sock->root) - return -ENODEV; - - ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG, - sock->mbinfo.base_addr + offset); - if (ret) - return ret; - - ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value) - : pci_read_config_dword(sock->root, HSMP_DATA_REG, value)); - - return ret; + return amd_smn_hsmp_rdwr(sock->sock_ind, sock->mbinfo.base_addr + offset, value, write); } static ssize_t hsmp_metric_tbl_plat_read(struct file *filp, struct kobject *kobj, @@ -95,7 +81,12 @@ static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj, * Static array of 8 + 1(for NULL) elements is created below * to create sysfs groups for sockets. * is_bin_visible function is used to show / hide the necessary groups. + * + * Validate the maximum number against MAX_AMD_NUM_NODES. If this changes, + * then the attributes and groups below must be adjusted. */ +static_assert(MAX_AMD_NUM_NODES == 8); + #define HSMP_BIN_ATTR(index, _list) \ static const struct bin_attribute attr##index = { \ .attr = { .name = HSMP_METRICS_TABLE_NAME, .mode = 0444}, \ @@ -159,10 +150,7 @@ static int init_platform_device(struct device *dev) int ret, i; for (i = 0; i < hsmp_pdev->num_sockets; i++) { - if (!node_to_amd_nb(i)) - return -ENODEV; sock = &hsmp_pdev->sock[i]; - sock->root = node_to_amd_nb(i)->root; sock->sock_ind = i; sock->dev = dev; sock->mbinfo.base_addr = SMN_HSMP_BASE; @@ -305,11 +293,11 @@ static int __init hsmp_plt_init(void) return -ENOMEM; /* - * amd_nb_num() returns number of SMN/DF interfaces present in the system + * amd_num_nodes() returns number of SMN/DF interfaces present in the system * if we have N SMN/DF interfaces that ideally means N sockets */ - hsmp_pdev->num_sockets = amd_nb_num(); - if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS) + hsmp_pdev->num_sockets = amd_num_nodes(); + if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES) return ret; ret = platform_driver_register(&amd_hsmp_driver); From bebe0afb74514ae51f4f348b28326c658b02209d Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 30 Jan 2025 19:48:56 +0000 Subject: [PATCH 129/651] x86/amd_node: Add SMN offsets to exclusive region access Offsets 0x60 and 0x64 are used internally by kernel drivers that call the amd_smn_read() and amd_smn_write() functions. If userspace accesses the regions at the same time as the kernel it may cause malfunctions in drivers using the offsets. Add these offsets to the exclusions so that the kernel is tainted if a non locked down userspace tries to access them. Signed-off-by: Mario Limonciello Signed-off-by: Yazen Ghannam Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20250130-wip-x86-amd-nb-cleanup-v4-2-b5cc997e471b@amd.com --- arch/x86/kernel/amd_node.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c index 65045f223c10..ac571948cb35 100644 --- a/arch/x86/kernel/amd_node.c +++ b/arch/x86/kernel/amd_node.c @@ -93,6 +93,7 @@ static struct pci_dev **amd_roots; /* Protect the PCI config register pairs used for SMN. */ static DEFINE_MUTEX(smn_mutex); +static bool smn_exclusive; #define SMN_INDEX_OFFSET 0x60 #define SMN_DATA_OFFSET 0x64 @@ -149,6 +150,9 @@ static int __amd_smn_rw(u8 i_off, u8 d_off, u16 node, u32 address, u32 *value, b if (!root) return err; + if (!smn_exclusive) + return err; + guard(mutex)(&smn_mutex); err = pci_write_config_dword(root, i_off, address); @@ -202,6 +206,39 @@ static int amd_cache_roots(void) return 0; } +static int reserve_root_config_spaces(void) +{ + struct pci_dev *root = NULL; + struct pci_bus *bus = NULL; + + while ((bus = pci_find_next_bus(bus))) { + /* Root device is Device 0 Function 0 on each Primary Bus. */ + root = pci_get_slot(bus, 0); + if (!root) + continue; + + if (root->vendor != PCI_VENDOR_ID_AMD && + root->vendor != PCI_VENDOR_ID_HYGON) + continue; + + pci_dbg(root, "Reserving PCI config space\n"); + + /* + * There are a few SMN index/data pairs and other registers + * that shouldn't be accessed by user space. + * So reserve the entire PCI config space for simplicity rather + * than covering specific registers piecemeal. + */ + if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) { + pci_err(root, "Failed to reserve config space\n"); + return -EEXIST; + } + } + + smn_exclusive = true; + return 0; +} + static int __init amd_smn_init(void) { int err; @@ -218,6 +255,10 @@ static int __init amd_smn_init(void) if (err) return err; + err = reserve_root_config_spaces(); + if (err) + return err; + return 0; } From 6b06755af6679fd7c98ebc017ac31c8a74127538 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 30 Jan 2025 19:48:57 +0000 Subject: [PATCH 130/651] x86/amd_node: Add support for debugfs access to SMN registers There are certain registers on AMD Zen systems that can only be accessed through SMN. Introduce a new interface that provides debugfs files for accessing SMN. As this introduces the capability for userspace to manipulate the hardware in unpredictable ways, taint the kernel when writing. Signed-off-by: Mario Limonciello Signed-off-by: Yazen Ghannam Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20250130-wip-x86-amd-nb-cleanup-v4-3-b5cc997e471b@amd.com --- arch/x86/kernel/amd_node.c | 99 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c index ac571948cb35..b670fa85c61b 100644 --- a/arch/x86/kernel/amd_node.c +++ b/arch/x86/kernel/amd_node.c @@ -8,6 +8,7 @@ * Author: Yazen Ghannam */ +#include #include /* @@ -192,6 +193,87 @@ int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write } EXPORT_SYMBOL_GPL(amd_smn_hsmp_rdwr); +static struct dentry *debugfs_dir; +static u16 debug_node; +static u32 debug_address; + +static ssize_t smn_node_write(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + u16 node; + int ret; + + ret = kstrtou16_from_user(userbuf, count, 0, &node); + if (ret) + return ret; + + if (node >= amd_num_nodes()) + return -ENODEV; + + debug_node = node; + return count; +} + +static int smn_node_show(struct seq_file *m, void *v) +{ + seq_printf(m, "0x%08x\n", debug_node); + return 0; +} + +static ssize_t smn_address_write(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + int ret; + + ret = kstrtouint_from_user(userbuf, count, 0, &debug_address); + if (ret) + return ret; + + return count; +} + +static int smn_address_show(struct seq_file *m, void *v) +{ + seq_printf(m, "0x%08x\n", debug_address); + return 0; +} + +static int smn_value_show(struct seq_file *m, void *v) +{ + u32 val; + int ret; + + ret = amd_smn_read(debug_node, debug_address, &val); + if (ret) + return ret; + + seq_printf(m, "0x%08x\n", val); + return 0; +} + +static ssize_t smn_value_write(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + u32 val; + int ret; + + ret = kstrtouint_from_user(userbuf, count, 0, &val); + if (ret) + return ret; + + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); + + ret = amd_smn_write(debug_node, debug_address, val); + if (ret) + return ret; + + return count; +} + +DEFINE_SHOW_STORE_ATTRIBUTE(smn_node); +DEFINE_SHOW_STORE_ATTRIBUTE(smn_address); +DEFINE_SHOW_STORE_ATTRIBUTE(smn_value); + static int amd_cache_roots(void) { u16 node, num_nodes = amd_num_nodes(); @@ -239,6 +321,15 @@ static int reserve_root_config_spaces(void) return 0; } +static bool enable_dfs; + +static int __init amd_smn_enable_dfs(char *str) +{ + enable_dfs = true; + return 1; +} +__setup("amd_smn_debugfs_enable", amd_smn_enable_dfs); + static int __init amd_smn_init(void) { int err; @@ -259,6 +350,14 @@ static int __init amd_smn_init(void) if (err) return err; + if (enable_dfs) { + debugfs_dir = debugfs_create_dir("amd_smn", arch_debugfs_dir); + + debugfs_create_file("node", 0600, debugfs_dir, NULL, &smn_node_fops); + debugfs_create_file("address", 0600, debugfs_dir, NULL, &smn_address_fops); + debugfs_create_file("value", 0600, debugfs_dir, NULL, &smn_value_fops); + } + return 0; } From 783db6851c1821d8b983ffb12b99c279ff64f2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Sat, 8 Feb 2025 00:57:22 +0000 Subject: [PATCH 131/651] ASoC: ops: Enforce platform maximum on initial value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lower the volume if it is violating the platform maximum at its initial value (i.e. at the time of the 'snd_soc_limit_volume' call). Signed-off-by: Martin PoviÅ¡er [Cherry picked from the Asahi kernel with fixups -- broonie] Signed-off-by: Mark Brown Link: https://patch.msgid.link/20250208-asoc-volume-limit-v1-1-b98fcf4cdbad@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index c6601ef16f84..a7d0d4035d65 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -639,6 +639,33 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); +static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; + struct snd_ctl_elem_value uctl; + int ret; + + if (!mc->platform_max) + return 0; + + ret = kctl->get(kctl, &uctl); + if (ret < 0) + return ret; + + if (uctl.value.integer.value[0] > mc->platform_max) + uctl.value.integer.value[0] = mc->platform_max; + + if (snd_soc_volsw_is_stereo(mc) && + uctl.value.integer.value[1] > mc->platform_max) + uctl.value.integer.value[1] = mc->platform_max; + + ret = kctl->put(kctl, &uctl); + if (ret < 0) + return ret; + + return 0; +} + /** * snd_soc_limit_volume - Set new limit to an existing volume control. * @@ -663,7 +690,7 @@ int snd_soc_limit_volume(struct snd_soc_card *card, struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; if (max <= mc->max - mc->min) { mc->platform_max = max; - ret = 0; + ret = snd_soc_clip_to_platform_max(kctl); } } return ret; From 9dc016eaba3a70febcd1db5f1a0beeb7430166aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 12 Feb 2025 18:29:47 +0100 Subject: [PATCH 132/651] ASoC: SOF: Intel: Don't import non-existing module namespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no module namespace "SND_SOC_SOF_INTEL_HIFI_EP_IPC", so don't import it. Historically there was such a namespace, but it was dropped in commit 97e22cbd0dc3 ("ASoC: SOF: Make Intel IPC stream ops generic"). Signed-off-by: Uwe Kleine-König Link: https://patch.msgid.link/20250212172947.38970-2-u.kleine-koenig@baylibre.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/bdw.c | 1 - sound/soc/sof/intel/byt.c | 1 - sound/soc/sof/intel/pci-tng.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index e1f0e38c2407..79374dcde89f 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -694,6 +694,5 @@ module_platform_driver(snd_sof_acpi_intel_bdw_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for Broadwell platforms"); -MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HIFI_EP_IPC"); MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); MODULE_IMPORT_NS("SND_SOC_SOF_ACPI_DEV"); diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index cae7dc0036c6..900cc10a3b7f 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -475,7 +475,6 @@ module_platform_driver(snd_sof_acpi_intel_byt_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for Baytrail/Cherrytrail"); -MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HIFI_EP_IPC"); MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); MODULE_IMPORT_NS("SND_SOC_SOF_ACPI_DEV"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index b585ac4a85c2..3eb7400942dd 100644 --- a/sound/soc/sof/intel/pci-tng.c +++ b/sound/soc/sof/intel/pci-tng.c @@ -245,7 +245,6 @@ module_pci_driver(snd_sof_pci_intel_tng_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for Tangier platforms"); -MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HIFI_EP_IPC"); MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_ATOM_HIFI_EP"); From e0f421d73053eaeb441aa77054b75992705656c7 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 10 Feb 2025 23:44:54 +0100 Subject: [PATCH 133/651] ASoC: SOF: ipc3: Use str_enabled_disabled() helper function Remove hard-coded strings by using the str_enabled_disabled() helper function. Remove unnecessary curly braces. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250210224453.363638-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/sof/ipc3.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index 7de5e3d285e7..4a194a705ace 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -801,20 +801,16 @@ int sof_ipc3_validate_fw_version(struct snd_sof_dev *sdev) return -EINVAL; } - if (ready->flags & SOF_IPC_INFO_BUILD) { + if (ready->flags & SOF_IPC_INFO_BUILD) dev_info(sdev->dev, "Firmware debug build %d on %s-%s - options:\n" " GDB: %s\n" " lock debug: %s\n" " lock vdebug: %s\n", v->build, v->date, v->time, - (ready->flags & SOF_IPC_INFO_GDB) ? - "enabled" : "disabled", - (ready->flags & SOF_IPC_INFO_LOCKS) ? - "enabled" : "disabled", - (ready->flags & SOF_IPC_INFO_LOCKSV) ? - "enabled" : "disabled"); - } + str_enabled_disabled(ready->flags & SOF_IPC_INFO_GDB), + str_enabled_disabled(ready->flags & SOF_IPC_INFO_LOCKS), + str_enabled_disabled(ready->flags & SOF_IPC_INFO_LOCKSV)); /* copy the fw_version into debugfs at first boot */ memcpy(&sdev->fw_version, v, sizeof(*v)); From 5c7e4c4da8586d2ef55a11a9f4df626b8ea9a146 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Fri, 7 Feb 2025 11:30:29 -0500 Subject: [PATCH 134/651] ASoC: dt-bindings: wlf,wm8960: add 'port' property The wm8960 codec may be used with audio graph card and thus may require an additional property: 'port'. Add it. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Daniel Baluta Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250207163029.3365-1-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/wlf,wm8960.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8960.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8960.yaml index 62e62c335d07..3c2b9790ffcf 100644 --- a/Documentation/devicetree/bindings/sound/wlf,wm8960.yaml +++ b/Documentation/devicetree/bindings/sound/wlf,wm8960.yaml @@ -75,6 +75,10 @@ properties: enable DACLRC pin. If shared-lrclk is present, no need to enable DAC for captrue. + port: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + required: - compatible - reg From 9f25b6f2568d50c247a8e3b031a0a5caee8c17d2 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 10 Feb 2025 12:58:03 +0100 Subject: [PATCH 135/651] ASoC: wm_hubs: Use str_enable_disable() in wm_hubs_update_class_w() Remove hard-coded strings by using the str_enable_disable() helper function. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250210115804.53504-3-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/codecs/wm_hubs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 0c881846f485..196ddb224e6d 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -674,7 +675,7 @@ void wm_hubs_update_class_w(struct snd_soc_component *component) if (hubs->check_class_w_digital && !hubs->check_class_w_digital(component)) enable = false; - dev_vdbg(component->dev, "Class W %s\n", enable ? "enabled" : "disabled"); + dev_vdbg(component->dev, "Class W %s\n", str_enabled_disabled(enable)); snd_soc_component_update_bits(component, WM8993_CLASS_W_0, WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable); From e08fe24c34d37d00e84009f2fb4c35f5978041e6 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 10 Feb 2025 13:01:30 +0100 Subject: [PATCH 136/651] ASoC: SOF: Intel: Use str_enable_disable() helper Remove hard-coded strings by using the str_enable_disable() helper function. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250210120132.53831-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/sof/intel/mtl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index d07c68f431ba..4a6b1d56171e 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include "../ipc4-priv.h" @@ -176,7 +177,7 @@ static void mtl_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); if (ret < 0) dev_err(sdev->dev, "failed to set SoundWire IPC interrupt %s\n", - enable ? "enable" : "disable"); + str_enable_disable(enable)); } int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) @@ -209,7 +210,7 @@ int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); if (ret < 0) { dev_err(sdev->dev, "failed to %s Host IPC and/or SOUNDWIRE\n", - enable ? "enable" : "disable"); + str_enable_disable(enable)); return ret; } @@ -228,7 +229,7 @@ int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); if (ret < 0) { dev_err(sdev->dev, "failed to set Host IPC interrupt %s\n", - enable ? "enable" : "disable"); + str_enable_disable(enable)); return ret; } From b20be2c77ce5341ded1a2d8aec119f6dca8ef1ad Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 17 Feb 2025 10:32:44 +0300 Subject: [PATCH 137/651] ASoC: SOF: imx: Fix an IS_ERR() vs NULL bug in imx_parse_ioremap_memory() The devm_ioremap() function doesn't return error pointers, it returns NULL on error. Update the checking to match. Fixes: 651e0ed391b1 ("ASoC: SOF: imx: introduce more common structures and functions") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/68973636-eab8-4d82-8359-ae2c8f60f261@stanley.mountain Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/imx/imx-common.c b/sound/soc/sof/imx/imx-common.c index c3594815e60e..ea4651a0995c 100644 --- a/sound/soc/sof/imx/imx-common.c +++ b/sound/soc/sof/imx/imx-common.c @@ -338,9 +338,9 @@ static int imx_parse_ioremap_memory(struct snd_sof_dev *sdev) } sdev->bar[blk_type] = devm_ioremap(sdev->dev, base, size); - if (IS_ERR(sdev->bar[blk_type])) + if (!sdev->bar[blk_type]) return dev_err_probe(sdev->dev, - PTR_ERR(sdev->bar[blk_type]), + -ENOMEM, "failed to ioremap %s region\n", chip_info->memory[i].name); } From a78f244a9150da0878a37a1b59fb0608b1ccfb9d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 17 Feb 2025 10:32:51 +0300 Subject: [PATCH 138/651] ASoC: SOF: imx: Fix error code in probe() This accidentally returns "common->clk_num" instead of "ret". Fixes: 651e0ed391b1 ("ASoC: SOF: imx: introduce more common structures and functions") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/b30ffe7f-21fd-45f9-9528-d6d689e04003@stanley.mountain Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx-common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/sof/imx/imx-common.c b/sound/soc/sof/imx/imx-common.c index ea4651a0995c..62bf707aa909 100644 --- a/sound/soc/sof/imx/imx-common.c +++ b/sound/soc/sof/imx/imx-common.c @@ -425,8 +425,7 @@ static int imx_probe(struct snd_sof_dev *sdev) ret = devm_clk_bulk_get_all(sdev->dev, &common->clks); if (ret < 0) - return dev_err_probe(sdev->dev, common->clk_num, - "failed to fetch clocks\n"); + return dev_err_probe(sdev->dev, ret, "failed to fetch clocks\n"); common->clk_num = ret; ret = clk_bulk_prepare_enable(common->clk_num, common->clks); From 5d9fca12f54d3e25e02521aa8f3ec5d53759b334 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Tue, 18 Feb 2025 10:40:00 +0530 Subject: [PATCH 139/651] ASoC: amd: ps: fix inconsistent indenting warning in check_and_handle_sdw_dma_irq() Fix below inconsistent indenting smatch warning. smatch warnings: sound/soc/amd/ps/pci-ps.c:68 check_and_handle_sdw_dma_irq() warn: inconsistent indenting Fixes: 4516be370ced ("ASoC: amd: ps: refactor soundwire dma interrupt handling") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202502132134.BlkNw1Iq-lkp@intel.com/ Signed-off-by: Vijendar Mukunda Link: https://patch.msgid.link/20250218051000.254265-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/ps/pci-ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 2ff8e67c19bd..221c65ff03c9 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -129,7 +129,7 @@ static short int check_and_handle_sdw_dma_irq(struct acp63_dev_data *adata, u32 if (ext_intr_stat1 & ACP63_P1_AUDIO1_RX_THRESHOLD) { writel(ACP63_P1_AUDIO1_RX_THRESHOLD, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); - adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; + adata->acp63_sdw1_dma_intr_stat[ACP63_SDW1_AUDIO1_RX] = 1; sdw_dma_irq_flag = 1; } if (ext_intr_stat1 & ACP63_P1_AUDIO1_TX_THRESHOLD) { From c893ee3f95f16fcb98da934d61483d0b7d8ed568 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 17 Feb 2025 17:17:41 -0600 Subject: [PATCH 140/651] x86/amd_node: Add a smn_read_register() helper Some of the ACP drivers will poll registers through SMN using read_poll_timeout() which requires returning the result of the register read as the argument. Add a helper to do just that. Signed-off-by: Mario Limonciello Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20250217231747.1656228-2-superm1@kernel.org --- arch/x86/include/asm/amd_node.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/x86/include/asm/amd_node.h b/arch/x86/include/asm/amd_node.h index 002c3afbd30f..23fe617898a8 100644 --- a/arch/x86/include/asm/amd_node.h +++ b/arch/x86/include/asm/amd_node.h @@ -46,4 +46,15 @@ static inline int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *val } #endif /* CONFIG_AMD_NODE */ +/* helper for use with read_poll_timeout */ +static inline int smn_read_register(u32 reg) +{ + int data, rc; + + rc = amd_smn_read(0, reg, &data); + if (rc) + return rc; + + return data; +} #endif /*_ASM_X86_AMD_NODE_H_*/ From e211adcf36d0ccdd31af7398af4725a47d74b3d4 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 17 Feb 2025 17:17:42 -0600 Subject: [PATCH 141/651] ASoC: amd: acp: rembrandt: Use AMD_NODE All consumers of SMN in the kernel should be doing it through the functions provided by AMD_NODE. Stop using the local SMN read/write symbols and switch to the AMD_NODE provided ones. Tested by: Venkata Prasad Potturu Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250217231747.1656228-3-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/amd/acp/Kconfig | 1 + sound/soc/amd/acp/acp-rembrandt.c | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 03f3fcbba5af..cdc3add3ffdb 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -58,6 +58,7 @@ config SND_AMD_ASOC_REMBRANDT select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + depends on AMD_NODE depends on X86 && PCI help This option enables Rembrandt I2S support on AMD platform. diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index 2648256fa129..e727754a8231 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -22,6 +22,8 @@ #include #include +#include + #include "amd.h" #include "../mach-config.h" #include "acp-mach.h" @@ -31,7 +33,6 @@ #define MP1_C2PMSG_69 0x3B10A14 #define MP1_C2PMSG_85 0x3B10A54 #define MP1_C2PMSG_93 0x3B10A74 -#define HOST_BRIDGE_ID 0x14B5 static struct acp_resource rsrc = { .offset = 0, @@ -166,21 +167,20 @@ static struct snd_soc_dai_driver acp_rmb_dai[] = { static int acp6x_master_clock_generate(struct device *dev) { - int data = 0; - struct pci_dev *smn_dev; + int data, rc; - smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, HOST_BRIDGE_ID, NULL); - if (!smn_dev) { - dev_err(dev, "Failed to get host bridge device\n"); - return -ENODEV; - } + rc = amd_smn_write(0, MP1_C2PMSG_93, 0); + if (rc) + return rc; + rc = amd_smn_write(0, MP1_C2PMSG_85, 0xC4); + if (rc) + return rc; + rc = amd_smn_write(0, MP1_C2PMSG_69, 0x4); + if (rc) + return rc; - smn_write(smn_dev, MP1_C2PMSG_93, 0); - smn_write(smn_dev, MP1_C2PMSG_85, 0xC4); - smn_write(smn_dev, MP1_C2PMSG_69, 0x4); - read_poll_timeout(smn_read, data, data, DELAY_US, - ACP_TIMEOUT, false, smn_dev, MP1_C2PMSG_93); - return 0; + return read_poll_timeout(smn_read_register, data, data > 0, DELAY_US, + ACP_TIMEOUT, false, MP1_C2PMSG_93); } static int rembrandt_audio_probe(struct platform_device *pdev) From 135c6af1cac5465529469700d16c0c44b24ce317 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 17 Feb 2025 17:17:43 -0600 Subject: [PATCH 142/651] ASoC: amd: acp: acp70: Use AMD_NODE All consumers of SMN in the kernel should be doing it through the functions provided by AMD_NODE. Stop using the local SMN read/write symbols and switch to the AMD_NODE provided ones. Tested by: Venkata Prasad Potturu Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250217231747.1656228-4-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/amd/acp/Kconfig | 1 + sound/soc/amd/acp/acp70.c | 28 ++++------------------------ sound/soc/sof/amd/pci-acp70.c | 1 - 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index cdc3add3ffdb..811921931430 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -82,6 +82,7 @@ config SND_AMD_ASOC_ACP70 tristate "AMD ACP ASOC Acp7.0 Support" depends on X86 && PCI depends on ACPI + depends on AMD_NODE select SND_SOC_AMD_ACP_PCM select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index 9e23729fd1a7..ef3f6504bc7f 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -23,6 +23,8 @@ #include "amd.h" #include "acp-mach.h" +#include + #define DRV_NAME "acp_asoc_acp70" #define CLK7_CLK0_DFS_CNTL_N1 0X0006C1A4 @@ -137,29 +139,6 @@ static struct snd_soc_dai_driver acp70_dai[] = { }, }; -static int acp70_i2s_master_clock_generate(struct acp_dev_data *adata) -{ - struct pci_dev *smn_dev; - u32 device_id; - - if (adata->acp_rev == ACP70_PCI_ID) - device_id = 0x1507; - else if (adata->acp_rev == ACP71_PCI_ID) - device_id = 0x1122; - else - return -ENODEV; - - smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, device_id, NULL); - - if (!smn_dev) - return -ENODEV; - - /* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/ - smn_write(smn_dev, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER); - - return 0; -} - static int acp_acp70_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -215,7 +194,8 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) dev_set_drvdata(dev, adata); - ret = acp70_i2s_master_clock_generate(adata); + /* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/ + ret = amd_smn_write(0, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER); if (ret) { dev_err(&pdev->dev, "Failed to set I2S master clock as 196.608MHz\n"); return ret; diff --git a/sound/soc/sof/amd/pci-acp70.c b/sound/soc/sof/amd/pci-acp70.c index 3647ec992e95..d886bdf3a112 100644 --- a/sound/soc/sof/amd/pci-acp70.c +++ b/sound/soc/sof/amd/pci-acp70.c @@ -28,7 +28,6 @@ #define ACP70_REG_END 0x125C000 static const struct sof_amd_acp_desc acp70_chip_info = { - .host_bridge_id = HOST_BRIDGE_ACP70, .pgfsm_base = ACP70_PGFSM_BASE, .ext_intr_enb = ACP70_EXTERNAL_INTR_ENB, .ext_intr_cntl = ACP70_EXTERNAL_INTR_CNTL, From 8f969537149d672d40a0e75a83f39451a5402780 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 17 Feb 2025 17:17:44 -0600 Subject: [PATCH 143/651] ASoC: amd: acp: acp63: Use AMD_NODE All consumers of SMN in the kernel should be doing it through the functions provided by AMD_NODE. Stop using the local SMN read/write symbols and switch to the AMD_NODE provided ones. Tested by: Venkata Prasad Potturu Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250217231747.1656228-5-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/amd/acp/Kconfig | 1 + sound/soc/amd/acp/acp63.c | 55 +++++++++++++++++++++++------------ sound/soc/sof/amd/pci-acp63.c | 1 - 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 811921931430..de54237a211a 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -69,6 +69,7 @@ config SND_AMD_ASOC_ACP63 tristate "AMD ACP ASOC ACP6.3 Support" depends on X86 && PCI depends on ACPI + depends on AMD_NODE select SND_SOC_AMD_ACP_PCM select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 81496e713440..4187a8968de7 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -20,6 +20,9 @@ #include #include #include + +#include + #include "amd.h" #include "acp-mach.h" #include "../mach-config.h" @@ -160,37 +163,53 @@ static struct snd_soc_dai_driver acp63_dai[] = { static int acp63_i2s_master_clock_generate(struct acp_dev_data *adata) { + int rc; u32 data; union clk_pll_req_no clk_pll; - struct pci_dev *smn_dev; - - smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x14E8, NULL); - if (!smn_dev) - return -ENODEV; /* Clk5 pll register values to get mclk as 196.6MHz*/ clk_pll.bits.fb_mult_int = 0x31; clk_pll.bits.pll_spine_div = 0; clk_pll.bits.gb_mult_frac = 0x26E9; - data = smn_read(smn_dev, CLK_PLL_PWR_REQ_N0); - smn_write(smn_dev, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_STOP_REQ); + rc = amd_smn_read(0, CLK_PLL_PWR_REQ_N0, &data); + if (rc) + return rc; + rc = amd_smn_write(0, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_STOP_REQ); + if (rc) + return rc; - data = smn_read(smn_dev, CLK_SPLL_FIELD_2_N0); - if (data & PLL_FRANCE_EN) - smn_write(smn_dev, CLK_SPLL_FIELD_2_N0, data | PLL_FRANCE_EN); + rc = amd_smn_read(0, CLK_SPLL_FIELD_2_N0, &data); + if (rc) + return rc; + if (data & PLL_FRANCE_EN) { + rc = amd_smn_write(0, CLK_SPLL_FIELD_2_N0, data | PLL_FRANCE_EN); + if (rc) + return rc; + } - smn_write(smn_dev, CLK_PLL_REQ_N0, clk_pll.clk_pll_req_no_reg); + rc = amd_smn_write(0, CLK_PLL_REQ_N0, clk_pll.clk_pll_req_no_reg); + if (rc) + return rc; - data = smn_read(smn_dev, CLK_PLL_PWR_REQ_N0); - smn_write(smn_dev, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_START_REQ); + rc = amd_smn_read(0, CLK_PLL_PWR_REQ_N0, &data); + if (rc) + return rc; + rc = amd_smn_write(0, CLK_PLL_PWR_REQ_N0, data | PLL_AUTO_START_REQ); + if (rc) + return rc; - data = smn_read(smn_dev, CLK_DFSBYPASS_CONTR); - smn_write(smn_dev, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_0); - smn_write(smn_dev, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_1); + rc = amd_smn_read(0, CLK_DFSBYPASS_CONTR, &data); + if (rc) + return rc; + rc = amd_smn_write(0, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_0); + if (rc) + return rc; + rc = amd_smn_write(0, CLK_DFSBYPASS_CONTR, data | EXIT_DPF_BYPASS_1); + if (rc) + return rc; - smn_write(smn_dev, CLK_DFS_CNTL_N0, CLK0_DIVIDER); - return 0; + return amd_smn_write(0, CLK_DFS_CNTL_N0, CLK0_DIVIDER); } static int acp63_audio_probe(struct platform_device *pdev) diff --git a/sound/soc/sof/amd/pci-acp63.c b/sound/soc/sof/amd/pci-acp63.c index ffe7c755d655..13aa87cdeeac 100644 --- a/sound/soc/sof/amd/pci-acp63.c +++ b/sound/soc/sof/amd/pci-acp63.c @@ -28,7 +28,6 @@ #define ACP6x_REG_END 0x125C000 static const struct sof_amd_acp_desc acp63_chip_info = { - .host_bridge_id = HOST_BRIDGE_ACP63, .pgfsm_base = ACP6X_PGFSM_BASE, .ext_intr_enb = ACP6X_EXTERNAL_INTR_ENB, .ext_intr_cntl = ACP6X_EXTERNAL_INTR_CNTL, From f120cf33d2325fd95d063eccbff2e86ffc7f493a Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 17 Feb 2025 17:17:45 -0600 Subject: [PATCH 144/651] ASoC: SOF: amd: Use AMD_NODE All consumers of SMN in the kernel should be doing it through the functions provided by AMD_NODE. Stop using the local SMN read/write symbols and switch to the AMD_NODE provided ones. Tested by: Venkata Prasad Potturu Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250217231747.1656228-6-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/sof/amd/Kconfig | 1 + sound/soc/sof/amd/acp.c | 56 ++++++++++----------------------- sound/soc/sof/amd/acp.h | 1 - sound/soc/sof/amd/pci-rmb.c | 1 - sound/soc/sof/amd/pci-rn.c | 1 - sound/soc/sof/amd/pci-vangogh.c | 1 - 6 files changed, 17 insertions(+), 44 deletions(-) diff --git a/sound/soc/sof/amd/Kconfig b/sound/soc/sof/amd/Kconfig index f4cafe801017..28216c8c1cf9 100644 --- a/sound/soc/sof/amd/Kconfig +++ b/sound/soc/sof/amd/Kconfig @@ -25,6 +25,7 @@ config SND_SOC_SOF_AMD_COMMON select SND_SOC_SOF_ACP_PROBES select SND_SOC_ACPI_AMD_MATCH select SND_SOC_ACPI if ACPI + depends on AMD_NODE help This option is not user-selectable but automatically handled by 'select' statements at a higher level diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index 33648ff8b833..7007014423a4 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -16,6 +16,8 @@ #include #include +#include + #include "../ops.h" #include "acp.h" #include "acp-dsp-offset.h" @@ -42,24 +44,6 @@ const struct dmi_system_id acp_sof_quirk_table[] = { }; EXPORT_SYMBOL_GPL(acp_sof_quirk_table); -static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data) -{ - pci_write_config_dword(dev, 0x60, smn_addr); - pci_write_config_dword(dev, 0x64, data); - - return 0; -} - -static int smn_read(struct pci_dev *dev, u32 smn_addr) -{ - u32 data = 0; - - pci_write_config_dword(dev, 0x60, smn_addr); - pci_read_config_dword(dev, 0x64, &data); - - return data; -} - static void init_dma_descriptor(struct acp_dev_data *adata) { struct snd_sof_dev *sdev = adata->dev; @@ -208,11 +192,11 @@ int configure_and_run_dma(struct acp_dev_data *adata, unsigned int src_addr, static int psp_mbox_ready(struct acp_dev_data *adata, bool ack) { struct snd_sof_dev *sdev = adata->dev; - int ret; - u32 data; + int ret, data; + + ret = read_poll_timeout(smn_read_register, data, data > 0 && data & MBOX_READY_MASK, + MBOX_DELAY_US, ACP_PSP_TIMEOUT_US, false, MP0_C2PMSG_114_REG); - ret = read_poll_timeout(smn_read, data, data & MBOX_READY_MASK, MBOX_DELAY_US, - ACP_PSP_TIMEOUT_US, false, adata->smn_dev, MP0_C2PMSG_114_REG); if (!ret) return 0; @@ -240,8 +224,8 @@ static int psp_send_cmd(struct acp_dev_data *adata, int cmd) return -EINVAL; /* Get a non-zero Doorbell value from PSP */ - ret = read_poll_timeout(smn_read, data, data, MBOX_DELAY_US, ACP_PSP_TIMEOUT_US, false, - adata->smn_dev, MP0_C2PMSG_73_REG); + ret = read_poll_timeout(smn_read_register, data, data > 0, MBOX_DELAY_US, + ACP_PSP_TIMEOUT_US, false, MP0_C2PMSG_73_REG); if (ret) { dev_err(sdev->dev, "Failed to get Doorbell from MBOX %x\n", MP0_C2PMSG_73_REG); @@ -253,10 +237,14 @@ static int psp_send_cmd(struct acp_dev_data *adata, int cmd) if (ret) return ret; - smn_write(adata->smn_dev, MP0_C2PMSG_114_REG, cmd); + ret = amd_smn_write(0, MP0_C2PMSG_114_REG, cmd); + if (ret) + return ret; /* Ring the Doorbell for PSP */ - smn_write(adata->smn_dev, MP0_C2PMSG_73_REG, data); + ret = amd_smn_write(0, MP0_C2PMSG_73_REG, data); + if (ret) + return ret; /* Check MBOX ready as PSP ack */ ret = psp_mbox_ready(adata, 1); @@ -770,16 +758,10 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev) adata->pci_rev = pci->revision; mutex_init(&adata->acp_lock); sdev->pdata->hw_pdata = adata; - adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL); - if (!adata->smn_dev) { - dev_err(sdev->dev, "Failed to get host bridge device\n"); - ret = -ENODEV; - goto unregister_dev; - } ret = acp_init(sdev); if (ret < 0) - goto free_smn_dev; + goto unregister_dev; sdev->ipc_irq = pci->irq; ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread, @@ -787,7 +769,7 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev) if (ret < 0) { dev_err(sdev->dev, "failed to register IRQ %d\n", sdev->ipc_irq); - goto free_smn_dev; + goto unregister_dev; } /* scan SoundWire capabilities exposed by DSDT */ @@ -800,7 +782,6 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev) if (ret < 0) { dev_err(sdev->dev, "error: SoundWire probe error\n"); free_irq(sdev->ipc_irq, sdev); - pci_dev_put(adata->smn_dev); return ret; } @@ -846,8 +827,6 @@ skip_soundwire: free_ipc_irq: free_irq(sdev->ipc_irq, sdev); -free_smn_dev: - pci_dev_put(adata->smn_dev); unregister_dev: platform_device_unregister(adata->dmic_dev); return ret; @@ -858,9 +837,6 @@ void amd_sof_acp_remove(struct snd_sof_dev *sdev) { struct acp_dev_data *adata = sdev->pdata->hw_pdata; - if (adata->smn_dev) - pci_dev_put(adata->smn_dev); - if (adata->sdw) amd_sof_sdw_exit(sdev); diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h index 800594440f73..514330106357 100644 --- a/sound/soc/sof/amd/acp.h +++ b/sound/soc/sof/amd/acp.h @@ -255,7 +255,6 @@ struct acp_dev_data { struct dma_descriptor dscr_info[ACP_MAX_DESC]; struct acp_dsp_stream stream_buf[ACP_MAX_STREAM]; struct acp_dsp_stream *dtrace_stream; - struct pci_dev *smn_dev; struct acp_dsp_stream *probe_stream; bool enable_fw_debug; bool is_dram_in_use; diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c index cbb4d5282664..0233b6ba2d2e 100644 --- a/sound/soc/sof/amd/pci-rmb.c +++ b/sound/soc/sof/amd/pci-rmb.c @@ -28,7 +28,6 @@ #define ACP6X_FUTURE_REG_ACLK_0 0x1854 static const struct sof_amd_acp_desc rembrandt_chip_info = { - .host_bridge_id = HOST_BRIDGE_RMB, .pgfsm_base = ACP6X_PGFSM_BASE, .ext_intr_stat = ACP6X_EXT_INTR_STAT, .dsp_intr_base = ACP6X_DSP_SW_INTR_BASE, diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c index b7d558cb1fd7..4a36029a00de 100644 --- a/sound/soc/sof/amd/pci-rn.c +++ b/sound/soc/sof/amd/pci-rn.c @@ -28,7 +28,6 @@ #define ACP3X_FUTURE_REG_ACLK_0 0x1860 static const struct sof_amd_acp_desc renoir_chip_info = { - .host_bridge_id = HOST_BRIDGE_CZN, .pgfsm_base = ACP3X_PGFSM_BASE, .ext_intr_stat = ACP3X_EXT_INTR_STAT, .dsp_intr_base = ACP3X_DSP_SW_INTR_BASE, diff --git a/sound/soc/sof/amd/pci-vangogh.c b/sound/soc/sof/amd/pci-vangogh.c index 53f64d6bc91b..18734cd21abf 100644 --- a/sound/soc/sof/amd/pci-vangogh.c +++ b/sound/soc/sof/amd/pci-vangogh.c @@ -27,7 +27,6 @@ static const struct sof_amd_acp_desc vangogh_chip_info = { .name = "vangogh", - .host_bridge_id = HOST_BRIDGE_VGH, .pgfsm_base = ACP5X_PGFSM_BASE, .ext_intr_stat = ACP5X_EXT_INTR_STAT, .dsp_intr_base = ACP5X_DSP_SW_INTR_BASE, From 40d05927830227f2a1701c61e8bbe65287a03490 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 17 Feb 2025 17:17:46 -0600 Subject: [PATCH 145/651] ASoC: amd: acp: Drop local symbols for smn read/write As the ACP drivers use the AMD_NODE provided symbols, the local ones are no longer necessary. Tested by: Venkata Prasad Potturu Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250217231747.1656228-7-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 18 ------------------ sound/soc/amd/acp/amd.h | 3 --- 2 files changed, 21 deletions(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 7acc7ed2e8cc..89f5cda18a23 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -345,24 +345,6 @@ int acp_deinit(struct acp_chip_info *chip) } EXPORT_SYMBOL_NS_GPL(acp_deinit, "SND_SOC_ACP_COMMON"); -int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data) -{ - pci_write_config_dword(dev, 0x60, smn_addr); - pci_write_config_dword(dev, 0x64, data); - return 0; -} -EXPORT_SYMBOL_NS_GPL(smn_write, "SND_SOC_ACP_COMMON"); - -int smn_read(struct pci_dev *dev, u32 smn_addr) -{ - u32 data; - - pci_write_config_dword(dev, 0x60, smn_addr); - pci_read_config_dword(dev, 0x64, &data); - return data; -} -EXPORT_SYMBOL_NS_GPL(smn_read, "SND_SOC_ACP_COMMON"); - static void check_acp3x_config(struct acp_chip_info *chip) { u32 val; diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index ee69dfb10cb8..c921bcabbcec 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -235,9 +235,6 @@ int acp_platform_unregister(struct device *dev); int acp_machine_select(struct acp_dev_data *adata); -int smn_read(struct pci_dev *dev, u32 smn_addr); -int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data); - int acp_init(struct acp_chip_info *chip); int acp_deinit(struct acp_chip_info *chip); void acp_enable_interrupts(struct acp_dev_data *adata); From a261d77fec147b9974aacca8ae8f0693feede838 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 17 Feb 2025 17:17:47 -0600 Subject: [PATCH 146/651] ASoC: SOF: amd: Drop host bridge ID from struct host_bridge_id is no longer used by any of the SoCs as they all use AMD_NODE to communicate with SMN routers. Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250217231747.1656228-8-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/sof/amd/acp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h index 514330106357..a26a3f47ba53 100644 --- a/sound/soc/sof/amd/acp.h +++ b/sound/soc/sof/amd/acp.h @@ -197,7 +197,6 @@ struct acp_dsp_stream { struct sof_amd_acp_desc { const char *name; - unsigned int host_bridge_id; u32 pgfsm_base; u32 ext_intr_enb; u32 ext_intr_cntl; From c8d08464bce947ee060e0174a3f4e87503269d0c Mon Sep 17 00:00:00 2001 From: Balakrishnan Sambath Date: Wed, 19 Feb 2025 11:22:27 +0530 Subject: [PATCH 147/651] ASoC: dt-bindings: atmel-at91sam9g20ek: convert to json-schema Convert atmel-at91sam9g20ek-wm8731-audio DT binding to yaml based json-schema.Change file name to match json-scheme naming. Signed-off-by: Balakrishnan Sambath Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250219-sound-atmel-at91sam9g20ek-v3-1-d7c082af4e14@microchip.com Signed-off-by: Mark Brown --- .../sound/atmel,at91sam9g20ek-wm8731.yaml | 72 +++++++++++++++++++ .../atmel-at91sam9g20ek-wm8731-audio.txt | 26 ------- 2 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml delete mode 100644 Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt diff --git a/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml new file mode 100644 index 000000000000..627da2d890b2 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/atmel,at91sam9g20ek-wm8731.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/atmel,at91sam9g20ek-wm8731.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Atmel at91sam9g20ek wm8731 audio complex + +maintainers: + - Balakrishnan Sambath + +description: + The audio complex configuration for Atmel at91sam9g20ek with WM8731 audio codec. + +properties: + compatible: + const: atmel,at91sam9g20ek-wm8731-audio + + atmel,model: + $ref: /schemas/types.yaml#/definitions/string + description: The user-visible name of this sound complex. + + atmel,audio-routing: + $ref: /schemas/types.yaml#/definitions/non-unique-string-array + description: A list of the connections between audio components. + minItems: 2 + maxItems: 4 + items: + enum: + # Board Connectors + - Ext Spk + - Int Mic + + # CODEC Pins + - LOUT + - ROUT + - LHPOUT + - RHPOUT + - LLINEIN + - RLINEIN + - MICIN + + atmel,ssc-controller: + $ref: /schemas/types.yaml#/definitions/phandle + description: The phandle of the SSC controller. + + atmel,audio-codec: + $ref: /schemas/types.yaml#/definitions/phandle + description: The phandle of WM8731 audio codec. + +required: + - compatible + - atmel,model + - atmel,audio-routing + - atmel,ssc-controller + - atmel,audio-codec + +additionalProperties: false + +examples: + - | + sound { + compatible = "atmel,at91sam9g20ek-wm8731-audio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pck0_as_mck>; + atmel,model = "wm8731 @ AT91SAMG20EK"; + atmel,audio-routing = + "Ext Spk", "LHPOUT", + "Int Mic", "MICIN"; + atmel,ssc-controller = <&ssc0>; + atmel,audio-codec = <&wm8731>; + }; diff --git a/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt deleted file mode 100644 index 9c5a9947b64d..000000000000 --- a/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt +++ /dev/null @@ -1,26 +0,0 @@ -* Atmel at91sam9g20ek wm8731 audio complex - -Required properties: - - compatible: "atmel,at91sam9g20ek-wm8731-audio" - - atmel,model: The user-visible name of this sound complex. - - atmel,audio-routing: A list of the connections between audio components. - - atmel,ssc-controller: The phandle of the SSC controller - - atmel,audio-codec: The phandle of the WM8731 audio codec -Optional properties: - - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt - -Example: -sound { - compatible = "atmel,at91sam9g20ek-wm8731-audio"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pck0_as_mck>; - - atmel,model = "wm8731 @ AT91SAMG20EK"; - - atmel,audio-routing = - "Ext Spk", "LHPOUT", - "Int MIC", "MICIN"; - - atmel,ssc-controller = <&ssc0>; - atmel,audio-codec = <&wm8731>; -}; From 2e2f89b184644f0e29f1ec0b4dcfd0361d2635cb Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Wed, 19 Feb 2025 15:21:32 +0000 Subject: [PATCH 148/651] firmware: cs_dsp: test_bin_error: Use same test cases for adsp2 and Halo Core Re-use the adsp2 test cases for the Halo Core test run. Before this the Halo Core kunit_case array was an empty placeholder. Signed-off-by: Richard Fitzgerald Link: https://patch.msgid.link/20250219152132.1285941-1-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- .../firmware/cirrus/test/cs_dsp_test_bin_error.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c b/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c index 5dcf62f19faf..8748874f0552 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c @@ -534,11 +534,6 @@ static int cs_dsp_bin_err_test_adsp2_16bit_init(struct kunit *test) return cs_dsp_bin_err_test_common_init(test, dsp, 1); } -static struct kunit_case cs_dsp_bin_err_test_cases_halo[] = { - - { } /* terminator */ -}; - static void cs_dsp_bin_err_block_types_desc(const struct cs_dsp_bin_test_param *param, char *desc) { @@ -560,7 +555,7 @@ KUNIT_ARRAY_PARAM(bin_test_block_types, bin_test_block_types_cases, cs_dsp_bin_err_block_types_desc); -static struct kunit_case cs_dsp_bin_err_test_cases_adsp2[] = { +static struct kunit_case cs_dsp_bin_err_test_cases[] = { KUNIT_CASE(bin_load_with_unknown_blocks), KUNIT_CASE(bin_err_wrong_magic), KUNIT_CASE(bin_err_too_short_for_header), @@ -578,21 +573,21 @@ static struct kunit_suite cs_dsp_bin_err_test_halo = { .name = "cs_dsp_bin_err_halo", .init = cs_dsp_bin_err_test_halo_init, .exit = cs_dsp_bin_err_test_exit, - .test_cases = cs_dsp_bin_err_test_cases_halo, + .test_cases = cs_dsp_bin_err_test_cases, }; static struct kunit_suite cs_dsp_bin_err_test_adsp2_32bit = { .name = "cs_dsp_bin_err_adsp2_32bit", .init = cs_dsp_bin_err_test_adsp2_32bit_init, .exit = cs_dsp_bin_err_test_exit, - .test_cases = cs_dsp_bin_err_test_cases_adsp2, + .test_cases = cs_dsp_bin_err_test_cases, }; static struct kunit_suite cs_dsp_bin_err_test_adsp2_16bit = { .name = "cs_dsp_bin_err_adsp2_16bit", .init = cs_dsp_bin_err_test_adsp2_16bit_init, .exit = cs_dsp_bin_err_test_exit, - .test_cases = cs_dsp_bin_err_test_cases_adsp2, + .test_cases = cs_dsp_bin_err_test_cases, }; kunit_test_suites(&cs_dsp_bin_err_test_halo, From 42ae6e2559e63c2d4096b698cd47aaeb974436df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 11 Feb 2025 16:00:02 +0100 Subject: [PATCH 149/651] firmware: cs_dsp: test_control_parse: null-terminate test strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The char pointers in 'struct cs_dsp_mock_coeff_def' are expected to point to C strings. They need to be terminated by a null byte. However the code does not allocate that trailing null byte and only works if by chance the allocation is followed by such a null byte. Refactor the repeated string allocation logic into a new helper which makes sure the terminating null is always present. It also makes the code more readable. Signed-off-by: Thomas Weißschuh Fixes: 83baecd92e7c ("firmware: cs_dsp: Add KUnit testing of control parsing") Cc: stable@vger.kernel.org Reviewed-by: Richard Fitzgerald Tested-by: Richard Fitzgerald Link: https://patch.msgid.link/20250211-cs_dsp-kunit-strings-v1-1-d9bc2035d154@linutronix.de Signed-off-by: Mark Brown --- .../cirrus/test/cs_dsp_test_control_parse.c | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c b/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c index cb90964740ea..942ba1af5e7c 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c @@ -73,6 +73,18 @@ static const struct cs_dsp_mock_coeff_def mock_coeff_template = { .length_bytes = 4, }; +static char *cs_dsp_ctl_alloc_test_string(struct kunit *test, char c, size_t len) +{ + char *str; + + str = kunit_kmalloc(test, len + 1, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str); + memset(str, c, len); + str[len] = '\0'; + + return str; +} + /* Algorithm info block without controls should load */ static void cs_dsp_ctl_parse_no_coeffs(struct kunit *test) { @@ -160,12 +172,8 @@ static void cs_dsp_ctl_parse_max_v1_name(struct kunit *test) struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *name; - name = kunit_kzalloc(test, 256, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, name); - memset(name, 'A', 255); - def.fullname = name; + def.fullname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -252,14 +260,9 @@ static void cs_dsp_ctl_parse_max_short_name(struct kunit *test) struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; - char *name; struct firmware *wmfw; - name = kunit_kmalloc(test, 255, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, name); - memset(name, 'A', 255); - - def.shortname = name; + def.shortname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -273,7 +276,7 @@ static void cs_dsp_ctl_parse_max_short_name(struct kunit *test) ctl = list_first_entry_or_null(&priv->dsp->ctl_list, struct cs_dsp_coeff_ctl, list); KUNIT_ASSERT_NOT_NULL(test, ctl); KUNIT_EXPECT_EQ(test, ctl->subname_len, 255); - KUNIT_EXPECT_MEMEQ(test, ctl->subname, name, ctl->subname_len); + KUNIT_EXPECT_MEMEQ(test, ctl->subname, def.shortname, ctl->subname_len); KUNIT_EXPECT_EQ(test, ctl->flags, def.flags); KUNIT_EXPECT_EQ(test, ctl->type, def.type); KUNIT_EXPECT_EQ(test, ctl->len, def.length_bytes); @@ -323,12 +326,8 @@ static void cs_dsp_ctl_parse_with_max_fullname(struct kunit *test) struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *fullname; - fullname = kunit_kmalloc(test, 255, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fullname); - memset(fullname, 'A', 255); - def.fullname = fullname; + def.fullname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -392,12 +391,8 @@ static void cs_dsp_ctl_parse_with_max_description(struct kunit *test) struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *description; - description = kunit_kmalloc(test, 65535, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, description); - memset(description, 'A', 65535); - def.description = description; + def.description = cs_dsp_ctl_alloc_test_string(test, 'A', 65535); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -429,17 +424,9 @@ static void cs_dsp_ctl_parse_with_max_fullname_and_description(struct kunit *tes struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *fullname, *description; - fullname = kunit_kmalloc(test, 255, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fullname); - memset(fullname, 'A', 255); - def.fullname = fullname; - - description = kunit_kmalloc(test, 65535, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, description); - memset(description, 'A', 65535); - def.description = description; + def.fullname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); + def.description = cs_dsp_ctl_alloc_test_string(test, 'A', 65535); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, From 64899904d6103500ad01be7b763298dc939285ae Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Thu, 20 Feb 2025 13:01:56 +0100 Subject: [PATCH 150/651] ASoC: soc-core: Use str_yes_no() in snd_soc_close_delayed_work() Remove hard-coded strings by using the str_yes_no() helper function. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250220120156.1663-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ae7b3e39d5ff..3f97d1f132c6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -430,7 +431,7 @@ void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd) codec_dai->driver->playback.stream_name, snd_soc_dai_stream_active(codec_dai, playback) ? "active" : "inactive", - rtd->pop_wait ? "yes" : "no"); + str_yes_no(rtd->pop_wait)); /* are we waiting on this codec DAI stream */ if (rtd->pop_wait == 1) { From b47834ee4485bbdcc6d36f086ff61c3efd8870d4 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 20 Feb 2025 12:48:20 -0600 Subject: [PATCH 151/651] ASoC: SOF: amd: Add depends on CPU_SUP_AMD When SMN support was switched to the kernel wide AMD_NODE instead of local implementation this broke compilation on the allyesconfig for some architectures. AMD_NODE is only supported on AMD platforms, so modify all the AMD drivers that use it to also require CPU_SUP_AMD. Reported-by: Stephen Rothwell Closes: https://lore.kernel.org/linux-next/20250220160950.2cd64bdb@canb.auug.org.au/ Fixes: f120cf33d232 ("ASoC: SOF: amd: Use AMD_NODE") Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250220184822.916090-1-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/sof/amd/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/sof/amd/Kconfig b/sound/soc/sof/amd/Kconfig index 28216c8c1cf9..6eb5b2d14843 100644 --- a/sound/soc/sof/amd/Kconfig +++ b/sound/soc/sof/amd/Kconfig @@ -33,6 +33,7 @@ config SND_SOC_SOF_AMD_COMMON config SND_SOC_SOF_AMD_RENOIR tristate "SOF support for RENOIR" depends on SND_SOC_SOF_PCI + depends on CPU_SUP_AMD select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support on AMD Renoir platform @@ -40,6 +41,7 @@ config SND_SOC_SOF_AMD_RENOIR config SND_SOC_SOF_AMD_VANGOGH tristate "SOF support for VANGOGH" depends on SND_SOC_SOF_PCI + depends on CPU_SUP_AMD select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support @@ -50,6 +52,7 @@ config SND_SOC_SOF_AMD_VANGOGH config SND_SOC_SOF_AMD_REMBRANDT tristate "SOF support for REMBRANDT" depends on SND_SOC_SOF_PCI + depends on CPU_SUP_AMD select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support on AMD Rembrandt platform @@ -82,6 +85,7 @@ config SND_SOC_SOF_AMD_SOUNDWIRE config SND_SOC_SOF_AMD_ACP63 tristate "SOF support for ACP6.3 platform" depends on SND_SOC_SOF_PCI + depends on CPU_SUP_AMD select SND_SOC_SOF_AMD_COMMON select SND_SOC_SOF_AMD_SOUNDWIRE_LINK_BASELINE help @@ -93,6 +97,7 @@ config SND_SOC_SOF_AMD_ACP63 config SND_SOC_SOF_AMD_ACP70 tristate "SOF support for ACP7.0 platform" depends on SND_SOC_SOF_PCI + depends on CPU_SUP_AMD select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support on From 0f1f26c59196c785ced9f1a083ff350a6361c39f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 22 Feb 2025 12:41:29 +0100 Subject: [PATCH 152/651] ALSA: arm: aaci: Constify amba_id table 'struct amba_id' table is not modified so can be changed to const for more safety. Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250222114129.162794-1-krzysztof.kozlowski@linaro.org Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index c3340b8ff3da..243965615ef2 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -1061,7 +1061,7 @@ static void aaci_remove(struct amba_device *dev) } } -static struct amba_id aaci_ids[] = { +static const struct amba_id aaci_ids[] = { { .id = 0x00041041, .mask = 0x000fffff, From 2fa56dae1a65e8124d417a31d7b02c37df013817 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Sun, 23 Feb 2025 21:27:41 +0100 Subject: [PATCH 153/651] ASoC: fsl: fsl_qmc_audio: Remove unnecessary bool conversions Remove unnecessary bool conversions and simplify the code. Signed-off-by: Thorsten Blum Acked-by: Herve Codina Link: https://patch.msgid.link/20250223202741.1916-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_qmc_audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c index e257b8adafe0..b2979290c973 100644 --- a/sound/soc/fsl/fsl_qmc_audio.c +++ b/sound/soc/fsl/fsl_qmc_audio.c @@ -892,7 +892,7 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node * qmc_soc_dai_driver->playback.channels_max = count > 1 ? count : nb_tx_ts; } qmc_soc_dai_driver->playback.formats = qmc_audio_formats(nb_tx_ts, - count > 1 ? true : false); + count > 1); qmc_soc_dai_driver->capture.channels_min = 0; qmc_soc_dai_driver->capture.channels_max = 0; @@ -901,7 +901,7 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node * qmc_soc_dai_driver->capture.channels_max = count > 1 ? count : nb_rx_ts; } qmc_soc_dai_driver->capture.formats = qmc_audio_formats(nb_rx_ts, - count > 1 ? true : false); + count > 1); qmc_soc_dai_driver->playback.rates = snd_pcm_rate_to_rate_bit(tx_fs_rate); qmc_soc_dai_driver->playback.rate_min = tx_fs_rate; From 91b75129149429bb16927cda8b5642c04c59e6b0 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 21 Feb 2025 12:18:12 -0600 Subject: [PATCH 154/651] ASoC: SOF: amd: Move depends on AMD_NODE to consumers CONFIG_SND_SOC_SOF_AMD_COMMON is a hidden option that is only selected by other options. It can't have a direct depends on AMD_NODE because select can't pick another option automatically. This was attempted to be fixed in commit b47834ee4485b ("ASoC: SOF: amd: Add depends on CPU_SUP_AMD") but this just masked the issue as it was found in another config. Instead move the `depends on AMD_NODE` out of SND_SOC_SOF_AMD_COMMON to all the consumers and drop `depends on CPU_SUP_AMD`. Fixes: b47834ee4485b ("ASoC: SOF: amd: Add depends on CPU_SUP_AMD") Fixes: f120cf33d232 ("ASoC: SOF: amd: Use AMD_NODE") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202502220104.a8P6ApQN-lkp@intel.com/ Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250221181840.2639793-1-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/sof/amd/Kconfig | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sound/soc/sof/amd/Kconfig b/sound/soc/sof/amd/Kconfig index 6eb5b2d14843..3ea82fa72e35 100644 --- a/sound/soc/sof/amd/Kconfig +++ b/sound/soc/sof/amd/Kconfig @@ -25,7 +25,6 @@ config SND_SOC_SOF_AMD_COMMON select SND_SOC_SOF_ACP_PROBES select SND_SOC_ACPI_AMD_MATCH select SND_SOC_ACPI if ACPI - depends on AMD_NODE help This option is not user-selectable but automatically handled by 'select' statements at a higher level @@ -33,7 +32,7 @@ config SND_SOC_SOF_AMD_COMMON config SND_SOC_SOF_AMD_RENOIR tristate "SOF support for RENOIR" depends on SND_SOC_SOF_PCI - depends on CPU_SUP_AMD + depends on AMD_NODE select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support on AMD Renoir platform @@ -41,7 +40,7 @@ config SND_SOC_SOF_AMD_RENOIR config SND_SOC_SOF_AMD_VANGOGH tristate "SOF support for VANGOGH" depends on SND_SOC_SOF_PCI - depends on CPU_SUP_AMD + depends on AMD_NODE select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support @@ -52,7 +51,7 @@ config SND_SOC_SOF_AMD_VANGOGH config SND_SOC_SOF_AMD_REMBRANDT tristate "SOF support for REMBRANDT" depends on SND_SOC_SOF_PCI - depends on CPU_SUP_AMD + depends on AMD_NODE select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support on AMD Rembrandt platform @@ -85,7 +84,7 @@ config SND_SOC_SOF_AMD_SOUNDWIRE config SND_SOC_SOF_AMD_ACP63 tristate "SOF support for ACP6.3 platform" depends on SND_SOC_SOF_PCI - depends on CPU_SUP_AMD + depends on AMD_NODE select SND_SOC_SOF_AMD_COMMON select SND_SOC_SOF_AMD_SOUNDWIRE_LINK_BASELINE help @@ -97,7 +96,7 @@ config SND_SOC_SOF_AMD_ACP63 config SND_SOC_SOF_AMD_ACP70 tristate "SOF support for ACP7.0 platform" depends on SND_SOC_SOF_PCI - depends on CPU_SUP_AMD + depends on AMD_NODE select SND_SOC_SOF_AMD_COMMON help Select this option for SOF support on From 88e09306b7e0f8a9e9f9c729ac13ccd11ed9679d Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Sat, 22 Feb 2025 23:59:25 +0100 Subject: [PATCH 155/651] ASoC: atmel: atmel-classd: Use str_enabled_disabled() helper Remove hard-coded strings by using the str_enabled_disabled() helper function. Signed-off-by: Thorsten Blum Reviewed-by: Andrei Simion Link: https://patch.msgid.link/20250222225925.539840-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-classd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index ba314b279919..1f8c60d2de82 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -275,7 +276,7 @@ static int atmel_classd_component_probe(struct snd_soc_component *component) dev_info(component->dev, "PWM modulation type is %s, non-overlapping is %s\n", pwm_type[pdata->pwm_type], - pdata->non_overlap_enable?"enabled":"disabled"); + str_enabled_disabled(pdata->non_overlap_enable)); return 0; } From 10efa807929084a8a1c38655942a3bf83bce587a Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Thu, 20 Feb 2025 13:01:01 +0100 Subject: [PATCH 156/651] ASoC: cros_ec_codec: Use str_enable_disable() helper in wov_enable_put() Remove hard-coded strings by using the str_enable_disable() helper function. Signed-off-by: Thorsten Blum Acked-by: Tzung-Bi Shih Link: https://patch.msgid.link/20250220120100.1530-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/codecs/cros_ec_codec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 11e7b3f6d410..571222ec520c 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -657,7 +658,7 @@ static int wov_enable_put(struct snd_kcontrol *kcontrol, (uint8_t *)&p, sizeof(p), NULL, 0); if (ret) { dev_err(priv->dev, "failed to %s wov\n", - enabled ? "enable" : "disable"); + str_enable_disable(enabled)); return ret; } From 8c6ede5cc4226fd841f252d02ab0372cb92ee75c Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 17 Feb 2025 10:17:14 +0800 Subject: [PATCH 157/651] ASoC: dt-bindings: imx-card: Add playback-only and capture-only property Refer to audio graph card, add playback-only and capture-only property for imx-audio-card.yaml for the case that only playback or capture is supported. Signed-off-by: Shengjiu Wang Reviewed-by: Daniel Baluta Reviewed-by: Iuliana Prodan Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250217021715.284951-2-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/imx-audio-card.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml index f7ad5ea2491e..3c75c8c78987 100644 --- a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml +++ b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml @@ -46,6 +46,14 @@ patternProperties: description: see tdm-slot.txt. $ref: /schemas/types.yaml#/definitions/uint32 + playback-only: + description: link is used only for playback + $ref: /schemas/types.yaml#/definitions/flag + + capture-only: + description: link is used only for capture + $ref: /schemas/types.yaml#/definitions/flag + cpu: description: Holds subnode which indicates cpu dai. type: object @@ -71,6 +79,12 @@ patternProperties: - link-name - cpu + allOf: + - not: + required: + - playback-only + - capture-only + additionalProperties: false required: From 1877c3e7937fb2b9373ba263a4900448d50917b7 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 17 Feb 2025 10:17:15 +0800 Subject: [PATCH 158/651] ASoC: imx-card: Add playback_only or capture_only support With the DPCM case, the backend only support capture or playback, then the linked frontend can only support capture or playback, but frontend can't automatically enable only capture or playback, it needs the input from dt-binding. Signed-off-by: Shengjiu Wang Reviewed-by: Daniel Baluta Reviewed-by: Iuliana Prodan Link: https://patch.msgid.link/20250217021715.284951-3-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/imx-card.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index ac043ad367ac..905294682996 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -518,6 +518,7 @@ static int imx_card_parse_of(struct imx_card_data *data) struct snd_soc_dai_link *link; struct dai_link_data *link_data; struct of_phandle_args args; + bool playback_only, capture_only; int ret, num_links; u32 asrc_fmt = 0; u32 width; @@ -679,6 +680,10 @@ static int imx_card_parse_of(struct imx_card_data *data) link->ops = &imx_aif_ops; } + graph_util_parse_link_direction(np, &playback_only, &capture_only); + link->playback_only = playback_only; + link->capture_only = capture_only; + /* Get dai fmt */ ret = simple_util_parse_daifmt(dev, np, codec, NULL, &link->dai_fmt); From 758beab0252912395efb79f34095c5ae7e3e58b1 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:06 +0100 Subject: [PATCH 159/651] ASoC: topology: Create kcontrols based on their type Fields ->ops.info and ->type of struct snd_soc_tplg_ctl_hdr denote info-operation type and control type respectively. These are two different pieces of information. The info type is represented by SND_SOC_TPLG_CTL_xxx and SND_SOC_TPLG_DAPM_CTL_xxx on UAPI side whereas for control type it is SND_SOC_TPLG_TYPE_xxx (mixer, bytes or enum). The type of the kcontrol to be created is currently guessed based on the value of the ->ops.info. Use the ->type instead to correct and simplify the code. With this change ops.info() can be customized by sound drivers utilizing the ASoC-topology just like ops.get() and ops.put() can be. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 58 +++++++++++----------------------------- 1 file changed, 16 insertions(+), 42 deletions(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 9f4da061eff9..921521a84e29 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -220,15 +220,6 @@ static int get_widget_id(int tplg_type) return -EINVAL; } -static inline void soc_bind_err(struct soc_tplg *tplg, - struct snd_soc_tplg_ctl_hdr *hdr, int index) -{ - dev_err(tplg->dev, - "ASoC: invalid control type (g,p,i) %d:%d:%d index %d at 0x%lx\n", - hdr->ops.get, hdr->ops.put, hdr->ops.info, index, - soc_tplg_get_offset(tplg)); -} - static inline void soc_control_err(struct soc_tplg *tplg, struct snd_soc_tplg_ctl_hdr *hdr, const char *name) { @@ -992,35 +983,26 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg, return -EINVAL; } - switch (le32_to_cpu(control_hdr->ops.info)) { - case SND_SOC_TPLG_CTL_VOLSW: - case SND_SOC_TPLG_CTL_STROBE: - case SND_SOC_TPLG_CTL_VOLSW_SX: - case SND_SOC_TPLG_CTL_VOLSW_XR_SX: - case SND_SOC_TPLG_CTL_RANGE: - case SND_SOC_TPLG_DAPM_CTL_VOLSW: - case SND_SOC_TPLG_DAPM_CTL_PIN: + switch (le32_to_cpu(control_hdr->type)) { + case SND_SOC_TPLG_TYPE_MIXER: ret = soc_tplg_dmixer_create(tplg, le32_to_cpu(hdr->payload_size)); break; - case SND_SOC_TPLG_CTL_ENUM: - case SND_SOC_TPLG_CTL_ENUM_VALUE: - case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: - case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: - case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: + case SND_SOC_TPLG_TYPE_ENUM: ret = soc_tplg_denum_create(tplg, le32_to_cpu(hdr->payload_size)); break; - case SND_SOC_TPLG_CTL_BYTES: + case SND_SOC_TPLG_TYPE_BYTES: ret = soc_tplg_dbytes_create(tplg, le32_to_cpu(hdr->payload_size)); break; default: - soc_bind_err(tplg, control_hdr, i); - return -EINVAL; - } - if (ret < 0) { - dev_err(tplg->dev, "ASoC: invalid control\n"); - return ret; + ret = -EINVAL; + break; } + if (ret < 0) { + dev_err(tplg->dev, "ASoC: invalid control type: %d, index: %d at 0x%lx\n", + control_hdr->type, i, soc_tplg_get_offset(tplg)); + return ret; + } } return 0; @@ -1184,13 +1166,9 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, for (i = 0; i < le32_to_cpu(w->num_kcontrols); i++) { control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; - switch (le32_to_cpu(control_hdr->ops.info)) { - case SND_SOC_TPLG_CTL_VOLSW: - case SND_SOC_TPLG_CTL_STROBE: - case SND_SOC_TPLG_CTL_VOLSW_SX: - case SND_SOC_TPLG_CTL_VOLSW_XR_SX: - case SND_SOC_TPLG_CTL_RANGE: - case SND_SOC_TPLG_DAPM_CTL_VOLSW: + + switch (le32_to_cpu(control_hdr->type)) { + case SND_SOC_TPLG_TYPE_MIXER: /* volume mixer */ kc[i].index = mixer_count; kcontrol_type[i] = SND_SOC_TPLG_TYPE_MIXER; @@ -1199,11 +1177,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, if (ret < 0) goto hdr_err; break; - case SND_SOC_TPLG_CTL_ENUM: - case SND_SOC_TPLG_CTL_ENUM_VALUE: - case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: - case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: - case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: + case SND_SOC_TPLG_TYPE_ENUM: /* enumerated mixer */ kc[i].index = enum_count; kcontrol_type[i] = SND_SOC_TPLG_TYPE_ENUM; @@ -1212,7 +1186,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, if (ret < 0) goto hdr_err; break; - case SND_SOC_TPLG_CTL_BYTES: + case SND_SOC_TPLG_TYPE_BYTES: /* bytes control */ kc[i].index = bytes_count; kcontrol_type[i] = SND_SOC_TPLG_TYPE_BYTES; From 81eb3a2bd273b84fa9808e6b13b533f9c55e16eb Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:07 +0100 Subject: [PATCH 160/651] ASoC: topology: Save num_channels value for mixer controls To provide minimal support for multi-channel kcontrols i.e.: more than stereo configuration, store the number of channels specified within the SectionControlMixer. The field is part of the topology standard, currently skipped by the ASoC core. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-topology.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 644cfe26022e..6bb2fca044c5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1254,6 +1254,7 @@ struct soc_mixer_control { int min, max, platform_max; int reg, rreg; unsigned int shift, rshift; + u32 num_channels; unsigned int sign_bit; unsigned int invert:1; unsigned int autodisable:1; diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 921521a84e29..2b86cc3311f7 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -669,6 +669,7 @@ static int soc_tplg_control_dmixer_create(struct soc_tplg *tplg, struct snd_kcon sm->min = le32_to_cpu(mc->min); sm->invert = le32_to_cpu(mc->invert); sm->platform_max = le32_to_cpu(mc->platform_max); + sm->num_channels = le32_to_cpu(mc->num_channels); /* map io handlers */ err = soc_tplg_kcontrol_bind_io(&mc->hdr, kc, tplg); From 28feec15fa285e561c626b3490bc5a10f5d177c8 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:08 +0100 Subject: [PATCH 161/651] ASoC: Intel: avs: Make PEAKVOL configurable from topology The driver exposes volume kcontrols if PEAKVOL/GAIN module is present in the streaming path. Currently there is no control over their default values including the effect that may accompany the volume change event. Add template for PEAKVOL/GAIN module which holds all the information needed to address the limitation. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- include/uapi/sound/intel/avs/tokens.h | 4 ++++ sound/soc/intel/avs/path.c | 4 ++-- sound/soc/intel/avs/topology.c | 18 ++++++++++++++++++ sound/soc/intel/avs/topology.h | 5 +++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/uapi/sound/intel/avs/tokens.h b/include/uapi/sound/intel/avs/tokens.h index 06ff30537f47..c9f845b3c523 100644 --- a/include/uapi/sound/intel/avs/tokens.h +++ b/include/uapi/sound/intel/avs/tokens.h @@ -84,6 +84,10 @@ enum avs_tplg_token { AVS_TKN_MODCFG_WHM_DMA_TYPE_U32 = 437, AVS_TKN_MODCFG_WHM_DMABUFF_SIZE_U32 = 438, AVS_TKN_MODCFG_WHM_BLOB_AFMT_ID_U32 = 439, + AVS_TKN_MODCFG_PEAKVOL_VOLUME_U32 = 440, + AVS_TKN_MODCFG_PEAKVOL_CHANNEL_ID_U32 = 441, /* reserved */ + AVS_TKN_MODCFG_PEAKVOL_CURVE_TYPE_U32 = 442, + AVS_TKN_MODCFG_PEAKVOL_CURVE_DURATION_U32 = 443, /* struct avs_tplg_pplcfg */ AVS_TKN_PPLCFG_ID_U32 = 1401, diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index dfb85bd2b665..329838119015 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -350,8 +350,8 @@ static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) cfg->base.audio_fmt = *t->in_fmt; cfg->vols[0].target_volume = volume; cfg->vols[0].channel_id = AVS_ALL_CHANNELS_MASK; - cfg->vols[0].curve_type = AVS_AUDIO_CURVE_NONE; - cfg->vols[0].curve_duration = 0; + cfg->vols[0].curve_type = t->cfg_ext->peakvol.curve_type; + cfg->vols[0].curve_duration = t->cfg_ext->peakvol.curve_duration; ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id, t->domain, cfg, cfg_size, &mod->instance_id); diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 471b00b9a149..45952fbe9694 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -857,6 +857,24 @@ static const struct avs_tplg_token_parser modcfg_ext_parsers[] = { .offset = offsetof(struct avs_tplg_modcfg_ext, whm.blob_fmt), .parse = avs_parse_audio_format_ptr, }, + { + .token = AVS_TKN_MODCFG_PEAKVOL_VOLUME_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, peakvol.target_volume), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_MODCFG_PEAKVOL_CURVE_TYPE_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, peakvol.curve_type), + .parse = avs_parse_word_token, + }, + { + .token = AVS_TKN_MODCFG_PEAKVOL_CURVE_DURATION_U32, + .type = SND_SOC_TPLG_TUPLE_TYPE_WORD, + .offset = offsetof(struct avs_tplg_modcfg_ext, peakvol.curve_duration), + .parse = avs_parse_word_token, + }, }; static const struct avs_tplg_token_parser pin_format_parsers[] = { diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h index 23d5ccd19959..304880997717 100644 --- a/sound/soc/intel/avs/topology.h +++ b/sound/soc/intel/avs/topology.h @@ -113,6 +113,11 @@ struct avs_tplg_modcfg_ext { struct { struct avs_audio_format *out_fmt; } micsel; + struct { + u32 target_volume; + u32 curve_type; + u32 curve_duration; + } peakvol; }; }; From 4c43a930e3e165ca6890147a309508ccb6768faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Mon, 17 Feb 2025 11:21:09 +0100 Subject: [PATCH 162/651] ASoC: Intel: avs: Add volume control for GAIN module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AudioDSP firmware's GAIN module has same initialization payload as PEAKVOL and user volume setting can be applied up-front. Update existing code to account for PEAKVOL and GAIN both. Signed-off-by: Amadeusz SÅ‚awiÅ„ski Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/control.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c index dc7dc45e0a0a..a55723289600 100644 --- a/sound/soc/intel/avs/control.c +++ b/sound/soc/intel/avs/control.c @@ -31,8 +31,11 @@ static struct avs_path_module *avs_get_volume_module(struct avs_dev *adev, u32 i list_for_each_entry(path, &adev->path_list, node) { list_for_each_entry(ppl, &path->ppl_list, node) { list_for_each_entry(mod, &ppl->mod_list, node) { - if (guid_equal(&mod->template->cfg_ext->type, &AVS_PEAKVOL_MOD_UUID) - && mod->template->ctl_id == id) { + guid_t *type = &mod->template->cfg_ext->type; + + if ((guid_equal(type, &AVS_PEAKVOL_MOD_UUID) || + guid_equal(type, &AVS_GAIN_MOD_UUID)) && + mod->template->ctl_id == id) { spin_unlock(&adev->path_list_lock); return mod; } From 10188a25c9b5944c0a912482011b484b7c2e22d4 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:10 +0100 Subject: [PATCH 163/651] ASoC: Intel: avs: Update VOLUME and add MUTE IPCs For mute kcontrols to have an effect add IPCs for triggering the mute operation on the DSP side. On top of basic get/set, an aggregated variant of the latter is provided for both MUTE and, to already present VOLUME IPC. It allows for efficient transmission of multiple parameters at once. While at it, sort the functions - getters come before setters in the AudioDSP firmware interface as well as in the kcontrol one. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/messages.c | 111 ++++++++++++++++++++++++++++++--- sound/soc/intel/avs/messages.h | 24 ++++++- 2 files changed, 126 insertions(+), 9 deletions(-) diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index 242a175381c2..a5ba27983091 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -677,13 +677,6 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id, (u8 *)&cpr_fmt, sizeof(cpr_fmt)); } -int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id, - struct avs_volume_cfg *vol) -{ - return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, (u8 *)vol, - sizeof(*vol)); -} - int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id, struct avs_volume_cfg **vols, size_t *num_vols) { @@ -706,6 +699,110 @@ int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_ return 0; } +int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_volume_cfg *vol) +{ + return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, + (u8 *)vol, sizeof(*vol)); +} + +int avs_ipc_peakvol_set_volumes(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_volume_cfg *vols, size_t num_vols) +{ + struct avs_tlv *tlv; + size_t offset; + size_t size; + u8 *payload; + int ret, i; + + size = num_vols * sizeof(*vols); + size += num_vols * sizeof(*tlv); + if (size > AVS_MAILBOX_SIZE) + return -EINVAL; + + payload = kzalloc(AVS_MAILBOX_SIZE, GFP_KERNEL); + if (!payload) + return -ENOMEM; + + for (offset = i = 0; i < num_vols; i++) { + tlv = (struct avs_tlv *)(payload + offset); + + tlv->type = AVS_PEAKVOL_VOLUME; + tlv->length = sizeof(*vols); + memcpy(tlv->value, &vols[i], tlv->length); + + offset += sizeof(*tlv) + tlv->length; + } + + ret = avs_ipc_set_large_config(adev, module_id, instance_id, AVS_VENDOR_CONFIG, payload, + size); + kfree(payload); + return ret; +} + +int avs_ipc_peakvol_get_mute(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_mute_cfg **mutes, size_t *num_mutes) +{ + size_t payload_size; + u8 *payload; + int ret; + + ret = avs_ipc_get_large_config(adev, module_id, instance_id, AVS_PEAKVOL_MUTE, NULL, 0, + &payload, &payload_size); + if (ret) + return ret; + + /* Non-zero payload expected for PEAKVOL_MUTE. */ + if (!payload_size) + return -EREMOTEIO; + + *mutes = (struct avs_mute_cfg *)payload; + *num_mutes = payload_size / sizeof(**mutes); + + return 0; +} + +int avs_ipc_peakvol_set_mute(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_mute_cfg *mute) +{ + return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_MUTE, + (u8 *)mute, sizeof(*mute)); +} + +int avs_ipc_peakvol_set_mutes(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_mute_cfg *mutes, size_t num_mutes) +{ + struct avs_tlv *tlv; + size_t offset; + size_t size; + u8 *payload; + int ret, i; + + size = num_mutes * sizeof(*mutes); + size += num_mutes * sizeof(*tlv); + if (size > AVS_MAILBOX_SIZE) + return -EINVAL; + + payload = kzalloc(AVS_MAILBOX_SIZE, GFP_KERNEL); + if (!payload) + return -ENOMEM; + + for (offset = i = 0; i < num_mutes; i++) { + tlv = (struct avs_tlv *)(payload + offset); + + tlv->type = AVS_PEAKVOL_MUTE; + tlv->length = sizeof(*mutes); + memcpy(tlv->value, &mutes[i], tlv->length); + + offset += sizeof(*tlv) + tlv->length; + } + + ret = avs_ipc_set_large_config(adev, module_id, instance_id, AVS_VENDOR_CONFIG, payload, + size); + kfree(payload); + return ret; +} + #ifdef CONFIG_DEBUG_FS int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size) { diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h index f44fcfc81de7..2f243802ccc2 100644 --- a/sound/soc/intel/avs/messages.h +++ b/sound/soc/intel/avs/messages.h @@ -814,6 +814,15 @@ struct avs_volume_cfg { } __packed; static_assert(sizeof(struct avs_volume_cfg) == 24); +struct avs_mute_cfg { + u32 channel_id; + u32 mute; + u32 curve_type; + u32 reserved; /* alignment */ + u64 curve_duration; +} __packed; +static_assert(sizeof(struct avs_mute_cfg) == 24); + struct avs_peakvol_cfg { struct avs_modcfg_base base; struct avs_volume_cfg vols[]; @@ -896,6 +905,8 @@ static_assert(sizeof(struct avs_whm_cfg) == 108); /* Module runtime parameters */ +#define AVS_VENDOR_CONFIG 0xFF + enum avs_copier_runtime_param { AVS_COPIER_SET_SINK_FORMAT = 2, }; @@ -914,6 +925,7 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id, enum avs_peakvol_runtime_param { AVS_PEAKVOL_VOLUME = 0, + AVS_PEAKVOL_MUTE = 3, }; enum avs_audio_curve_type { @@ -921,10 +933,18 @@ enum avs_audio_curve_type { AVS_AUDIO_CURVE_WINDOWS_FADE = 1, }; -int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id, - struct avs_volume_cfg *vol); int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id, struct avs_volume_cfg **vols, size_t *num_vols); +int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_volume_cfg *vol); +int avs_ipc_peakvol_set_volumes(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_volume_cfg *vols, size_t num_vols); +int avs_ipc_peakvol_get_mute(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_mute_cfg **mutes, size_t *num_mutes); +int avs_ipc_peakvol_set_mute(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_mute_cfg *mute); +int avs_ipc_peakvol_set_mutes(struct avs_dev *adev, u16 module_id, u8 instance_id, + struct avs_mute_cfg *mutes, size_t num_mutes); #define AVS_PROBE_INST_ID 0 From c321a4d705a31a50d7580516422aaa5b853e7602 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:11 +0100 Subject: [PATCH 164/651] ASoC: Intel: avs: New volume control operations To provide multi-channel - more than 2 - capability to volume controls implement operations that honor the num_channels of a mixer control. As mc->num_channels can be 0 and is in fact the default behavior, the new functions decide between ALL_CHANNELS_MASK and individual channels based on the field value. To avoid hard-to-review delta when refactoring the code, first implement the new behavior with follow up changes cleaning things up. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/control.c | 84 +++++++++++++++++++++++++++++++++++ sound/soc/intel/avs/control.h | 5 +++ sound/soc/intel/avs/path.c | 36 +++++++++++++++ sound/soc/intel/avs/path.h | 3 ++ 4 files changed, 128 insertions(+) diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c index a55723289600..a1c7431cfe13 100644 --- a/sound/soc/intel/avs/control.c +++ b/sound/soc/intel/avs/control.c @@ -6,6 +6,7 @@ // Cezary Rojewski // +#include #include #include "avs.h" #include "control.h" @@ -114,3 +115,86 @@ int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va return ret ? ret : changed; } + +int avs_control_volume_get2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; + struct avs_control_data *ctl_data = mc->dobj.private; + struct avs_path_module *active_module; + struct avs_volume_cfg *dspvols; + struct avs_dev *adev; + size_t num_dspvols; + int ret, i; + + adev = avs_get_kcontrol_adev(kctl); + + /* Prevent access to modules while path is being constructed. */ + guard(mutex)(&adev->path_mutex); + + active_module = avs_get_volume_module(adev, ctl_data->id); + if (active_module) { + ret = avs_ipc_peakvol_get_volume(adev, active_module->module_id, + active_module->instance_id, &dspvols, + &num_dspvols); + if (ret) + return AVS_IPC_RET(ret); + + /* Do not copy more than the control can store. */ + num_dspvols = min_t(u32, num_dspvols, SND_SOC_TPLG_MAX_CHAN); + for (i = 0; i < num_dspvols; i++) + ctl_data->values[i] = dspvols[i].target_volume; + kfree(dspvols); + } + + memcpy(uctl->value.integer.value, ctl_data->values, sizeof(ctl_data->values)); + return 0; +} + +int avs_control_volume_put2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) +{ + struct avs_path_module *active_module; + struct avs_control_data *ctl_data; + struct soc_mixer_control *mc; + struct avs_dev *adev; + long *input; + int ret, i; + + mc = (struct soc_mixer_control *)kctl->private_value; + ctl_data = mc->dobj.private; + adev = avs_get_kcontrol_adev(kctl); + input = uctl->value.integer.value; + i = 0; + + /* mc->num_channels can be 0. */ + do { + if (input[i] < mc->min || input[i] > mc->max) + return -EINVAL; + } while (++i < mc->num_channels); + + if (!memcmp(ctl_data->values, input, sizeof(ctl_data->values))) + return 0; + + /* Prevent access to modules while path is being constructed. */ + guard(mutex)(&adev->path_mutex); + + active_module = avs_get_volume_module(adev, ctl_data->id); + if (active_module) { + ret = avs_peakvol_set_volume(adev, active_module, mc, input); + if (ret) + return ret; + } + + memcpy(ctl_data->values, input, sizeof(ctl_data->values)); + return 1; +} + +int avs_control_volume_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = max_t(u32, 1, mc->num_channels); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mc->max; + return 0; +} diff --git a/sound/soc/intel/avs/control.h b/sound/soc/intel/avs/control.h index d9fac3569e8d..e16fa79962de 100644 --- a/sound/soc/intel/avs/control.h +++ b/sound/soc/intel/avs/control.h @@ -10,14 +10,19 @@ #define __SOUND_SOC_INTEL_AVS_CTRL_H #include +#include struct avs_control_data { u32 id; long volume; + long values[SND_SOC_TPLG_MAX_CHAN]; }; int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +int avs_control_volume_get2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); +int avs_control_volume_put2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); +int avs_control_volume_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo); #endif diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index 329838119015..a72ebde7d011 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -323,6 +323,42 @@ static struct avs_control_data *avs_get_module_control(struct avs_path_module *m return NULL; } +int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod, + struct soc_mixer_control *mc, long *input) +{ + struct avs_volume_cfg vols[SND_SOC_TPLG_MAX_CHAN] = {{0}}; + struct avs_control_data *ctl_data; + struct avs_tplg_module *t; + int ret, i; + + ctl_data = mc->dobj.private; + t = mod->template; + if (!input) + input = ctl_data->values; + + if (mc->num_channels) { + for (i = 0; i < mc->num_channels; i++) { + vols[i].channel_id = i; + vols[i].target_volume = input[i]; + vols[i].curve_type = t->cfg_ext->peakvol.curve_type; + vols[i].curve_duration = t->cfg_ext->peakvol.curve_duration; + } + + ret = avs_ipc_peakvol_set_volumes(adev, mod->module_id, mod->instance_id, vols, + mc->num_channels); + return AVS_IPC_RET(ret); + } + + /* Target all channels if no individual selected. */ + vols[0].channel_id = AVS_ALL_CHANNELS_MASK; + vols[0].target_volume = input[0]; + vols[0].curve_type = t->cfg_ext->peakvol.curve_type; + vols[0].curve_duration = t->cfg_ext->peakvol.curve_duration; + + ret = avs_ipc_peakvol_set_volume(adev, mod->module_id, mod->instance_id, &vols[0]); + return AVS_IPC_RET(ret); +} + static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) { struct avs_tplg_module *t = mod->template; diff --git a/sound/soc/intel/avs/path.h b/sound/soc/intel/avs/path.h index bfd253c9fa95..e9317b64de86 100644 --- a/sound/soc/intel/avs/path.h +++ b/sound/soc/intel/avs/path.h @@ -69,4 +69,7 @@ int avs_path_reset(struct avs_path *path); int avs_path_pause(struct avs_path *path); int avs_path_run(struct avs_path *path, int trigger); +int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod, + struct soc_mixer_control *mc, long *input); + #endif From 4c32ebcc8650ce506632a32136993c85537fb01a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:12 +0100 Subject: [PATCH 165/651] ASoC: Intel: avs: Move to the new control operations Allow for multi-channel volume controls to be utilized by an application by moving over to the new implementation. Drop all unused code in the process. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/control.c | 72 +--------------------------------- sound/soc/intel/avs/control.h | 8 +--- sound/soc/intel/avs/path.c | 2 +- sound/soc/intel/avs/topology.c | 1 + 4 files changed, 6 insertions(+), 77 deletions(-) diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c index a1c7431cfe13..64283aa35281 100644 --- a/sound/soc/intel/avs/control.c +++ b/sound/soc/intel/avs/control.c @@ -48,75 +48,7 @@ static struct avs_path_module *avs_get_volume_module(struct avs_dev *adev, u32 i return NULL; } -int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private; - struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol); - struct avs_volume_cfg *dspvols = NULL; - struct avs_path_module *active_module; - size_t num_dspvols; - int ret = 0; - - /* prevent access to modules while path is being constructed */ - mutex_lock(&adev->path_mutex); - - active_module = avs_get_volume_module(adev, ctl_data->id); - if (active_module) { - ret = avs_ipc_peakvol_get_volume(adev, active_module->module_id, - active_module->instance_id, &dspvols, - &num_dspvols); - if (!ret) - ucontrol->value.integer.value[0] = dspvols[0].target_volume; - - ret = AVS_IPC_RET(ret); - kfree(dspvols); - } else { - ucontrol->value.integer.value[0] = ctl_data->volume; - } - - mutex_unlock(&adev->path_mutex); - return ret; -} - -int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private; - struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol); - long *volume = &ctl_data->volume; - struct avs_path_module *active_module; - struct avs_volume_cfg dspvol = {0}; - long ctlvol = ucontrol->value.integer.value[0]; - int ret = 0, changed = 0; - - if (ctlvol < 0 || ctlvol > mc->max) - return -EINVAL; - - /* prevent access to modules while path is being constructed */ - mutex_lock(&adev->path_mutex); - - if (*volume != ctlvol) { - *volume = ctlvol; - changed = 1; - } - - active_module = avs_get_volume_module(adev, ctl_data->id); - if (active_module) { - dspvol.channel_id = AVS_ALL_CHANNELS_MASK; - dspvol.target_volume = *volume; - - ret = avs_ipc_peakvol_set_volume(adev, active_module->module_id, - active_module->instance_id, &dspvol); - ret = AVS_IPC_RET(ret); - } - - mutex_unlock(&adev->path_mutex); - - return ret ? ret : changed; -} - -int avs_control_volume_get2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) +int avs_control_volume_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; struct avs_control_data *ctl_data = mc->dobj.private; @@ -150,7 +82,7 @@ int avs_control_volume_get2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value return 0; } -int avs_control_volume_put2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) +int avs_control_volume_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { struct avs_path_module *active_module; struct avs_control_data *ctl_data; diff --git a/sound/soc/intel/avs/control.h b/sound/soc/intel/avs/control.h index e16fa79962de..66f3fe064e1d 100644 --- a/sound/soc/intel/avs/control.h +++ b/sound/soc/intel/avs/control.h @@ -14,15 +14,11 @@ struct avs_control_data { u32 id; - - long volume; long values[SND_SOC_TPLG_MAX_CHAN]; }; -int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int avs_control_volume_get2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); -int avs_control_volume_put2(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); +int avs_control_volume_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); +int avs_control_volume_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); int avs_control_volume_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo); #endif diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index a72ebde7d011..56a2916eec5e 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -370,7 +370,7 @@ static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) ctl_data = avs_get_module_control(mod); if (ctl_data) - volume = ctl_data->volume; + volume = ctl_data->values[0]; /* As 2+ channels controls are unsupported, have a single block for all channels. */ cfg_size = struct_size(cfg, vols, 1); diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 45952fbe9694..ee70e3d0e889 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -1912,6 +1912,7 @@ static const struct snd_soc_tplg_kcontrol_ops avs_control_ops[] = { .id = AVS_CONTROL_OPS_VOLUME, .get = avs_control_volume_get, .put = avs_control_volume_put, + .info = avs_control_volume_info, }, }; From a4217a03686989c4a79530fe54fa17576aff7330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Mon, 17 Feb 2025 11:21:13 +0100 Subject: [PATCH 166/651] ASoC: Intel: avs: Add support for mute for PEAKVOL and GAIN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With recent updates to AudioDSP firmware, mute functionality has been added to PEAKVOL and GAIN modules. The operation occurs over IPC similarly to how volume is configured. Wire it up to kcontrol infrastructure present in the avs-driver. Signed-off-by: Amadeusz SÅ‚awiÅ„ski Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/control.c | 83 ++++++++++++++++++++++++++++++++++ sound/soc/intel/avs/control.h | 3 ++ sound/soc/intel/avs/path.c | 36 +++++++++++++++ sound/soc/intel/avs/path.h | 2 + sound/soc/intel/avs/topology.c | 11 ++++- 5 files changed, 134 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c index 64283aa35281..2e01dc75a15a 100644 --- a/sound/soc/intel/avs/control.c +++ b/sound/soc/intel/avs/control.c @@ -130,3 +130,86 @@ int avs_control_volume_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info uinfo->value.integer.max = mc->max; return 0; } + +int avs_control_mute_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; + struct avs_control_data *ctl_data = mc->dobj.private; + struct avs_path_module *active_module; + struct avs_mute_cfg *dspmutes; + struct avs_dev *adev; + size_t num_dspmutes; + int ret, i; + + adev = avs_get_kcontrol_adev(kctl); + + /* Prevent access to modules while path is being constructed. */ + guard(mutex)(&adev->path_mutex); + + active_module = avs_get_volume_module(adev, ctl_data->id); + if (active_module) { + ret = avs_ipc_peakvol_get_mute(adev, active_module->module_id, + active_module->instance_id, &dspmutes, + &num_dspmutes); + if (ret) + return AVS_IPC_RET(ret); + + /* Do not copy more than the control can store. */ + num_dspmutes = min_t(u32, num_dspmutes, SND_SOC_TPLG_MAX_CHAN); + for (i = 0; i < num_dspmutes; i++) + ctl_data->values[i] = !dspmutes[i].mute; + kfree(dspmutes); + } + + memcpy(uctl->value.integer.value, ctl_data->values, sizeof(ctl_data->values)); + return 0; +} + +int avs_control_mute_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) +{ + struct avs_path_module *active_module; + struct avs_control_data *ctl_data; + struct soc_mixer_control *mc; + struct avs_dev *adev; + long *input; + int ret, i; + + mc = (struct soc_mixer_control *)kctl->private_value; + ctl_data = mc->dobj.private; + adev = avs_get_kcontrol_adev(kctl); + input = uctl->value.integer.value; + i = 0; + + /* mc->num_channels can be 0. */ + do { + if (input[i] < mc->min || input[i] > mc->max) + return -EINVAL; + } while (++i < mc->num_channels); + + if (!memcmp(ctl_data->values, input, sizeof(ctl_data->values))) + return 0; + + /* Prevent access to modules while path is being constructed. */ + guard(mutex)(&adev->path_mutex); + + active_module = avs_get_volume_module(adev, ctl_data->id); + if (active_module) { + ret = avs_peakvol_set_mute(adev, active_module, mc, input); + if (ret) + return ret; + } + + memcpy(ctl_data->values, input, sizeof(ctl_data->values)); + return 1; +} + +int avs_control_mute_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = max_t(u32, 1, mc->num_channels); + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mc->max; + return 0; +} diff --git a/sound/soc/intel/avs/control.h b/sound/soc/intel/avs/control.h index 66f3fe064e1d..08b2919e4629 100644 --- a/sound/soc/intel/avs/control.h +++ b/sound/soc/intel/avs/control.h @@ -20,5 +20,8 @@ struct avs_control_data { int avs_control_volume_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); int avs_control_volume_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); int avs_control_volume_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo); +int avs_control_mute_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); +int avs_control_mute_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl); +int avs_control_mute_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo); #endif diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index 56a2916eec5e..403510494e77 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -359,6 +359,42 @@ int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod, return AVS_IPC_RET(ret); } +int avs_peakvol_set_mute(struct avs_dev *adev, struct avs_path_module *mod, + struct soc_mixer_control *mc, long *input) +{ + struct avs_mute_cfg mutes[SND_SOC_TPLG_MAX_CHAN] = {{0}}; + struct avs_control_data *ctl_data; + struct avs_tplg_module *t; + int ret, i; + + ctl_data = mc->dobj.private; + t = mod->template; + if (!input) + input = ctl_data->values; + + if (mc->num_channels) { + for (i = 0; i < mc->num_channels; i++) { + mutes[i].channel_id = i; + mutes[i].mute = !input[i]; + mutes[i].curve_type = t->cfg_ext->peakvol.curve_type; + mutes[i].curve_duration = t->cfg_ext->peakvol.curve_duration; + } + + ret = avs_ipc_peakvol_set_mutes(adev, mod->module_id, mod->instance_id, mutes, + mc->num_channels); + return AVS_IPC_RET(ret); + } + + /* Target all channels if no individual selected. */ + mutes[0].channel_id = AVS_ALL_CHANNELS_MASK; + mutes[0].mute = !input[0]; + mutes[0].curve_type = t->cfg_ext->peakvol.curve_type; + mutes[0].curve_duration = t->cfg_ext->peakvol.curve_duration; + + ret = avs_ipc_peakvol_set_mute(adev, mod->module_id, mod->instance_id, &mutes[0]); + return AVS_IPC_RET(ret); +} + static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) { struct avs_tplg_module *t = mod->template; diff --git a/sound/soc/intel/avs/path.h b/sound/soc/intel/avs/path.h index e9317b64de86..7ed7e94e0a56 100644 --- a/sound/soc/intel/avs/path.h +++ b/sound/soc/intel/avs/path.h @@ -71,5 +71,7 @@ int avs_path_run(struct avs_path *path, int trigger); int avs_peakvol_set_volume(struct avs_dev *adev, struct avs_path_module *mod, struct soc_mixer_control *mc, long *input); +int avs_peakvol_set_mute(struct avs_dev *adev, struct avs_path_module *mod, + struct soc_mixer_control *mc, long *input); #endif diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index ee70e3d0e889..9ef1adb077f4 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -1905,7 +1905,10 @@ static int avs_manifest(struct snd_soc_component *comp, int index, return 0; } -#define AVS_CONTROL_OPS_VOLUME 257 +enum { + AVS_CONTROL_OPS_VOLUME = 257, + AVS_CONTROL_OPS_MUTE, +}; static const struct snd_soc_tplg_kcontrol_ops avs_control_ops[] = { { @@ -1914,6 +1917,12 @@ static const struct snd_soc_tplg_kcontrol_ops avs_control_ops[] = { .put = avs_control_volume_put, .info = avs_control_volume_info, }, + { + .id = AVS_CONTROL_OPS_MUTE, + .get = avs_control_mute_get, + .put = avs_control_mute_put, + .info = avs_control_mute_info, + }, }; static const struct avs_tplg_token_parser control_parsers[] = { From 76e013152891a69dfe68a28706a51a7df9ed4c42 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:14 +0100 Subject: [PATCH 167/651] ASoC: Intel: avs: Honor the invert flag for mixer controls Values for the mute flag represented on the AudioDSP side are inverted. Check mixer control description and initialize default values accordingly. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/topology.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 9ef1adb077f4..3c222c352701 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -1943,18 +1943,20 @@ avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_ struct avs_control_data *ctl_data; struct soc_mixer_control *mc; size_t block_size; - int ret; + int ret, i; switch (le32_to_cpu(hdr->type)) { case SND_SOC_TPLG_TYPE_MIXER: - tmc = container_of(hdr, typeof(*tmc), hdr); - tuples = tmc->priv.array; - block_size = le32_to_cpu(tmc->priv.size); break; default: return -EINVAL; } + mc = (struct soc_mixer_control *)ctmpl->private_value; + tmc = container_of(hdr, typeof(*tmc), hdr); + tuples = tmc->priv.array; + block_size = le32_to_cpu(tmc->priv.size); + ctl_data = devm_kzalloc(comp->card->dev, sizeof(*ctl_data), GFP_KERNEL); if (!ctl_data) return -ENOMEM; @@ -1965,8 +1967,13 @@ avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_ if (ret) return ret; - mc = (struct soc_mixer_control *)ctmpl->private_value; mc->dobj.private = ctl_data; + if (tmc->invert) { + ctl_data->values[0] = mc->max; + for (i = 1; i < mc->num_channels; i++) + ctl_data->values[i] = mc->max; + } + return 0; } From a9409fcb979eaff401837b955b234ca1ee05fdbd Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 17 Feb 2025 11:21:15 +0100 Subject: [PATCH 168/651] ASoC: Intel: avs: Support multi-channel PEAKVOL instantiation The PEAKVOL module initialization procedure allows for specifying default configuration for all individual channels. To reflect that in the code, first update avs_get_module_control() to allow for selecting Volume or Mute control based on needs and then apply the settings with newly added avs_peakvol_set_volume() and avs_peakvol_set_mute(). Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250217102115.3539427-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/path.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index 403510494e77..ef0c1d125d66 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -300,7 +300,8 @@ static int avs_whm_create(struct avs_dev *adev, struct avs_path_module *mod) return ret; } -static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod) +static struct soc_mixer_control *avs_get_module_control(struct avs_path_module *mod, + const char *name) { struct avs_tplg_module *t = mod->template; struct avs_tplg_path_template *path_tmpl; @@ -316,8 +317,8 @@ static struct avs_control_data *avs_get_module_control(struct avs_path_module *m mc = (struct soc_mixer_control *)w->kcontrols[i]->private_value; ctl_data = (struct avs_control_data *)mc->dobj.private; - if (ctl_data->id == t->ctl_id) - return ctl_data; + if (ctl_data->id == t->ctl_id && strstr(w->kcontrols[i]->id.name, name)) + return mc; } return NULL; @@ -398,17 +399,11 @@ int avs_peakvol_set_mute(struct avs_dev *adev, struct avs_path_module *mod, static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) { struct avs_tplg_module *t = mod->template; - struct avs_control_data *ctl_data; + struct soc_mixer_control *mc; struct avs_peakvol_cfg *cfg; - int volume = S32_MAX; size_t cfg_size; int ret; - ctl_data = avs_get_module_control(mod); - if (ctl_data) - volume = ctl_data->values[0]; - - /* As 2+ channels controls are unsupported, have a single block for all channels. */ cfg_size = struct_size(cfg, vols, 1); if (cfg_size > AVS_MAILBOX_SIZE) return -EINVAL; @@ -420,15 +415,28 @@ static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) cfg->base.obs = t->cfg_base->obs; cfg->base.is_pages = t->cfg_base->is_pages; cfg->base.audio_fmt = *t->in_fmt; - cfg->vols[0].target_volume = volume; cfg->vols[0].channel_id = AVS_ALL_CHANNELS_MASK; + cfg->vols[0].target_volume = S32_MAX; cfg->vols[0].curve_type = t->cfg_ext->peakvol.curve_type; cfg->vols[0].curve_duration = t->cfg_ext->peakvol.curve_duration; ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id, t->domain, cfg, cfg_size, &mod->instance_id); + if (ret) + return ret; - return ret; + /* Now configure both VOLUME and MUTE parameters. */ + mc = avs_get_module_control(mod, "Volume"); + if (mc) { + ret = avs_peakvol_set_volume(adev, mod, mc, NULL); + if (ret) + return ret; + } + + mc = avs_get_module_control(mod, "Switch"); + if (mc) + return avs_peakvol_set_mute(adev, mod, mc, NULL); + return 0; } static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod) From 5a09e179024e76afdf9ad3a6ae767b4e06884ea8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 19 Feb 2025 01:19:10 +0000 Subject: [PATCH 169/651] ASoC: Documentation: DPCM: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikp6vii9.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- Documentation/sound/soc/dpcm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/sound/soc/dpcm.rst b/Documentation/sound/soc/dpcm.rst index 02419a6f8213..a12636552f50 100644 --- a/Documentation/sound/soc/dpcm.rst +++ b/Documentation/sound/soc/dpcm.rst @@ -362,7 +362,7 @@ The machine driver sets some additional parameters to the DAI link i.e. .codec_dai_name = "modem-aif1", .codec_name = "modem", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .c2c_params = &dai_params, .num_c2c_params = 1, } From 1c4749873bd0f769a47372636a428484e7035f59 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 19 Feb 2025 01:19:48 +0000 Subject: [PATCH 170/651] ASoC: kirkwood: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczuvih7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/kirkwood/armada-370-db.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/kirkwood/armada-370-db.c b/sound/soc/kirkwood/armada-370-db.c index 79ee7599f06a..77a5f440364e 100644 --- a/sound/soc/kirkwood/armada-370-db.c +++ b/sound/soc/kirkwood/armada-370-db.c @@ -73,20 +73,20 @@ static struct snd_soc_dai_link a370db_dai[] = { { .name = "CS42L51", .stream_name = "analog", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC, .ops = &a370db_ops, SND_SOC_DAILINK_REG(analog), }, { .name = "S/PDIF out", .stream_name = "spdif-out", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(spdif_out), }, { .name = "S/PDIF in", .stream_name = "spdif-in", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(spdif_in), }, }; From 38399716e353776dca7f04dbae98a07af68f2880 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 19 Feb 2025 01:19:31 +0000 Subject: [PATCH 171/651] ASoC: ti: rx51: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frkaviho.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/rx51.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/rx51.c b/sound/soc/ti/rx51.c index d9900c69e536..e969031657e9 100644 --- a/sound/soc/ti/rx51.c +++ b/sound/soc/ti/rx51.c @@ -307,7 +307,7 @@ static struct snd_soc_dai_link rx51_dai[] = { .name = "TLV320AIC34", .stream_name = "AIC34", .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .init = rx51_aic34_init, .ops = &rx51_ops, SND_SOC_DAILINK_REG(aic34), From a5a3de8990f47f4c54ca5daeeea8ff7daa42f9de Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 19 Feb 2025 01:19:21 +0000 Subject: [PATCH 172/651] ASoC: sh: migor: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64qvihz.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/renesas/migor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/renesas/migor.c b/sound/soc/renesas/migor.c index 5a0bc6edac0a..45fc594d331b 100644 --- a/sound/soc/renesas/migor.c +++ b/sound/soc/renesas/migor.c @@ -132,7 +132,7 @@ static struct snd_soc_dai_link migor_dai = { .name = "wm8978", .stream_name = "WM8978", .dai_fmt = SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &migor_dai_ops, SND_SOC_DAILINK_REG(wm8978), }; From 63d93f4d0f38fbb95a55729fbd2cc4920743931c Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Sat, 22 Feb 2025 14:55:20 -0500 Subject: [PATCH 173/651] ASoC: q6dsp: q6apm: replace kzalloc() with kcalloc() in q6apm_map_memory_regions() We are trying to get rid of all multiplications from allocation functions to prevent integer overflows[1]. Here the multiplication is obviously safe, but using kcalloc() is more appropriate and improves readability. This patch has no effect on runtime behavior. Link: https://github.com/KSPP/linux/issues/162 [1] Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Signed-off-by: Ethan Carter Edwards Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20250222-q6apm-kcalloc-v1-1-6f09dae6c31c@ethancedwards.com Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6apm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c index 2a2a5bd98110..11e252a70f69 100644 --- a/sound/soc/qcom/qdsp6/q6apm.c +++ b/sound/soc/qcom/qdsp6/q6apm.c @@ -230,7 +230,7 @@ int q6apm_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, phys_a return 0; } - buf = kzalloc(((sizeof(struct audio_buffer)) * periods), GFP_KERNEL); + buf = kcalloc(periods, sizeof(struct audio_buffer), GFP_KERNEL); if (!buf) { mutex_unlock(&graph->lock); return -ENOMEM; From 8fd0e127d8da856e34391399df40b33af2b307e0 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 24 Feb 2025 23:12:12 +0100 Subject: [PATCH 174/651] ASoC: amd: acp: acp70: Remove unnecessary if-check Since list_for_each_entry() expects the list to not be empty, the iterator variable cannot be NULL and the unnecessary if-check can be removed. Remove it and indent the code accordingly. Compile-tested only. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250224221214.199849-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp70.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index ef3f6504bc7f..7f4ec3bfaeab 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -230,18 +230,16 @@ static int __maybe_unused acp70_pcm_resume(struct device *dev) spin_lock(&adata->acp_lock); list_for_each_entry(stream, &adata->stream_list, list) { - if (stream) { - substream = stream->substream; - if (substream && substream->runtime) { - buf_in_frames = (substream->runtime->buffer_size); - buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); - if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); - else - restore_acp_pdm_params(substream, adata); - } + substream = stream->substream; + if (substream && substream->runtime) { + buf_in_frames = (substream->runtime->buffer_size); + buf_size = frames_to_bytes(substream->runtime, buf_in_frames); + config_pte_for_stream(adata, stream); + config_acp_dma(adata, stream, buf_size); + if (stream->dai_id) + restore_acp_i2s_params(substream, adata, stream); + else + restore_acp_pdm_params(substream, adata); } } spin_unlock(&adata->acp_lock); From 6542db20caf4987b938ed8feec07d199779823f2 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 24 Feb 2025 17:04:12 +0800 Subject: [PATCH 175/651] ASoC: dt-bindings: fsl,easrc: Reference common DAI properties Reference the dai-common.yaml schema to allow '#sound-dai-cells' and "sound-name-prefix' to be used. Signed-off-by: Shengjiu Wang Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250224090413.727911-2-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl,easrc.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,easrc.yaml b/Documentation/devicetree/bindings/sound/fsl,easrc.yaml index c454110f4281..8f1108e7e14e 100644 --- a/Documentation/devicetree/bindings/sound/fsl,easrc.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,easrc.yaml @@ -80,7 +80,10 @@ required: - fsl,asrc-rate - fsl,asrc-format -additionalProperties: false +allOf: + - $ref: dai-common.yaml# + +unevaluatedProperties: false examples: - | From 3e7b375752b5e4de56e92dfb9c43309cd985b869 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 24 Feb 2025 17:04:13 +0800 Subject: [PATCH 176/651] ASoC: dt-bindings: fsl,imx-asrc: Reference common DAI properties Reference the dai-common.yaml schema to allow '#sound-dai-cells' and "sound-name-prefix' to be used. Signed-off-by: Shengjiu Wang Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250224090413.727911-3-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml index 76aa1f248488..abac5084d63b 100644 --- a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml @@ -120,6 +120,7 @@ required: - fsl,asrc-width allOf: + - $ref: dai-common.yaml# - if: properties: compatible: @@ -145,7 +146,7 @@ allOf: required: - power-domains -additionalProperties: false +unevaluatedProperties: false examples: - | From ef6a24c79d5047c029577113af43eddd1d0f1bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 25 Feb 2025 11:33:47 -0300 Subject: [PATCH 177/651] ASoC: mediatek: mt8188: Add audsys hires clocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe and register the aud_dmic_hires audsys clocks, which are needed when recording the DMIC at a sample rate of 96k. Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20250225-genio700-dmic-v2-1-3076f5b50ef7@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-audsys-clk.c | 4 ++++ sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c index c796ad8b62ee..40d2ab0a7677 100644 --- a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c +++ b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c @@ -84,6 +84,10 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = { GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "top_a1sys_hp", 14), GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "top_audio_h", 16), GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "top_audio_h", 17), + GATE_AUD1(CLK_AUD_DMIC_HIRES1, "aud_dmic_hires1", "top_audio_h", 20), + GATE_AUD1(CLK_AUD_DMIC_HIRES2, "aud_dmic_hires2", "top_audio_h", 21), + GATE_AUD1(CLK_AUD_DMIC_HIRES3, "aud_dmic_hires3", "top_audio_h", 22), + GATE_AUD1(CLK_AUD_DMIC_HIRES4, "aud_dmic_hires4", "top_audio_h", 23), /* AUD3 */ GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "top_apll5", 5), diff --git a/sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h b/sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h index 6f34ffc760e0..9cb732863c10 100644 --- a/sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h +++ b/sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h @@ -33,6 +33,10 @@ enum{ CLK_AUD_AFE_26M_DMIC_TM, CLK_AUD_UL_TML_HIRES, CLK_AUD_ADC_HIRES, + CLK_AUD_DMIC_HIRES1, + CLK_AUD_DMIC_HIRES2, + CLK_AUD_DMIC_HIRES3, + CLK_AUD_DMIC_HIRES4, CLK_AUD_LINEIN_TUNER, CLK_AUD_EARC_TUNER, CLK_AUD_I2SIN, From bf1800073f4d55f08191b034c86b95881e99b6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 25 Feb 2025 11:33:48 -0300 Subject: [PATCH 178/651] ASoC: mediatek: mt8188: Add reference for dmic clocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the names for the dmic clocks, aud_afe_dmic* and aud_dmic_hires*, so they can be acquired and enabled by the platform driver. Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20250225-genio700-dmic-v2-2-3076f5b50ef7@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 8 ++++++++ sound/soc/mediatek/mt8188/mt8188-afe-clk.h | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c index e69c1bb2cb23..7f411b857782 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c @@ -58,7 +58,15 @@ static const char *aud_clks[MT8188_CLK_NUM] = { [MT8188_CLK_AUD_ADC] = "aud_adc", [MT8188_CLK_AUD_DAC_HIRES] = "aud_dac_hires", [MT8188_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp", + [MT8188_CLK_AUD_AFE_DMIC1] = "aud_afe_dmic1", + [MT8188_CLK_AUD_AFE_DMIC2] = "aud_afe_dmic2", + [MT8188_CLK_AUD_AFE_DMIC3] = "aud_afe_dmic3", + [MT8188_CLK_AUD_AFE_DMIC4] = "aud_afe_dmic4", [MT8188_CLK_AUD_ADC_HIRES] = "aud_adc_hires", + [MT8188_CLK_AUD_DMIC_HIRES1] = "aud_dmic_hires1", + [MT8188_CLK_AUD_DMIC_HIRES2] = "aud_dmic_hires2", + [MT8188_CLK_AUD_DMIC_HIRES3] = "aud_dmic_hires3", + [MT8188_CLK_AUD_DMIC_HIRES4] = "aud_dmic_hires4", [MT8188_CLK_AUD_I2SIN] = "aud_i2sin", [MT8188_CLK_AUD_TDM_IN] = "aud_tdm_in", [MT8188_CLK_AUD_I2S_OUT] = "aud_i2s_out", diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h index ec53c171c170..c6c78d684f3e 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h @@ -54,7 +54,15 @@ enum { MT8188_CLK_AUD_ADC, MT8188_CLK_AUD_DAC_HIRES, MT8188_CLK_AUD_A1SYS_HP, + MT8188_CLK_AUD_AFE_DMIC1, + MT8188_CLK_AUD_AFE_DMIC2, + MT8188_CLK_AUD_AFE_DMIC3, + MT8188_CLK_AUD_AFE_DMIC4, MT8188_CLK_AUD_ADC_HIRES, + MT8188_CLK_AUD_DMIC_HIRES1, + MT8188_CLK_AUD_DMIC_HIRES2, + MT8188_CLK_AUD_DMIC_HIRES3, + MT8188_CLK_AUD_DMIC_HIRES4, MT8188_CLK_AUD_I2SIN, MT8188_CLK_AUD_TDM_IN, MT8188_CLK_AUD_I2S_OUT, From 7d87bde21c73731ddaf15e572020f80999c38ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 25 Feb 2025 11:33:49 -0300 Subject: [PATCH 179/651] ASoC: mediatek: mt8188: Treat DMIC_GAINx_CUR as non-volatile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DMIC_GAINx_CUR registers contain the current (as in present) gain of each DMIC. During capture, this gain will ramp up until a target value is reached, and therefore the register is volatile since it is updated automatically by hardware. However, after capture the register's value returns to the value that was written to it. So reading these registers returns the current gain, and writing configures the initial gain for every capture. >From an audio configuration perspective, reading the instantaneous gain is not really useful. Instead, reading back the initial gain that was configured is the desired behavior. For that reason, consider the DMIC_GAINx_CUR registers as non-volatile, so the regmap's cache can be used to retrieve the values, rather than requiring pm runtime resuming the device. Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20250225-genio700-dmic-v2-3-3076f5b50ef7@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c index 73e5c63aeec8..d36520c6272d 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c @@ -2855,10 +2855,6 @@ static bool mt8188_is_volatile_reg(struct device *dev, unsigned int reg) case AFE_DMIC3_SRC_DEBUG_MON0: case AFE_DMIC3_UL_SRC_MON0: case AFE_DMIC3_UL_SRC_MON1: - case DMIC_GAIN1_CUR: - case DMIC_GAIN2_CUR: - case DMIC_GAIN3_CUR: - case DMIC_GAIN4_CUR: case ETDM_IN1_MONITOR: case ETDM_IN2_MONITOR: case ETDM_OUT1_MONITOR: From c1e42ec04197ac013d049dde40d9c72cf543b5f6 Mon Sep 17 00:00:00 2001 From: parkeryang Date: Tue, 25 Feb 2025 11:33:50 -0300 Subject: [PATCH 180/651] ASoC: mediatek: mt8188: Add support for DMIC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the DMIC DAIs present on the MT8188 SoC. To achieve that, add a DAI driver for DMIC and register it during probe, and describe the AFE routes that connect the DMIC (I004-I011) to the UL9 frontend (O002-O009). Signed-off-by: parkeryang Co-developed-by: Nícolas F. R. A. Prado Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20250225-genio700-dmic-v2-4-3076f5b50ef7@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/Makefile | 1 + sound/soc/mediatek/mt8188/mt8188-afe-common.h | 1 + sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 24 + sound/soc/mediatek/mt8188/mt8188-dai-dmic.c | 682 ++++++++++++++++++ sound/soc/mediatek/mt8188/mt8188-reg.h | 17 +- 5 files changed, 723 insertions(+), 2 deletions(-) create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-dmic.c diff --git a/sound/soc/mediatek/mt8188/Makefile b/sound/soc/mediatek/mt8188/Makefile index 1178bce45c50..b9f3e4ad7b07 100644 --- a/sound/soc/mediatek/mt8188/Makefile +++ b/sound/soc/mediatek/mt8188/Makefile @@ -6,6 +6,7 @@ snd-soc-mt8188-afe-y := \ mt8188-afe-pcm.o \ mt8188-audsys-clk.o \ mt8188-dai-adda.o \ + mt8188-dai-dmic.o \ mt8188-dai-etdm.o \ mt8188-dai-pcm.o diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-common.h b/sound/soc/mediatek/mt8188/mt8188-afe-common.h index 1304d685a306..01aa11242e29 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-common.h +++ b/sound/soc/mediatek/mt8188/mt8188-afe-common.h @@ -137,6 +137,7 @@ struct mt8188_afe_private { int mt8188_afe_fs_timing(unsigned int rate); /* dai register */ int mt8188_dai_adda_register(struct mtk_base_afe *afe); +int mt8188_dai_dmic_register(struct mtk_base_afe *afe); int mt8188_dai_etdm_register(struct mtk_base_afe *afe); int mt8188_dai_pcm_register(struct mtk_base_afe *afe); diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c index d36520c6272d..a2b57e00ff4e 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c @@ -652,6 +652,7 @@ static struct snd_soc_dai_driver mt8188_memif_dai_driver[] = { static const struct snd_kcontrol_new o002_mix[] = { SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN2, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I004 Switch", AFE_CONN2, 4, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN2, 12, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN2, 20, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN2, 22, 1, 0), @@ -662,6 +663,8 @@ static const struct snd_kcontrol_new o002_mix[] = { static const struct snd_kcontrol_new o003_mix[] = { SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN3, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I005 Switch", AFE_CONN3, 5, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I006 Switch", AFE_CONN3, 6, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN3, 13, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN3, 21, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN3, 23, 1, 0), @@ -672,6 +675,8 @@ static const struct snd_kcontrol_new o003_mix[] = { static const struct snd_kcontrol_new o004_mix[] = { SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN4, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I006 Switch", AFE_CONN4, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I008 Switch", AFE_CONN4, 8, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I014 Switch", AFE_CONN4, 14, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN4, 24, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I074 Switch", AFE_CONN4_2, 10, 1, 0), @@ -679,6 +684,8 @@ static const struct snd_kcontrol_new o004_mix[] = { static const struct snd_kcontrol_new o005_mix[] = { SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN5, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I007 Switch", AFE_CONN5, 7, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I010 Switch", AFE_CONN5, 10, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I015 Switch", AFE_CONN5, 15, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN5, 25, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I075 Switch", AFE_CONN5_2, 11, 1, 0), @@ -686,6 +693,7 @@ static const struct snd_kcontrol_new o005_mix[] = { static const struct snd_kcontrol_new o006_mix[] = { SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN6, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I008 Switch", AFE_CONN6, 8, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I016 Switch", AFE_CONN6, 16, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN6, 26, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I076 Switch", AFE_CONN6_2, 12, 1, 0), @@ -693,18 +701,21 @@ static const struct snd_kcontrol_new o006_mix[] = { static const struct snd_kcontrol_new o007_mix[] = { SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN7, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I009 Switch", AFE_CONN7, 9, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I017 Switch", AFE_CONN7, 17, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN7, 27, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I077 Switch", AFE_CONN7_2, 13, 1, 0), }; static const struct snd_kcontrol_new o008_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I010 Switch", AFE_CONN8, 10, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I018 Switch", AFE_CONN8, 18, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN8, 28, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I078 Switch", AFE_CONN8_2, 14, 1, 0), }; static const struct snd_kcontrol_new o009_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I011 Switch", AFE_CONN9, 11, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I019 Switch", AFE_CONN9, 19, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN9, 29, 1, 0), SOC_DAPM_SINGLE_AUTODISABLE("I079 Switch", AFE_CONN9_2, 15, 1, 0), @@ -1275,6 +1286,18 @@ static const struct snd_soc_dapm_route mt8188_memif_routes[] = { {"O002", "I070 Switch", "I070"}, {"O003", "I071 Switch", "I071"}, + {"O002", "I004 Switch", "I004"}, + {"O003", "I005 Switch", "I005"}, + {"O003", "I006 Switch", "I006"}, + {"O004", "I006 Switch", "I006"}, + {"O004", "I008 Switch", "I008"}, + {"O005", "I007 Switch", "I007"}, + {"O005", "I010 Switch", "I010"}, + {"O006", "I008 Switch", "I008"}, + {"O007", "I009 Switch", "I009"}, + {"O008", "I010 Switch", "I010"}, + {"O009", "I011 Switch", "I011"}, + {"O034", "I000 Switch", "I000"}, {"O035", "I001 Switch", "I001"}, {"O034", "I002 Switch", "I002"}, @@ -3072,6 +3095,7 @@ static int mt8188_dai_memif_register(struct mtk_base_afe *afe) typedef int (*dai_register_cb)(struct mtk_base_afe *); static const dai_register_cb dai_register_cbs[] = { mt8188_dai_adda_register, + mt8188_dai_dmic_register, mt8188_dai_etdm_register, mt8188_dai_pcm_register, mt8188_dai_memif_register, diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c b/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c new file mode 100644 index 000000000000..4cfbcb71d2d9 --- /dev/null +++ b/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c @@ -0,0 +1,682 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI DMIC I/F Control + * + * Copyright (c) 2020 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + * Parker Yang + */ + +#include +#include +#include +#include +#include "mt8188-afe-clk.h" +#include "mt8188-afe-common.h" +#include "mt8188-reg.h" + +/* DMIC HW Gain configuration maximum value. */ +#define DMIC_GAIN_MAX_STEP GENMASK(19, 0) +#define DMIC_GAIN_MAX_PER_STEP GENMASK(7, 0) +#define DMIC_GAIN_MAX_TARGET GENMASK(27, 0) +#define DMIC_GAIN_MAX_CURRENT GENMASK(27, 0) + +#define CLK_PHASE_SEL_CH1 0 +#define CLK_PHASE_SEL_CH2 ((CLK_PHASE_SEL_CH1) + 4) + +#define DMIC1_SRC_SEL 0 +#define DMIC2_SRC_SEL 0 +#define DMIC3_SRC_SEL 2 +#define DMIC4_SRC_SEL 0 +#define DMIC5_SRC_SEL 4 +#define DMIC6_SRC_SEL 0 +#define DMIC7_SRC_SEL 6 +#define DMIC8_SRC_SEL 0 + +enum { + SUPPLY_SEQ_DMIC_GAIN, + SUPPLY_SEQ_DMIC_CK, +}; + +enum { + DMIC0, + DMIC1, + DMIC2, + DMIC3, + DMIC_NUM, +}; + +struct mtk_dai_dmic_ctrl_reg { + unsigned int con0; +}; + +struct mtk_dai_dmic_hw_gain_ctrl_reg { + unsigned int bypass; + unsigned int con0; +}; + +struct mtk_dai_dmic_priv { + unsigned int gain_on[DMIC_NUM]; + unsigned int channels; + bool hires_required; +}; + +static const struct mtk_dai_dmic_ctrl_reg dmic_ctrl_regs[DMIC_NUM] = { + [DMIC0] = { + .con0 = AFE_DMIC0_UL_SRC_CON0, + }, + [DMIC1] = { + .con0 = AFE_DMIC1_UL_SRC_CON0, + }, + [DMIC2] = { + .con0 = AFE_DMIC2_UL_SRC_CON0, + }, + [DMIC3] = { + .con0 = AFE_DMIC3_UL_SRC_CON0, + }, +}; + +static const struct mtk_dai_dmic_ctrl_reg *get_dmic_ctrl_reg(int id) +{ + if (id < 0 || id >= DMIC_NUM) + return NULL; + + return &dmic_ctrl_regs[id]; +} + +static const struct mtk_dai_dmic_hw_gain_ctrl_reg + dmic_hw_gain_ctrl_regs[DMIC_NUM] = { + [DMIC0] = { + .bypass = DMIC_BYPASS_HW_GAIN, + .con0 = DMIC_GAIN1_CON0, + }, + [DMIC1] = { + .bypass = DMIC_BYPASS_HW_GAIN, + .con0 = DMIC_GAIN2_CON0, + }, + [DMIC2] = { + .bypass = DMIC_BYPASS_HW_GAIN, + .con0 = DMIC_GAIN3_CON0, + }, + [DMIC3] = { + .bypass = DMIC_BYPASS_HW_GAIN, + .con0 = DMIC_GAIN4_CON0, + }, +}; + +static const struct mtk_dai_dmic_hw_gain_ctrl_reg + *get_dmic_hw_gain_ctrl_reg(struct mtk_base_afe *afe, int id) +{ + if ((id < 0) || (id >= DMIC_NUM)) { + dev_dbg(afe->dev, "%s invalid id\n", __func__); + return NULL; + } + + return &dmic_hw_gain_ctrl_regs[id]; +} + +static void mtk_dai_dmic_hw_gain_bypass(struct mtk_base_afe *afe, + unsigned int id, bool bypass) +{ + const struct mtk_dai_dmic_hw_gain_ctrl_reg *reg; + unsigned int msk; + + reg = get_dmic_hw_gain_ctrl_reg(afe, id); + if (!reg) + return; + + switch (id) { + case DMIC0: + msk = DMIC_BYPASS_HW_GAIN_DMIC1_BYPASS; + break; + case DMIC1: + msk = DMIC_BYPASS_HW_GAIN_DMIC2_BYPASS; + break; + case DMIC2: + msk = DMIC_BYPASS_HW_GAIN_DMIC3_BYPASS; + break; + case DMIC3: + msk = DMIC_BYPASS_HW_GAIN_DMIC4_BYPASS; + break; + default: + return; + } + + if (bypass) + regmap_set_bits(afe->regmap, reg->bypass, msk); + else + regmap_clear_bits(afe->regmap, reg->bypass, msk); +} + +static void mtk_dai_dmic_hw_gain_on(struct mtk_base_afe *afe, unsigned int id, + bool on) +{ + const struct mtk_dai_dmic_hw_gain_ctrl_reg *reg = get_dmic_hw_gain_ctrl_reg(afe, id); + + if (!reg) + return; + + if (on) + regmap_set_bits(afe->regmap, reg->con0, DMIC_GAIN_CON0_GAIN_ON); + else + regmap_clear_bits(afe->regmap, reg->con0, DMIC_GAIN_CON0_GAIN_ON); +} + +static const struct reg_sequence mtk_dai_dmic_iir_coeff_reg_defaults[] = { + { AFE_DMIC0_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC0_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC0_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC0_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC0_IIR_COEF_10_09, 0x0000C048 }, + { AFE_DMIC1_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC1_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC1_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC1_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC1_IIR_COEF_10_09, 0x0000C048 }, + { AFE_DMIC2_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC2_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC2_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC2_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC2_IIR_COEF_10_09, 0x0000C048 }, + { AFE_DMIC3_IIR_COEF_02_01, 0x00000000 }, + { AFE_DMIC3_IIR_COEF_04_03, 0x00003FB8 }, + { AFE_DMIC3_IIR_COEF_06_05, 0x3FB80000 }, + { AFE_DMIC3_IIR_COEF_08_07, 0x3FB80000 }, + { AFE_DMIC3_IIR_COEF_10_09, 0x0000C048 }, +}; + +static int mtk_dai_dmic_load_iir_coeff_table(struct mtk_base_afe *afe) +{ + return regmap_multi_reg_write(afe->regmap, + mtk_dai_dmic_iir_coeff_reg_defaults, + ARRAY_SIZE(mtk_dai_dmic_iir_coeff_reg_defaults)); +} + +static int mtk_dai_dmic_configure_array(struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + const u32 mask = PWR2_TOP_CON_DMIC8_SRC_SEL_MASK | + PWR2_TOP_CON_DMIC7_SRC_SEL_MASK | + PWR2_TOP_CON_DMIC6_SRC_SEL_MASK | + PWR2_TOP_CON_DMIC5_SRC_SEL_MASK | + PWR2_TOP_CON_DMIC4_SRC_SEL_MASK | + PWR2_TOP_CON_DMIC3_SRC_SEL_MASK | + PWR2_TOP_CON_DMIC2_SRC_SEL_MASK | + PWR2_TOP_CON_DMIC1_SRC_SEL_MASK; + const u32 val = PWR2_TOP_CON_DMIC8_SRC_SEL_VAL(DMIC8_SRC_SEL) | + PWR2_TOP_CON_DMIC7_SRC_SEL_VAL(DMIC7_SRC_SEL) | + PWR2_TOP_CON_DMIC6_SRC_SEL_VAL(DMIC6_SRC_SEL) | + PWR2_TOP_CON_DMIC5_SRC_SEL_VAL(DMIC5_SRC_SEL) | + PWR2_TOP_CON_DMIC4_SRC_SEL_VAL(DMIC4_SRC_SEL) | + PWR2_TOP_CON_DMIC3_SRC_SEL_VAL(DMIC3_SRC_SEL) | + PWR2_TOP_CON_DMIC2_SRC_SEL_VAL(DMIC2_SRC_SEL) | + PWR2_TOP_CON_DMIC1_SRC_SEL_VAL(DMIC1_SRC_SEL); + + return regmap_update_bits(afe->regmap, PWR2_TOP_CON0, mask, val); +} + +/* This function assumes that the caller checked that channels is valid */ +static u8 mtk_dmic_channels_to_dmic_number(unsigned int channels) +{ + switch (channels) { + case 1: + return DMIC0; + case 2: + return DMIC1; + case 3: + return DMIC2; + case 4: + default: + return DMIC3; + } +} + +static void mtk_dai_dmic_hw_gain_enable(struct mtk_base_afe *afe, + unsigned int channels, bool enable) +{ + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; + u8 dmic_num; + int i; + + dmic_num = mtk_dmic_channels_to_dmic_number(channels); + for (i = dmic_num; i >= DMIC0; i--) { + if (enable && dmic_priv->gain_on[i]) { + mtk_dai_dmic_hw_gain_bypass(afe, i, false); + mtk_dai_dmic_hw_gain_on(afe, i, true); + } else { + mtk_dai_dmic_hw_gain_on(afe, i, false); + mtk_dai_dmic_hw_gain_bypass(afe, i, true); + } + } +} + +static int mtk_dmic_gain_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; + unsigned int channels = dmic_priv->channels; + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + if (!channels) + return -EINVAL; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mtk_dai_dmic_hw_gain_enable(afe, channels, true); + break; + case SND_SOC_DAPM_POST_PMD: + mtk_dai_dmic_hw_gain_enable(afe, channels, false); + break; + default: + break; + } + + return 0; +} + +static int mtk_dmic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; + const struct mtk_dai_dmic_ctrl_reg *reg = NULL; + unsigned int channels = dmic_priv->channels; + unsigned int msk; + u8 dmic_num; + int i; + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + if (!channels) + return -EINVAL; + + dmic_num = mtk_dmic_channels_to_dmic_number(channels); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* request fifo soft rst */ + for (i = dmic_num; i >= DMIC0; i--) + msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i); + + regmap_set_bits(afe->regmap, PWR2_TOP_CON1, msk); + + msk = AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL | + AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL | + AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL | + AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL; + + for (i = dmic_num; i >= DMIC0; i--) { + reg = get_dmic_ctrl_reg(i); + if (reg) + regmap_set_bits(afe->regmap, reg->con0, msk); + } + break; + case SND_SOC_DAPM_POST_PMU: + msk = AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL; + + for (i = dmic_num; i >= DMIC0; i--) { + reg = get_dmic_ctrl_reg(i); + if (reg) + regmap_set_bits(afe->regmap, reg->con0, msk); + } + + if (dmic_priv->hires_required) { + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]); + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]); + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]); + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]); + } + + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]); + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]); + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]); + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC4]); + + /* release fifo soft rst */ + msk = 0; + for (i = dmic_num; i >= DMIC0; i--) + msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i); + + regmap_clear_bits(afe->regmap, PWR2_TOP_CON1, msk); + break; + case SND_SOC_DAPM_PRE_PMD: + msk = AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL | + AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL | + AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL | + AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL | + AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL; + + for (i = dmic_num; i >= DMIC0; i--) { + reg = get_dmic_ctrl_reg(i); + if (reg) + regmap_set_bits(afe->regmap, reg->con0, msk); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 126); + + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC4]); + + if (dmic_priv->hires_required) { + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]); + } + break; + default: + break; + } + + return 0; +} + +static int mtk_dai_dmic_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; + unsigned int rate = params_rate(params); + unsigned int channels = params_channels(params); + const struct mtk_dai_dmic_ctrl_reg *reg = NULL; + u32 val = AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH1(CLK_PHASE_SEL_CH1) | + AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH2(CLK_PHASE_SEL_CH2) | + AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL(0); + const u32 msk = AFE_DMIC_UL_SRC_CON0_UL_TWO_WIRE_MODE_CTL | + AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_MASK | + AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL_MASK | + AFE_DMIC_UL_VOICE_MODE_MASK; + u8 dmic_num; + int ret; + int i; + + if (!channels || channels > 8) + return -EINVAL; + + ret = mtk_dai_dmic_configure_array(dai); + if (ret < 0) + return ret; + + ret = mtk_dai_dmic_load_iir_coeff_table(afe); + if (ret < 0) + return ret; + + switch (rate) { + case 96000: + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_96K; + dmic_priv->hires_required = 1; + break; + case 48000: + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_48K; + dmic_priv->hires_required = 0; + break; + case 32000: + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_32K; + dmic_priv->hires_required = 0; + break; + case 16000: + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_16K; + dmic_priv->hires_required = 0; + break; + case 8000: + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_8K; + dmic_priv->hires_required = 0; + break; + default: + dev_dbg(afe->dev, "%s invalid rate %u, use 48000Hz\n", __func__, rate); + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_48K; + dmic_priv->hires_required = 0; + break; + } + + dmic_num = mtk_dmic_channels_to_dmic_number(channels); + for (i = dmic_num; i >= DMIC0; i--) { + reg = get_dmic_ctrl_reg(i); + if (reg) { + ret = regmap_update_bits(afe->regmap, reg->con0, msk, val); + if (ret < 0) + return ret; + } + } + + dmic_priv->channels = channels; + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_dmic_ops = { + .hw_params = mtk_dai_dmic_hw_params, +}; + +#define MTK_DMIC_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000) + +#define MTK_DMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_dmic_driver[] = { + { + .name = "DMIC", + .id = MT8188_AFE_IO_DMIC_IN, + .capture = { + .stream_name = "DMIC Capture", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_DMIC_RATES, + .formats = MTK_DMIC_FORMATS, + }, + .ops = &mtk_dai_dmic_ops, + }, +}; + +static const struct snd_soc_dapm_widget mtk_dai_dmic_widgets[] = { + SND_SOC_DAPM_MIXER("I004", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I005", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I006", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I007", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I008", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I009", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I010", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I011", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("DMIC_GAIN_ON", SUPPLY_SEQ_DMIC_GAIN, + SND_SOC_NOPM, 0, 0, + mtk_dmic_gain_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("DMIC_CK_ON", SUPPLY_SEQ_DMIC_CK, + PWR2_TOP_CON1, + PWR2_TOP_CON1_DMIC_CKDIV_ON_SHIFT, 0, + mtk_dmic_event, + SND_SOC_DAPM_PRE_POST_PMU | + SND_SOC_DAPM_PRE_POST_PMD), + SND_SOC_DAPM_INPUT("DMIC_INPUT"), +}; + +static const struct snd_soc_dapm_route mtk_dai_dmic_routes[] = { + {"I004", NULL, "DMIC Capture"}, + {"I005", NULL, "DMIC Capture"}, + {"I006", NULL, "DMIC Capture"}, + {"I007", NULL, "DMIC Capture"}, + {"I008", NULL, "DMIC Capture"}, + {"I009", NULL, "DMIC Capture"}, + {"I010", NULL, "DMIC Capture"}, + {"I011", NULL, "DMIC Capture"}, + {"DMIC Capture", NULL, "DMIC_CK_ON"}, + {"DMIC Capture", NULL, "DMIC_GAIN_ON"}, + {"DMIC Capture", NULL, "DMIC_INPUT"}, +}; + +static const char * const mt8188_dmic_gain_enable_text[] = { + "Bypass", "Connect", +}; + +static SOC_ENUM_SINGLE_EXT_DECL(dmic_gain_on_enum, + mt8188_dmic_gain_enable_text); + +static int mtk_dai_dmic_hw_gain_ctrl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; + unsigned int source = ucontrol->value.enumerated.item[0]; + unsigned int *cached; + + if (source >= e->items) + return -EINVAL; + + if (!strcmp(kcontrol->id.name, "DMIC1_HW_GAIN_EN")) + cached = &dmic_priv->gain_on[0]; + else if (!strcmp(kcontrol->id.name, "DMIC2_HW_GAIN_EN")) + cached = &dmic_priv->gain_on[1]; + else if (!strcmp(kcontrol->id.name, "DMIC3_HW_GAIN_EN")) + cached = &dmic_priv->gain_on[2]; + else if (!strcmp(kcontrol->id.name, "DMIC4_HW_GAIN_EN")) + cached = &dmic_priv->gain_on[3]; + else + return -EINVAL; + + if (source == *cached) + return 0; + + *cached = source; + return 1; +} + +static int mtk_dai_dmic_hw_gain_ctrl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; + unsigned int val; + + if (!strcmp(kcontrol->id.name, "DMIC1_HW_GAIN_EN")) + val = dmic_priv->gain_on[0]; + else if (!strcmp(kcontrol->id.name, "DMIC2_HW_GAIN_EN")) + val = dmic_priv->gain_on[1]; + else if (!strcmp(kcontrol->id.name, "DMIC3_HW_GAIN_EN")) + val = dmic_priv->gain_on[2]; + else if (!strcmp(kcontrol->id.name, "DMIC4_HW_GAIN_EN")) + val = dmic_priv->gain_on[3]; + else + return -EINVAL; + + ucontrol->value.enumerated.item[0] = val; + return 0; +} + +static const struct snd_kcontrol_new mtk_dai_dmic_controls[] = { + SOC_ENUM_EXT("DMIC1_HW_GAIN_EN", dmic_gain_on_enum, + mtk_dai_dmic_hw_gain_ctrl_get, + mtk_dai_dmic_hw_gain_ctrl_put), + SOC_ENUM_EXT("DMIC2_HW_GAIN_EN", dmic_gain_on_enum, + mtk_dai_dmic_hw_gain_ctrl_get, + mtk_dai_dmic_hw_gain_ctrl_put), + SOC_ENUM_EXT("DMIC3_HW_GAIN_EN", dmic_gain_on_enum, + mtk_dai_dmic_hw_gain_ctrl_get, + mtk_dai_dmic_hw_gain_ctrl_put), + SOC_ENUM_EXT("DMIC4_HW_GAIN_EN", dmic_gain_on_enum, + mtk_dai_dmic_hw_gain_ctrl_get, + mtk_dai_dmic_hw_gain_ctrl_put), + SOC_SINGLE("DMIC1_HW_GAIN_TARGET", DMIC_GAIN1_CON1, + 0, DMIC_GAIN_MAX_TARGET, 0), + SOC_SINGLE("DMIC2_HW_GAIN_TARGET", DMIC_GAIN2_CON1, + 0, DMIC_GAIN_MAX_TARGET, 0), + SOC_SINGLE("DMIC3_HW_GAIN_TARGET", DMIC_GAIN3_CON1, + 0, DMIC_GAIN_MAX_TARGET, 0), + SOC_SINGLE("DMIC4_HW_GAIN_TARGET", DMIC_GAIN4_CON1, + 0, DMIC_GAIN_MAX_TARGET, 0), + SOC_SINGLE("DMIC1_HW_GAIN_CURRENT", DMIC_GAIN1_CUR, + 0, DMIC_GAIN_MAX_CURRENT, 0), + SOC_SINGLE("DMIC2_HW_GAIN_CURRENT", DMIC_GAIN2_CUR, + 0, DMIC_GAIN_MAX_CURRENT, 0), + SOC_SINGLE("DMIC3_HW_GAIN_CURRENT", DMIC_GAIN3_CUR, + 0, DMIC_GAIN_MAX_CURRENT, 0), + SOC_SINGLE("DMIC4_HW_GAIN_CURRENT", DMIC_GAIN4_CUR, + 0, DMIC_GAIN_MAX_CURRENT, 0), + SOC_SINGLE("DMIC1_HW_GAIN_UP_STEP", DMIC_GAIN1_CON3, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC2_HW_GAIN_UP_STEP", DMIC_GAIN2_CON3, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC3_HW_GAIN_UP_STEP", DMIC_GAIN3_CON3, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC4_HW_GAIN_UP_STEP", DMIC_GAIN4_CON3, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC1_HW_GAIN_DOWN_STEP", DMIC_GAIN1_CON2, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC2_HW_GAIN_DOWN_STEP", DMIC_GAIN2_CON2, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC3_HW_GAIN_DOWN_STEP", DMIC_GAIN3_CON2, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC4_HW_GAIN_DOWN_STEP", DMIC_GAIN4_CON2, + 0, DMIC_GAIN_MAX_STEP, 0), + SOC_SINGLE("DMIC1_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN1_CON0, + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), + SOC_SINGLE("DMIC2_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN2_CON0, + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), + SOC_SINGLE("DMIC3_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN3_CON0, + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), + SOC_SINGLE("DMIC4_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN4_CON0, + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), +}; + +static int init_dmic_priv_data(struct mtk_base_afe *afe) +{ + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_dmic_priv *dmic_priv; + + dmic_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_dmic_priv), + GFP_KERNEL); + if (!dmic_priv) + return -ENOMEM; + + afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN] = dmic_priv; + return 0; +} + +int mt8188_dai_dmic_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_dmic_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_dmic_driver); + dai->dapm_widgets = mtk_dai_dmic_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_dmic_widgets); + dai->dapm_routes = mtk_dai_dmic_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_dmic_routes); + dai->controls = mtk_dai_dmic_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_dmic_controls); + + return init_dmic_priv_data(afe); +} diff --git a/sound/soc/mediatek/mt8188/mt8188-reg.h b/sound/soc/mediatek/mt8188/mt8188-reg.h index bdd885419ff3..2e9c65de249d 100644 --- a/sound/soc/mediatek/mt8188/mt8188-reg.h +++ b/sound/soc/mediatek/mt8188/mt8188-reg.h @@ -2837,9 +2837,20 @@ #define PWR2_TOP_CON_DMIC3_SRC_SEL_MASK GENMASK(16, 14) #define PWR2_TOP_CON_DMIC2_SRC_SEL_MASK GENMASK(13, 11) #define PWR2_TOP_CON_DMIC1_SRC_SEL_MASK GENMASK(10, 8) +#define PWR2_TOP_CON_DMIC8_SRC_SEL_VAL(x) ((x) << 29) +#define PWR2_TOP_CON_DMIC7_SRC_SEL_VAL(x) ((x) << 26) +#define PWR2_TOP_CON_DMIC6_SRC_SEL_VAL(x) ((x) << 23) +#define PWR2_TOP_CON_DMIC5_SRC_SEL_VAL(x) ((x) << 20) +#define PWR2_TOP_CON_DMIC4_SRC_SEL_VAL(x) ((x) << 17) +#define PWR2_TOP_CON_DMIC3_SRC_SEL_VAL(x) ((x) << 14) +#define PWR2_TOP_CON_DMIC2_SRC_SEL_VAL(x) ((x) << 11) +#define PWR2_TOP_CON_DMIC1_SRC_SEL_VAL(x) ((x) << 8) /* PWR2_TOP_CON1 */ -#define PWR2_TOP_CON1_DMIC_CKDIV_ON BIT(1) +#define PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(x) BIT(5 + 6 * (x)) +#define PWR2_TOP_CON1_DMIC_CKDIV_ON BIT(1) +#define PWR2_TOP_CON1_DMIC_CKDIV_ON_SHIFT 1 + /* PCM_INTF_CON1 */ #define PCM_INTF_CON1_SYNC_OUT_INV BIT(23) @@ -2921,13 +2932,14 @@ #define AFE_DMIC_UL_SRC_CON0_UL_TWO_WIRE_MODE_CTL BIT(23) #define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL BIT(22) #define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL BIT(21) - +#define AFE_DMIC_UL_VOICE_MODE(x) (((x) & GENMASK(2, 0)) << 17) #define AFE_DMIC_UL_VOICE_MODE_MASK GENMASK(19, 17) #define AFE_DMIC_UL_CON0_VOCIE_MODE_8K AFE_DMIC_UL_VOICE_MODE(0) #define AFE_DMIC_UL_CON0_VOCIE_MODE_16K AFE_DMIC_UL_VOICE_MODE(1) #define AFE_DMIC_UL_CON0_VOCIE_MODE_32K AFE_DMIC_UL_VOICE_MODE(2) #define AFE_DMIC_UL_CON0_VOCIE_MODE_48K AFE_DMIC_UL_VOICE_MODE(3) #define AFE_DMIC_UL_CON0_VOCIE_MODE_96K AFE_DMIC_UL_VOICE_MODE(4) +#define AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL(x) (((x) & GENMASK(2, 0)) << 7) #define AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL_MASK GENMASK(9, 7) #define AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL BIT(10) #define AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL BIT(1) @@ -2944,6 +2956,7 @@ /* DMIC_GAINx_CON0 */ #define DMIC_GAIN_CON0_GAIN_ON BIT(0) +#define DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT 8 #define DMIC_GAIN_CON0_SAMPLE_PER_STEP_MASK GENMASK(15, 8) /* DMIC_GAINx_CON1 */ From 390ebb24b3c3a95e109c28e14c2ec9fe3f0f8aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 25 Feb 2025 11:33:51 -0300 Subject: [PATCH 181/651] ASoC: mediatek: mt8188-mt6359: Add DMIC support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the DMIC backend, which connects to the DMIC DAI in the platform driver, as well as a "AP DMIC" mic widget. On the Genio 700 EVK board the dual DMIC on-board are wired through that DMIC DAI. Co-developed-by: parkeryang Signed-off-by: parkeryang Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250225-genio700-dmic-v2-5-3076f5b50ef7@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-mt6359.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index 2d0d04e0232d..420b1427b71d 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -150,6 +150,11 @@ SND_SOC_DAILINK_DEFS(dl_src, "mt6359-snd-codec-aif1")), DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(DMIC_BE, + DAILINK_COMP_ARRAY(COMP_CPU("DMIC")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + SND_SOC_DAILINK_DEFS(dptx, DAILINK_COMP_ARRAY(COMP_CPU("DPTX")), DAILINK_COMP_ARRAY(COMP_DUMMY()), @@ -297,6 +302,7 @@ static const struct snd_soc_dapm_widget mt8188_rear_spk_widgets[] = { static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("AP DMIC", NULL), SND_SOC_DAPM_SINK("HDMI"), SND_SOC_DAPM_SINK("DP"), SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), @@ -533,6 +539,7 @@ enum { DAI_LINK_UL9_FE, DAI_LINK_UL10_FE, DAI_LINK_DL_SRC_BE, + DAI_LINK_DMIC_BE, DAI_LINK_DPTX_BE, DAI_LINK_ETDM1_IN_BE, DAI_LINK_ETDM2_IN_BE, @@ -1120,6 +1127,13 @@ static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = { .playback_only = 1, SND_SOC_DAILINK_REG(dl_src), }, + [DAI_LINK_DMIC_BE] = { + .name = "DMIC_BE", + .no_pcm = 1, + .capture_only = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(DMIC_BE), + }, [DAI_LINK_DPTX_BE] = { .name = "DPTX_BE", .ops = &mt8188_dptx_ops, From f00b3056843d14754ac1bab2106cf5599680f115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Tue, 25 Feb 2025 11:33:53 -0300 Subject: [PATCH 182/651] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add DMIC backend to dai-link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MT8188 platforms also have DMIC DAIs, which were previously undescribed. Add DMIC_BE as a possible backend for the dai-link property. Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20250225-genio700-dmic-v2-7-3076f5b50ef7@collabora.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml index 362e729b51b4..8c77e7f68ad7 100644 --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml @@ -62,6 +62,7 @@ patternProperties: - PCM1_BE - DL_SRC_BE - UL_SRC_BE + - DMIC_BE codec: description: Holds subnode which indicates codec dai. From 62142da241a08006f89b0620f7291e3a08c0a094 Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Wed, 26 Feb 2025 16:47:28 +0800 Subject: [PATCH 183/651] ASoC: rt712-sdca: Add FU05 playback switch control Because there is no playback switch control for rt712-sdw headphone endpoint, it causes there is no way to control HP on and off in ALSA UCM config. Signed-off-by: derek.fang Signed-off-by: Shuming Fan Link: https://patch.msgid.link/20250226084728.1889082-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt712-sdca.c | 80 +++++++++++++++++++++++++++-------- sound/soc/codecs/rt712-sdca.h | 3 ++ 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/rt712-sdca.c b/sound/soc/codecs/rt712-sdca.c index 78dbf9eed494..19d99b9d4ab2 100644 --- a/sound/soc/codecs/rt712-sdca.c +++ b/sound/soc/codecs/rt712-sdca.c @@ -652,6 +652,61 @@ static int rt712_sdca_fu0f_capture_put(struct snd_kcontrol *kcontrol, return 1; } +static int rt712_sdca_set_fu05_playback_ctl(struct rt712_sdca_priv *rt712) +{ + int err; + unsigned int ch_01, ch_02; + + ch_01 = (rt712->fu05_dapm_mute || rt712->fu05_mixer_l_mute) ? 0x01 : 0x00; + ch_02 = (rt712->fu05_dapm_mute || rt712->fu05_mixer_r_mute) ? 0x01 : 0x00; + + err = regmap_write(rt712->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, + RT712_SDCA_CTL_FU_MUTE, CH_01), ch_01); + if (err < 0) + return err; + + err = regmap_write(rt712->regmap, + SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, + RT712_SDCA_CTL_FU_MUTE, CH_02), ch_02); + if (err < 0) + return err; + + return 0; +} + +static int rt712_sdca_fu05_playback_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = !rt712->fu05_mixer_l_mute; + ucontrol->value.integer.value[1] = !rt712->fu05_mixer_r_mute; + return 0; +} + +static int rt712_sdca_fu05_playback_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); + int err; + + if (rt712->fu05_mixer_l_mute == !ucontrol->value.integer.value[0] && + rt712->fu05_mixer_r_mute == !ucontrol->value.integer.value[1]) + return 0; + + rt712->fu05_mixer_l_mute = !ucontrol->value.integer.value[0]; + rt712->fu05_mixer_r_mute = !ucontrol->value.integer.value[1]; + + err = rt712_sdca_set_fu05_playback_ctl(rt712); + if (err < 0) + return err; + + return 1; +} + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0); static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -1725, 75, 0); static const DECLARE_TLV_DB_SCALE(boost_vol_tlv, 0, 1000, 0); @@ -674,6 +729,8 @@ static const struct snd_kcontrol_new rt712_sdca_controls[] = { SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_PLATFORM_FU44, RT712_SDCA_CTL_FU_CH_GAIN, CH_02), 8, 3, 0, rt712_sdca_set_gain_get, rt712_sdca_set_gain_put, boost_vol_tlv), + SOC_DOUBLE_EXT("FU05 Playback Switch", SND_SOC_NOPM, 0, 1, 1, 0, + rt712_sdca_fu05_playback_get, rt712_sdca_fu05_playback_put), }; static const struct snd_kcontrol_new rt712_sdca_spk_controls[] = { @@ -766,28 +823,15 @@ static int rt712_sdca_fu05_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct rt712_sdca_priv *rt712 = snd_soc_component_get_drvdata(component); - unsigned char unmute = 0x0, mute = 0x1; switch (event) { case SND_SOC_DAPM_POST_PMU: - regmap_write(rt712->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, - RT712_SDCA_CTL_FU_MUTE, CH_01), - unmute); - regmap_write(rt712->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, - RT712_SDCA_CTL_FU_MUTE, CH_02), - unmute); + rt712->fu05_dapm_mute = false; + rt712_sdca_set_fu05_playback_ctl(rt712); break; case SND_SOC_DAPM_PRE_PMD: - regmap_write(rt712->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, - RT712_SDCA_CTL_FU_MUTE, CH_01), - mute); - regmap_write(rt712->regmap, - SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, - RT712_SDCA_CTL_FU_MUTE, CH_02), - mute); + rt712->fu05_dapm_mute = true; + rt712_sdca_set_fu05_playback_ctl(rt712); break; } return 0; @@ -1640,6 +1684,8 @@ int rt712_sdca_init(struct device *dev, struct regmap *regmap, rt712->fu1e_dapm_mute = true; rt712->fu1e_mixer_mute[0] = rt712->fu1e_mixer_mute[1] = rt712->fu1e_mixer_mute[2] = rt712->fu1e_mixer_mute[3] = true; + rt712->fu05_dapm_mute = true; + rt712->fu05_mixer_l_mute = rt712->fu05_mixer_r_mute = false; /* JD source uses JD1 in default */ rt712->jd_src = RT712_JD1; diff --git a/sound/soc/codecs/rt712-sdca.h b/sound/soc/codecs/rt712-sdca.h index a08491496d90..7ab7d5feb50a 100644 --- a/sound/soc/codecs/rt712-sdca.h +++ b/sound/soc/codecs/rt712-sdca.h @@ -42,6 +42,9 @@ struct rt712_sdca_priv { bool fu0f_mixer_r_mute; bool fu1e_dapm_mute; bool fu1e_mixer_mute[4]; + bool fu05_dapm_mute; + bool fu05_mixer_l_mute; + bool fu05_mixer_r_mute; }; struct rt712_dmic_kctrl_priv { From a206376b425472c7c3a824f47a9967a4c97ae32c Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Wed, 26 Feb 2025 12:23:22 +0000 Subject: [PATCH 184/651] ASoC: dt-bindings: xlnx,i2s: Convert to json-schema Convert the Xilinx I2S device tree binding documentation to json-schema. Reviewed-by: Rob Herring (Arm) Signed-off-by: Vincenzo Frascino Link: https://patch.msgid.link/20250226122325.2014547-2-vincenzo.frascino@arm.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/xlnx,i2s.txt | 28 -------- .../devicetree/bindings/sound/xlnx,i2s.yaml | 65 +++++++++++++++++++ 2 files changed, 65 insertions(+), 28 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/xlnx,i2s.txt create mode 100644 Documentation/devicetree/bindings/sound/xlnx,i2s.yaml diff --git a/Documentation/devicetree/bindings/sound/xlnx,i2s.txt b/Documentation/devicetree/bindings/sound/xlnx,i2s.txt deleted file mode 100644 index 5e7c7d5bb60a..000000000000 --- a/Documentation/devicetree/bindings/sound/xlnx,i2s.txt +++ /dev/null @@ -1,28 +0,0 @@ -Device-Tree bindings for Xilinx I2S PL block - -The IP supports I2S based playback/capture audio - -Required property: - - compatible: "xlnx,i2s-transmitter-1.0" for playback and - "xlnx,i2s-receiver-1.0" for capture - -Required property common to both I2S playback and capture: - - reg: Base address and size of the IP core instance. - - xlnx,dwidth: sample data width. Can be any of 16, 24. - - xlnx,num-channels: Number of I2S streams. Can be any of 1, 2, 3, 4. - supported channels = 2 * xlnx,num-channels - -Example: - - i2s_receiver@a0080000 { - compatible = "xlnx,i2s-receiver-1.0"; - reg = <0x0 0xa0080000 0x0 0x10000>; - xlnx,dwidth = <0x18>; - xlnx,num-channels = <1>; - }; - i2s_transmitter@a0090000 { - compatible = "xlnx,i2s-transmitter-1.0"; - reg = <0x0 0xa0090000 0x0 0x10000>; - xlnx,dwidth = <0x18>; - xlnx,num-channels = <1>; - }; diff --git a/Documentation/devicetree/bindings/sound/xlnx,i2s.yaml b/Documentation/devicetree/bindings/sound/xlnx,i2s.yaml new file mode 100644 index 000000000000..3c2b0be07c53 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/xlnx,i2s.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/xlnx,i2s.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx I2S PL block + +description: + The IP supports I2S based playback/capture audio. + +maintainers: + - Vincenzo Frascino + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + enum: + - xlnx,i2s-receiver-1.0 + - xlnx,i2s-transmitter-1.0 + + reg: + maxItems: 1 + + xlnx,dwidth: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 16 + - 24 + description: | + Sample data width. + + xlnx,num-channels: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 4 + description: | + Number of I2S streams. + +required: + - compatible + - reg + - xlnx,dwidth + - xlnx,num-channels + +additionalProperties: false + +examples: + - | + i2s@a0080000 { + compatible = "xlnx,i2s-receiver-1.0"; + reg = <0xa0080000 0x10000>; + xlnx,dwidth = <0x18>; + xlnx,num-channels = <1>; + }; + i2s@a0090000 { + compatible = "xlnx,i2s-transmitter-1.0"; + reg = <0xa0090000 0x10000>; + xlnx,dwidth = <0x18>; + xlnx,num-channels = <1>; + }; + +... From 1b8b6dd0c91b7db58e344f01781932458ac43da3 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Wed, 26 Feb 2025 12:23:23 +0000 Subject: [PATCH 185/651] ASoC: dt-bindings: xlnx,audio-formatter: Convert to json-schema Convert the Xilinx Audio Formatter 1.0 device tree binding documentation to json-schema. Reviewed-by: Rob Herring (Arm) Signed-off-by: Vincenzo Frascino Link: https://patch.msgid.link/20250226122325.2014547-3-vincenzo.frascino@arm.com Signed-off-by: Mark Brown --- .../bindings/sound/xlnx,audio-formatter.txt | 29 -------- .../bindings/sound/xlnx,audio-formatter.yaml | 72 +++++++++++++++++++ 2 files changed, 72 insertions(+), 29 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt create mode 100644 Documentation/devicetree/bindings/sound/xlnx,audio-formatter.yaml diff --git a/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt b/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt deleted file mode 100644 index cbc93c8f4963..000000000000 --- a/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt +++ /dev/null @@ -1,29 +0,0 @@ -Device-Tree bindings for Xilinx PL audio formatter - -The IP core supports DMA, data formatting(AES<->PCM conversion) -of audio samples. - -Required properties: - - compatible: "xlnx,audio-formatter-1.0" - - interrupt-names: Names specified to list of interrupts in same - order mentioned under "interrupts". - List of supported interrupt names are: - "irq_mm2s" : interrupt from MM2S block - "irq_s2mm" : interrupt from S2MM block - - interrupts-parent: Phandle for interrupt controller. - - interrupts: List of Interrupt numbers. - - reg: Base address and size of the IP core instance. - - clock-names: List of input clocks. - Required elements: "s_axi_lite_aclk", "aud_mclk" - - clocks: Input clock specifier. Refer to common clock bindings. - -Example: - audio_ss_0_audio_formatter_0: audio_formatter@80010000 { - compatible = "xlnx,audio-formatter-1.0"; - interrupt-names = "irq_mm2s", "irq_s2mm"; - interrupt-parent = <&gic>; - interrupts = <0 104 4>, <0 105 4>; - reg = <0x0 0x80010000 0x0 0x1000>; - clock-names = "s_axi_lite_aclk", "aud_mclk"; - clocks = <&clk 71>, <&clk_wiz_1 0>; - }; diff --git a/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.yaml b/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.yaml new file mode 100644 index 000000000000..82fa448bd2e9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/xlnx,audio-formatter.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx PL audio formatter + +description: + The IP core supports DMA, data formatting(AES<->PCM conversion) + of audio samples. + +maintainers: + - Vincenzo Frascino + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + enum: + - xlnx,audio-formatter-1.0 + + reg: + maxItems: 1 + + interrupt-names: + minItems: 1 + items: + - const: irq_mm2s + - const: irq_s2mm + + interrupts: + minItems: 1 + items: + - description: interrupt from MM2S block + - description: interrupt from S2MM block + + clock-names: + minItems: 1 + items: + - const: s_axi_lite_aclk + - const: aud_mclk + + clocks: + minItems: 1 + items: + - description: clock for the axi data stream + - description: clock for the MEMS microphone data stream + +required: + - compatible + - reg + - interrupt-names + - interrupts + - clock-names + - clocks + +additionalProperties: false + +examples: + - | + audio_formatter@80010000 { + compatible = "xlnx,audio-formatter-1.0"; + reg = <0x80010000 0x1000>; + interrupt-names = "irq_mm2s", "irq_s2mm"; + interrupt-parent = <&gic>; + interrupts = <0 104 4>, <0 105 4>; + clock-names = "s_axi_lite_aclk", "aud_mclk"; + clocks = <&clk 71>, <&clk_wiz_1 0>; + }; +... From 7ed7065dfbbac1b5405a0c8029299847e408cf97 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Wed, 26 Feb 2025 12:23:24 +0000 Subject: [PATCH 186/651] ASoC: dt-bindings: xlnx,spdif: Convert to json-schema Convert the Xilinx SPDIF 2.0 device tree binding documentation to json-schema. Reviewed-by: Rob Herring (Arm) Signed-off-by: Vincenzo Frascino Link: https://patch.msgid.link/20250226122325.2014547-4-vincenzo.frascino@arm.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/xlnx,spdif.txt | 28 ------- .../devicetree/bindings/sound/xlnx,spdif.yaml | 77 +++++++++++++++++++ 2 files changed, 77 insertions(+), 28 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/xlnx,spdif.txt create mode 100644 Documentation/devicetree/bindings/sound/xlnx,spdif.yaml diff --git a/Documentation/devicetree/bindings/sound/xlnx,spdif.txt b/Documentation/devicetree/bindings/sound/xlnx,spdif.txt deleted file mode 100644 index 15c2d64d247c..000000000000 --- a/Documentation/devicetree/bindings/sound/xlnx,spdif.txt +++ /dev/null @@ -1,28 +0,0 @@ -Device-Tree bindings for Xilinx SPDIF IP - -The IP supports playback and capture of SPDIF audio - -Required properties: - - compatible: "xlnx,spdif-2.0" - - clock-names: List of input clocks. - Required elements: "s_axi_aclk", "aud_clk_i" - - clocks: Input clock specifier. Refer to common clock bindings. - - reg: Base address and address length of the IP core instance. - - interrupts-parent: Phandle for interrupt controller. - - interrupts: List of Interrupt numbers. - - xlnx,spdif-mode: 0 :- receiver mode - 1 :- transmitter mode - - xlnx,aud_clk_i: input audio clock value. - -Example: - spdif_0: spdif@80010000 { - clock-names = "aud_clk_i", "s_axi_aclk"; - clocks = <&misc_clk_0>, <&clk 71>; - compatible = "xlnx,spdif-2.0"; - interrupt-names = "spdif_interrupt"; - interrupt-parent = <&gic>; - interrupts = <0 91 4>; - reg = <0x0 0x80010000 0x0 0x10000>; - xlnx,spdif-mode = <1>; - xlnx,aud_clk_i = <49152913>; - }; diff --git a/Documentation/devicetree/bindings/sound/xlnx,spdif.yaml b/Documentation/devicetree/bindings/sound/xlnx,spdif.yaml new file mode 100644 index 000000000000..a45d8a0755fe --- /dev/null +++ b/Documentation/devicetree/bindings/sound/xlnx,spdif.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/xlnx,spdif.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx SPDIF IP + +description: + The IP supports playback and capture of SPDIF audio. + +maintainers: + - Vincenzo Frascino + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + enum: + - xlnx,spdif-2.0 + + reg: + maxItems: 1 + + interrupts: + items: + - description: SPDIF audio interrupt + + clock-names: + items: + - const: aud_clk_i + - const: s_axi_aclk + + clocks: + minItems: 1 + items: + - description: input audio clock + - description: clock for the AXI data stream + + xlnx,spdif-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 + - 1 + description: | + 0 - receiver + 1 - transmitter + + xlnx,aud_clk_i: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Input audio clock frequency. It affects the sampling rate. + +required: + - compatible + - reg + - interrupts + - clock-names + - clocks + +additionalProperties: false + +examples: + - | + spdif@80010000 { + compatible = "xlnx,spdif-2.0"; + reg = <0x80010000 0x10000>; + clock-names = "aud_clk_i", "s_axi_aclk"; + clocks = <&misc_clk_0>, <&clk 71>; + interrupt-parent = <&gic>; + interrupts = <0 91 4>; + xlnx,spdif-mode = <1>; + xlnx,aud_clk_i = <49152913>; + }; + +... From 55a1abd6e76ce91eb6049f32efec3a8506686748 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Wed, 26 Feb 2025 12:23:25 +0000 Subject: [PATCH 187/651] MAINTAINERS: Add Vincenzo Frascino as Xilinx Sound Driver Maintainer Add Vincenzo Frascino as Xilinx Sound Driver Maintainer. Signed-off-by: Vincenzo Frascino Link: https://patch.msgid.link/20250226122325.2014547-5-vincenzo.frascino@arm.com Signed-off-by: Mark Brown --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7671b498d5e8..51a9992b4da3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -26009,6 +26009,14 @@ S: Maintained F: drivers/pwm/pwm-xilinx.c F: include/clocksource/timer-xilinx.h +XILINX SOUND DRIVERS +M: Vincenzo Frascino +S: Maintained +F: Documentation/devicetree/bindings/sound/xlnx,i2s.yaml +F: Documentation/devicetree/bindings/sound/xlnx,audio-formatter.yaml +F: Documentation/devicetree/bindings/sound/xlnx,spdif.yaml +F: sound/soc/xilinx/* + XILINX SD-FEC IP CORES M: Derek Kiernan M: Dragan Cvetic From be1e3607f29a5a182eaa70e3058aef32fd0cc4f8 Mon Sep 17 00:00:00 2001 From: Baojun Xu Date: Wed, 26 Feb 2025 22:43:28 +0800 Subject: [PATCH 188/651] ASoC: tas2781: Clean up for some define Do some clean up for some define in header file. Like change lower case in value, up case in define, space add in recommends, change date of files and add author. Signed-off-by: Baojun Xu Link: https://patch.msgid.link/20250226144328.11645-1-baojun.xu@ti.com Signed-off-by: Mark Brown --- include/sound/tas2781.h | 21 +++++++++++---------- sound/soc/codecs/tas2781-fmwlib.c | 7 ++++--- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 0f1e585635bb..4d9a37544354 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -2,7 +2,7 @@ // // ALSA SoC Texas Instruments TAS2563/TAS2781 Audio Smart Amplifier // -// Copyright (C) 2022 - 2024 Texas Instruments Incorporated +// Copyright (C) 2022 - 2025 Texas Instruments Incorporated // https://www.ti.com // // The TAS2563/TAS2781 driver implements a flexible and configurable @@ -11,6 +11,7 @@ // // Author: Shenghao Ding // Author: Kevin Lu +// Author: Baojun Xu // #ifndef __TAS2781_H__ @@ -31,7 +32,7 @@ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -/*PAGE Control Register (available in page0 of each book) */ +/* PAGE Control Register (available in page0 of each book) */ #define TASDEVICE_PAGE_SELECT 0x00 #define TASDEVICE_BOOKCTL_PAGE 0x00 #define TASDEVICE_BOOKCTL_REG 127 @@ -42,12 +43,12 @@ #define TASDEVICE_REG(book, page, reg) (((book * 256 * 128) + \ (page * 128)) + reg) -/*Software Reset */ -#define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0X0, 0x01) +/* Software Reset */ +#define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0x0, 0x01) #define TASDEVICE_REG_SWRESET_RESET BIT(0) -/*I2C Checksum */ -#define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E) +/* I2C Checksum */ +#define TASDEVICE_CHECKSUM_REG TASDEVICE_REG(0x0, 0x0, 0x7e) /* XM_340 */ #define TASDEVICE_XM_A1_REG TASDEVICE_REG(0x64, 0x63, 0x3c) @@ -55,8 +56,8 @@ #define TASDEVICE_XM_A2_REG TASDEVICE_REG(0x64, 0x63, 0x38) /* Volume control */ -#define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0C) -#define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A) +#define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0c) +#define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1a) #define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03) #define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1) @@ -95,8 +96,8 @@ #define TAS2781_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x14, 0x40) #define TAS2781_PRM_SINEGAIN2_REG TASDEVICE_REG(0x00, 0x14, 0x44) -#define TAS2781_TEST_UNLOCK_REG TASDEVICE_REG(0x00, 0xFD, 0x0D) -#define TAS2781_TEST_PAGE_UNLOCK 0x0D +#define TAS2781_TEST_UNLOCK_REG TASDEVICE_REG(0x00, 0xfd, 0x0d) +#define TAS2781_TEST_PAGE_UNLOCK 0x0d #define TAS2781_RUNTIME_LATCH_RE_REG TASDEVICE_REG(0x00, 0x00, 0x49) #define TAS2781_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x62, 0x48) diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 61d9c220b6a4..bc2f68bd9846 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -2,9 +2,10 @@ // // tas2781-fmwlib.c -- TASDEVICE firmware support // -// Copyright 2023 - 2024 Texas Instruments, Inc. +// Copyright 2023 - 2025 Texas Instruments, Inc. // // Author: Shenghao Ding +// Author: Baojun Xu #include #include @@ -1496,7 +1497,7 @@ static int tasdev_block_chksum(struct tasdevice_priv *tas_priv, unsigned int nr_value; int ret; - ret = tasdevice_dev_read(tas_priv, chn, TASDEVICE_I2CChecksum, + ret = tasdevice_dev_read(tas_priv, chn, TASDEVICE_CHECKSUM_REG, &nr_value); if (ret < 0) { dev_err(tas_priv->dev, "%s: Chn %d\n", __func__, chn); @@ -1540,7 +1541,7 @@ static int tasdev_load_blk(struct tasdevice_priv *tas_priv, while (block->nr_retry > 0) { if (block->is_pchksum_present) { ret = tasdevice_dev_write(tas_priv, chn, - TASDEVICE_I2CChecksum, 0); + TASDEVICE_CHECKSUM_REG, 0); if (ret < 0) break; } From 604a0fe88db0ecef56ac38156a154945f4535ddf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 27 Feb 2025 10:51:49 +0100 Subject: [PATCH 189/651] ALSA: pcm: Drop superfluous NULL check in snd_pcm_format_set_silence() We applied a fix for a KASAN issue for snd_pcm_format_set_silence(), and it introduced a NULL check of pat. But this turned out to be utterly superfluous; it points to pcm_formats[].silence, and this is an array, which can be never NULL. The problem (supposedly) it tried to address at that time was likely already fixed by another commit 8423f0b6d513 ("ALSA: pcm: oss: Fix race at SNDCTL_DSP_SYNC") instead. So let's drop the superfluous NULL check again. While we're at it, keep the whitespace fix and move the pat assignment after the width check for a bit better code readability. Fixes: 2f7a26abb824 ("ALSA: pcm: Test for "silence" field in struct "pcm_format_data"") Link: https://patch.msgid.link/20250227095150.8187-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/pcm_misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 4f556211bb56..d3a08e292072 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -432,9 +432,9 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int if (samples == 0) return 0; width = pcm_formats[(INT)format].phys; /* physical width */ - pat = pcm_formats[(INT)format].silence; - if (!width || !pat) + if (!width) return -EINVAL; + pat = pcm_formats[(INT)format].silence; /* signed or 1 byte data */ if (pcm_formats[(INT)format].signd == 1 || width <= 8) { unsigned int bytes = samples * width / 8; From aeb7cf20285ad322984480086c21bd3a04d419bc Mon Sep 17 00:00:00 2001 From: Charles Han Date: Thu, 27 Feb 2025 16:52:00 +0800 Subject: [PATCH 190/651] ALSA: emu10k1: fix inconsistent indenting warning in snd_emu10k1_synth_free() Fix below inconsistent indenting smatch warning. smatch warnings: sound/pci/emu10k1/memory.c:444 snd_emu10k1_synth_free() warn: inconsistent indenting Signed-off-by: Charles Han Link: https://patch.msgid.link/20250227085243.18413-1-hanchunchao@inspur.com Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index d29711777161..f6982bc6ff0d 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -441,7 +441,7 @@ snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk) unmap_memblk(emu, blk); spin_unlock_irqrestore(&emu->memblk_lock, flags); synth_free_pages(emu, blk); - __snd_util_mem_free(hdr, memblk); + __snd_util_mem_free(hdr, memblk); mutex_unlock(&hdr->block_mutex); return 0; } From e747104c99fd3a97044e734b0cad9a6227699937 Mon Sep 17 00:00:00 2001 From: Charles Han Date: Thu, 27 Feb 2025 17:18:10 +0800 Subject: [PATCH 191/651] ALSA: opti9xx: fix inconsistent indenting warning in snd_opti9xx_configure() Fix below inconsistent indenting smatch warning. smatch warnings: sound/isa/opti9xx/opti92x-ad1848.c:489 snd_opti9xx_configure() warn: inconsistent indenting Signed-off-by: Charles Han Link: https://patch.msgid.link/20250227091810.18847-1-hanchunchao@inspur.com Signed-off-by: Takashi Iwai --- sound/isa/opti9xx/opti92x-ad1848.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 220ea1952c1e..a07a665d93dc 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -486,7 +486,7 @@ __skip_base: #endif /* CS4231 || OPTi93X */ #ifndef OPTi93X - outb(irq_bits << 3 | dma_bits, chip->wss_base); + outb(irq_bits << 3 | dma_bits, chip->wss_base); #else /* OPTi93X */ snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); #endif /* OPTi93X */ From fd80df352ba1884ce2b62dd8d9495582308101b7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 17 Feb 2025 14:01:56 +0000 Subject: [PATCH 192/651] regcache: Add support for sorting defaults arrays The defaults array in regcache must be sorted into ascending register address order, because binary search is used to locate values in the array. Add a helper to sort the register defaults array which can be useful for systems that dynamically create a defaults array based on external information. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250217140159.2288784-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 31 +++++++++++++++++++++++++++++++ include/linux/regmap.h | 7 +++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index b1f8508c3966..f7fcf2de1301 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -21,6 +21,37 @@ static const struct regcache_ops *cache_types[] = { ®cache_flat_ops, }; +static int regcache_defaults_cmp(const void *a, const void *b) +{ + const struct reg_default *x = a; + const struct reg_default *y = b; + + if (x->reg > y->reg) + return 1; + else if (x->reg < y->reg) + return -1; + else + return 0; +} + +static void regcache_defaults_swap(void *a, void *b, int size) +{ + struct reg_default *x = a; + struct reg_default *y = b; + struct reg_default tmp; + + tmp = *x; + *x = *y; + *y = tmp; +} + +void regcache_sort_defaults(struct reg_default *defaults, unsigned int ndefaults) +{ + sort(defaults, ndefaults, sizeof(*defaults), + regcache_defaults_cmp, regcache_defaults_swap); +} +EXPORT_SYMBOL_GPL(regcache_sort_defaults); + static int regcache_hw_init(struct regmap *map) { int i, j; diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 3a96d068915f..d17c5ea3d55d 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1352,6 +1352,7 @@ bool regmap_can_raw_write(struct regmap *map); size_t regmap_get_raw_read_max(struct regmap *map); size_t regmap_get_raw_write_max(struct regmap *map); +void regcache_sort_defaults(struct reg_default *defaults, unsigned int ndefaults); int regcache_sync(struct regmap *map); int regcache_sync_region(struct regmap *map, unsigned int min, unsigned int max); @@ -2043,6 +2044,12 @@ static inline bool regmap_might_sleep(struct regmap *map) return true; } +static inline void regcache_sort_defaults(struct reg_default *defaults, + unsigned int ndefaults) +{ + WARN_ONCE(1, "regmap API is disabled"); +} + static inline int regcache_sync(struct regmap *map) { WARN_ONCE(1, "regmap API is disabled"); From e3f7caf74b795621252e3c25b4a9fb6888336ef1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 17 Feb 2025 14:01:57 +0000 Subject: [PATCH 193/651] ASoC: SDCA: Add generic regmap SDCA helpers Add helper functions that SDCA drivers can use to calculate the properties of SDCA Controls (registers) specified through DisCo. Most of these are fairly obvious from the SDCA Access Modes. DisCo Constants, values which are specified in the ACPI rather than on the device, are handled as unreadable and unwritable registers. The intention is these will be populated in the register defaults table allowing drivers to read them normally. This means the drivers can be agnostic as to which values are DisCo Constants. Finally, support for SDCA Dual Ranked Controls is currently limited here, at the moment the current value will be used directly. Writing the current value directly is valid as per the specification although the synchronicity of updates across multiple registers is lost. Support for this will probably need to be added later. But its a fairly hard problem and doesn't need to be solved immediately. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250217140159.2288784-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_regmap.h | 21 ++++ sound/soc/sdca/Makefile | 2 +- sound/soc/sdca/sdca_regmap.c | 192 +++++++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 include/sound/sdca_regmap.h create mode 100644 sound/soc/sdca/sdca_regmap.c diff --git a/include/sound/sdca_regmap.h b/include/sound/sdca_regmap.h new file mode 100644 index 000000000000..11826f4f0726 --- /dev/null +++ b/include/sound/sdca_regmap.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * The MIPI SDCA specification is available for public downloads at + * https://www.mipi.org/mipi-sdca-v1-0-download + * + * Copyright (C) 2025 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ + +#ifndef __SDCA_REGMAP_H__ +#define __SDCA_REGMAP_H__ + +struct sdca_function_data; + +bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg); +bool sdca_regmap_writeable(struct sdca_function_data *function, unsigned int reg); +bool sdca_regmap_volatile(struct sdca_function_data *function, unsigned int reg); +bool sdca_regmap_deferrable(struct sdca_function_data *function, unsigned int reg); +int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg); + +#endif // __SDCA_REGMAP_H__ diff --git a/sound/soc/sdca/Makefile b/sound/soc/sdca/Makefile index 5d1ddbbfbf62..dddc3e694256 100644 --- a/sound/soc/sdca/Makefile +++ b/sound/soc/sdca/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -snd-soc-sdca-y := sdca_functions.o sdca_device.o +snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_regmap.o obj-$(CONFIG_SND_SOC_SDCA) += snd-soc-sdca.o diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c new file mode 100644 index 000000000000..ae6358f0fc26 --- /dev/null +++ b/sound/soc/sdca/sdca_regmap.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2025 Cirrus Logic, Inc. and +// Cirrus Logic International Semiconductor Ltd. + +/* + * The MIPI SDCA specification is available for public downloads at + * https://www.mipi.org/mipi-sdca-v1-0-download + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct sdca_entity * +function_find_entity(struct sdca_function_data *function, unsigned int reg) +{ + int i; + + for (i = 0; i < function->num_entities; i++) + if (SDW_SDCA_CTL_ENT(reg) == function->entities[i].id) + return &function->entities[i]; + + return NULL; +} + +static struct sdca_control * +entity_find_control(struct sdca_entity *entity, unsigned int reg) +{ + int i; + + for (i = 0; i < entity->num_controls; i++) { + if (SDW_SDCA_CTL_CSEL(reg) == entity->controls[i].sel) + return &entity->controls[i]; + } + + return NULL; +} + +static struct sdca_control * +function_find_control(struct sdca_function_data *function, unsigned int reg) +{ + struct sdca_entity *entity; + + entity = function_find_entity(function, reg); + if (!entity) + return NULL; + + return entity_find_control(entity, reg); +} + +/** + * sdca_regmap_readable - return if a given SDCA Control is readable + * @function: Pointer to the Function information. + * @reg: Register address/Control to be processed. + * + * Return: Returns true if the register is readable. + */ +bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg) +{ + struct sdca_control *control; + + if (!SDW_SDCA_VALID_CTL(reg)) + return false; + + control = function_find_control(function, reg); + if (!control) + return false; + + switch (control->mode) { + case SDCA_ACCESS_MODE_RW: + case SDCA_ACCESS_MODE_RO: + case SDCA_ACCESS_MODE_DUAL: + case SDCA_ACCESS_MODE_RW1S: + case SDCA_ACCESS_MODE_RW1C: + /* No access to registers marked solely for device use */ + return control->layers & ~SDCA_ACCESS_LAYER_DEVICE; + default: + return false; + } +} +EXPORT_SYMBOL_NS(sdca_regmap_readable, "SND_SOC_SDCA"); + +/** + * sdca_regmap_writeable - return if a given SDCA Control is writeable + * @function: Pointer to the Function information. + * @reg: Register address/Control to be processed. + * + * Return: Returns true if the register is writeable. + */ +bool sdca_regmap_writeable(struct sdca_function_data *function, unsigned int reg) +{ + struct sdca_control *control; + + if (!SDW_SDCA_VALID_CTL(reg)) + return false; + + control = function_find_control(function, reg); + if (!control) + return false; + + switch (control->mode) { + case SDCA_ACCESS_MODE_RW: + case SDCA_ACCESS_MODE_DUAL: + case SDCA_ACCESS_MODE_RW1S: + case SDCA_ACCESS_MODE_RW1C: + /* No access to registers marked solely for device use */ + return control->layers & ~SDCA_ACCESS_LAYER_DEVICE; + default: + return false; + } +} +EXPORT_SYMBOL_NS(sdca_regmap_writeable, "SND_SOC_SDCA"); + +/** + * sdca_regmap_volatile - return if a given SDCA Control is volatile + * @function: Pointer to the Function information. + * @reg: Register address/Control to be processed. + * + * Return: Returns true if the register is volatile. + */ +bool sdca_regmap_volatile(struct sdca_function_data *function, unsigned int reg) +{ + struct sdca_control *control; + + if (!SDW_SDCA_VALID_CTL(reg)) + return false; + + control = function_find_control(function, reg); + if (!control) + return false; + + switch (control->mode) { + case SDCA_ACCESS_MODE_RO: + case SDCA_ACCESS_MODE_RW1S: + case SDCA_ACCESS_MODE_RW1C: + return true; + default: + return false; + } +} +EXPORT_SYMBOL_NS(sdca_regmap_volatile, "SND_SOC_SDCA"); + +/** + * sdca_regmap_deferrable - return if a given SDCA Control is deferrable + * @function: Pointer to the Function information. + * @reg: Register address/Control to be processed. + * + * Return: Returns true if the register is deferrable. + */ +bool sdca_regmap_deferrable(struct sdca_function_data *function, unsigned int reg) +{ + struct sdca_control *control; + + if (!SDW_SDCA_VALID_CTL(reg)) + return false; + + control = function_find_control(function, reg); + if (!control) + return false; + + return control->deferrable; +} +EXPORT_SYMBOL_NS(sdca_regmap_deferrable, "SND_SOC_SDCA"); + +/** + * sdca_regmap_mbq_size - return size in bytes of a given SDCA Control + * @function: Pointer to the Function information. + * @reg: Register address/Control to be processed. + * + * Return: Returns the size in bytes of the Control. + */ +int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg) +{ + struct sdca_control *control; + + if (!SDW_SDCA_VALID_CTL(reg)) + return -EINVAL; + + control = function_find_control(function, reg); + if (!control) + return false; + + return clamp_val(control->nbits / BITS_PER_BYTE, sizeof(u8), sizeof(u32)); +} +EXPORT_SYMBOL_NS(sdca_regmap_mbq_size, "SND_SOC_SDCA"); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SDCA library"); From 28c12866c22c2826ccbd8c82dc353f02ab2deea5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 17 Feb 2025 14:01:58 +0000 Subject: [PATCH 194/651] ASoC: SDCA: Add regmap helpers for parsing for DisCo Constant values Add helpers to parse the DisCo Constant values from ACPI and populate an array of reg_defaults with these. This will allow drivers to access these ACPI specified values through the same interface as other registers that are physically present on the device, using the regmap cache. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250217140159.2288784-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_regmap.h | 6 +++ sound/soc/sdca/sdca_regmap.c | 80 ++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/include/sound/sdca_regmap.h b/include/sound/sdca_regmap.h index 11826f4f0726..850533e83f3b 100644 --- a/include/sound/sdca_regmap.h +++ b/include/sound/sdca_regmap.h @@ -10,7 +10,9 @@ #ifndef __SDCA_REGMAP_H__ #define __SDCA_REGMAP_H__ +struct device; struct sdca_function_data; +struct reg_default; bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg); bool sdca_regmap_writeable(struct sdca_function_data *function, unsigned int reg); @@ -18,4 +20,8 @@ bool sdca_regmap_volatile(struct sdca_function_data *function, unsigned int reg) bool sdca_regmap_deferrable(struct sdca_function_data *function, unsigned int reg); int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg); +int sdca_regmap_count_constants(struct device *dev, struct sdca_function_data *function); +int sdca_regmap_populate_constants(struct device *dev, struct sdca_function_data *function, + struct reg_default *consts); + #endif // __SDCA_REGMAP_H__ diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c index ae6358f0fc26..dba4188620f9 100644 --- a/sound/soc/sdca/sdca_regmap.c +++ b/sound/soc/sdca/sdca_regmap.c @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -188,5 +190,83 @@ int sdca_regmap_mbq_size(struct sdca_function_data *function, unsigned int reg) } EXPORT_SYMBOL_NS(sdca_regmap_mbq_size, "SND_SOC_SDCA"); +/** + * sdca_regmap_count_constants - count the number of DisCo constant Controls + * @dev: Pointer to the device. + * @function: Pointer to the Function information, to be parsed. + * + * This function returns the number of DisCo constant Controls present + * in a function. Typically this information will be used to populate + * the regmap defaults array, allowing drivers to access the values of + * DisCo constants as any other physical register. + * + * Return: Returns number of DisCo constant controls, or a negative error + * code on failure. + */ +int sdca_regmap_count_constants(struct device *dev, + struct sdca_function_data *function) +{ + int nconsts = 0; + int i, j; + + for (i = 0; i < function->num_entities; i++) { + struct sdca_entity *entity = &function->entities[i]; + + for (j = 0; j < entity->num_controls; j++) { + if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC) + nconsts += hweight64(entity->controls[j].cn_list); + } + } + + return nconsts; +} +EXPORT_SYMBOL_NS(sdca_regmap_count_constants, "SND_SOC_SDCA"); + +/** + * sdca_regmap_populate_constants - fill an array with DisCo constant values + * @dev: Pointer to the device. + * @function: Pointer to the Function information, to be parsed. + * @consts: Pointer to the array which should be filled with the DisCo + * constant values. + * + * This function will populate a regmap struct reg_default array with + * the values of the DisCo constants for a given Function. This + * allows to access the values of DisCo constants the same as any + * other physical register. + * + * Return: Returns the number of constants populated on success, a negative + * error code on failure. + */ +int sdca_regmap_populate_constants(struct device *dev, + struct sdca_function_data *function, + struct reg_default *consts) +{ + int i, j, k; + + for (i = 0, k = 0; i < function->num_entities; i++) { + struct sdca_entity *entity = &function->entities[i]; + + for (j = 0; j < entity->num_controls; j++) { + struct sdca_control *control = &entity->controls[j]; + int cn; + + if (control->mode != SDCA_ACCESS_MODE_DC) + continue; + + for_each_set_bit(cn, (unsigned long *)&control->cn_list, + BITS_PER_TYPE(control->cn_list)) { + consts[k].reg = SDW_SDCA_CTL(function->desc->adr, + entity->id, + control->sel, cn); + consts[k].def = control->value; + k++; + } + } + } + + return k; +} +EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA"); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SDCA library"); From c143755d8cce31e770234732ff23134993b0550f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 17 Feb 2025 14:01:59 +0000 Subject: [PATCH 195/651] ASoC: SDCA: Add helper to write out defaults and fixed values The concept of an SDCA default value differs slightly from the regmap usage of the term. An SDCA default is a value that is parsed from DisCo and then written out to the hardware if no user value has superceded it. Add a helper function that will iterate through all the SDCA Controls and write out any default values. After these have been written out once they will exist in the cache and that will take care of any user values superceeding them. The code here also writes out any Controls with a fixed value as there is only one available value for these Controls there is no point in allowing the user to select them, simply treat them similarly to a default. Signed-off-by: Charles Keepax Reviewed-by: Pierre-Louis Bossart Link: https://patch.msgid.link/20250217140159.2288784-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_regmap.h | 4 +++ sound/soc/sdca/sdca_regmap.c | 49 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/sound/sdca_regmap.h b/include/sound/sdca_regmap.h index 850533e83f3b..b2e3c2ad2bb8 100644 --- a/include/sound/sdca_regmap.h +++ b/include/sound/sdca_regmap.h @@ -12,6 +12,7 @@ struct device; struct sdca_function_data; +struct regmap; struct reg_default; bool sdca_regmap_readable(struct sdca_function_data *function, unsigned int reg); @@ -24,4 +25,7 @@ int sdca_regmap_count_constants(struct device *dev, struct sdca_function_data *f int sdca_regmap_populate_constants(struct device *dev, struct sdca_function_data *function, struct reg_default *consts); +int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, + struct sdca_function_data *function); + #endif // __SDCA_REGMAP_H__ diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c index dba4188620f9..4b78188cfceb 100644 --- a/sound/soc/sdca/sdca_regmap.c +++ b/sound/soc/sdca/sdca_regmap.c @@ -268,5 +268,54 @@ int sdca_regmap_populate_constants(struct device *dev, } EXPORT_SYMBOL_NS(sdca_regmap_populate_constants, "SND_SOC_SDCA"); +/** + * sdca_regmap_write_defaults - write out DisCo defaults to device + * @dev: Pointer to the device. + * @regmap: Pointer to the Function register map. + * @function: Pointer to the Function information, to be parsed. + * + * This function will write out to the hardware all the DisCo default and + * fixed value controls. This will cause them to be populated into the cache, + * and subsequent handling can be done through a cache sync. + * + * Return: Returns zero on success, and a negative error code on failure. + */ +int sdca_regmap_write_defaults(struct device *dev, struct regmap *regmap, + struct sdca_function_data *function) +{ + int i, j; + int ret; + + for (i = 0; i < function->num_entities; i++) { + struct sdca_entity *entity = &function->entities[i]; + + for (j = 0; j < entity->num_controls; j++) { + struct sdca_control *control = &entity->controls[j]; + int cn; + + if (control->mode == SDCA_ACCESS_MODE_DC) + continue; + + if (!control->has_default && !control->has_fixed) + continue; + + for_each_set_bit(cn, (unsigned long *)&control->cn_list, + BITS_PER_TYPE(control->cn_list)) { + unsigned int reg; + + reg = SDW_SDCA_CTL(function->desc->adr, entity->id, + control->sel, cn); + + ret = regmap_write(regmap, reg, control->value); + if (ret) + return ret; + } + } + } + + return 0; +} +EXPORT_SYMBOL_NS(sdca_regmap_write_defaults, "SND_SOC_SDCA"); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SDCA library"); From 79ed408b2402e8113aa5a298f3bb9088ede58f6c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 27 Feb 2025 14:19:01 +0100 Subject: [PATCH 196/651] ASoC: mediatek: mt8188: avoid uninitialized variable use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'msk' variable has no initialization: sound/soc/mediatek/mt8188/mt8188-dai-dmic.c:311:4: error: variable 'msk' is uninitialized when used here [-Werror,-Wuninitialized] 311 | msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i); | ^~~ Set it to zero before the loop. Fixes: c1e42ec04197 ("ASoC: mediatek: mt8188: Add support for DMIC") Signed-off-by: Arnd Bergmann Reviewed-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250227131939.1040168-1-arnd@kernel.org Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-dai-dmic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c b/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c index 4cfbcb71d2d9..adcea7818be2 100644 --- a/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c +++ b/sound/soc/mediatek/mt8188/mt8188-dai-dmic.c @@ -307,6 +307,7 @@ static int mtk_dmic_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: /* request fifo soft rst */ + msk = 0; for (i = dmic_num; i >= DMIC0; i--) msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i); From 080564558eb1373c40e6c8447219376c1e089b9f Mon Sep 17 00:00:00 2001 From: Amin Dandache Date: Thu, 27 Feb 2025 14:30:27 +0100 Subject: [PATCH 197/651] ALSA: usb-audio: enable support for Presonus Studio 1824c within 1810c file This patch adds support for Presonus Studio 1824c, a usb interface that's UAC2 compliant and it is enabled by identifying the device ID 194f:010d and works with the code brought in by the 1810c change from Nick Kossifidis in 2020-02-15. More infos on the card: https://www.presonus.com/products/Studio-1824c Signed-off-by: Amin Dandache Link: https://patch.msgid.link/20250227133027.21148-1-git@amin85.de Signed-off-by: Takashi Iwai --- sound/usb/format.c | 4 ++++ sound/usb/mixer_quirks.c | 3 +++ sound/usb/quirks.c | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/usb/format.c b/sound/usb/format.c index 6049d957694c..9d32b21a5fbb 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -384,6 +384,10 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, if (chip->usb_id == USB_ID(0x194f, 0x010c) && !s1810c_valid_sample_rate(fp, rate)) goto skip_rate; + /* Filter out invalid rates on Presonus Studio 1824c */ + if (chip->usb_id == USB_ID(0x194f, 0x010d) && + !s1810c_valid_sample_rate(fp, rate)) + goto skip_rate; /* Filter out invalid rates on Focusrite devices */ if (USB_ID_VENDOR(chip->usb_id) == 0x1235 && diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ed6127b0389f..79c8c1540ee2 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -4119,6 +4119,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) case USB_ID(0x194f, 0x010c): /* Presonus Studio 1810c */ err = snd_sc1810_init_mixer(mixer); break; + case USB_ID(0x194f, 0x010d): /* Presonus Studio 1824c */ + err = snd_sc1810_init_mixer(mixer); + break; case USB_ID(0x2a39, 0x3fb0): /* RME Babyface Pro FS */ err = snd_bbfpro_controls_create(mixer); break; diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index a97efb7b131e..dea8bfaa7e91 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1599,7 +1599,9 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, /* presonus studio 1810c: skip altsets incompatible with device_setup */ if (chip->usb_id == USB_ID(0x194f, 0x010c)) return s1810c_skip_setting_quirk(chip, iface, altno); - + /* presonus studio 1824c: skip altsets incompatible with device_setup */ + if (chip->usb_id == USB_ID(0x194f, 0x010d)) + return s1810c_skip_setting_quirk(chip, iface, altno); return 0; } From 7fa25e87fecbba89fe9c87b2d902976b42efda32 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 28 Feb 2025 08:36:31 +0000 Subject: [PATCH 198/651] ALSA: es18xx: Fix spelling mistake "grap" -> "grab" There are spelling mistakes in dev_err messages. Fix them. Signed-off-by: Colin Ian King Link: https://patch.msgid.link/20250228083631.676877-1-colin.i.king@gmail.com Signed-off-by: Takashi Iwai --- sound/isa/es18xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 59c784a70ac1..e35c727a52fa 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -1735,27 +1735,27 @@ static int snd_es18xx_new_device(struct snd_card *card, chip->active = 0; if (!devm_request_region(card->dev, port, 16, "ES18xx")) { - dev_err(card->dev, "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1); + dev_err(card->dev, "unable to grab ports 0x%lx-0x%lx\n", port, port + 16 - 1); return -EBUSY; } if (devm_request_irq(card->dev, irq, snd_es18xx_interrupt, 0, "ES18xx", (void *) card)) { - dev_err(card->dev, "unable to grap IRQ %d\n", irq); + dev_err(card->dev, "unable to grab IRQ %d\n", irq); return -EBUSY; } chip->irq = irq; card->sync_irq = chip->irq; if (snd_devm_request_dma(card->dev, dma1, "ES18xx DMA 1")) { - dev_err(card->dev, "unable to grap DMA1 %d\n", dma1); + dev_err(card->dev, "unable to grab DMA1 %d\n", dma1); return -EBUSY; } chip->dma1 = dma1; if (dma2 != dma1 && snd_devm_request_dma(card->dev, dma2, "ES18xx DMA 2")) { - dev_err(card->dev, "unable to grap DMA2 %d\n", dma2); + dev_err(card->dev, "unable to grab DMA2 %d\n", dma2); return -EBUSY; } chip->dma2 = dma2; From 3abe3d342fc6a254e8b878d1e8c72c0ff980e68a Mon Sep 17 00:00:00 2001 From: Charles Han Date: Fri, 28 Feb 2025 11:34:27 +0800 Subject: [PATCH 199/651] ALSA: seq: seq_oss_event: fix inconsistent indenting warning in note_on_event() Fix below inconsistent indenting smatch warning. smatch warnings: sound/core/seq/oss/seq_oss_event.c:297 note_on_event() warn: inconsistent indenting Signed-off-by: Charles Han Link: https://patch.msgid.link/20250228033427.7056-1-hanchunchao@inspur.com Signed-off-by: Takashi Iwai --- sound/core/seq/oss/seq_oss_event.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sound/core/seq/oss/seq_oss_event.c b/sound/core/seq/oss/seq_oss_event.c index 7b7c925dd3aa..76fb81077eef 100644 --- a/sound/core/seq/oss/seq_oss_event.c +++ b/sound/core/seq/oss/seq_oss_event.c @@ -290,16 +290,14 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st if (note == 255 && info->ch[ch].note >= 0) { /* volume control */ int type; - //if (! vel) - /* set volume to zero -- note off */ - // type = SNDRV_SEQ_EVENT_NOTEOFF; - //else - if (info->ch[ch].vel) + + if (info->ch[ch].vel) /* sample already started -- volume change */ type = SNDRV_SEQ_EVENT_KEYPRESS; else /* sample not started -- start now */ type = SNDRV_SEQ_EVENT_NOTEON; + info->ch[ch].vel = vel; return set_note_event(dp, dev, type, ch, info->ch[ch].note, vel, ev); } else if (note >= 128) From 0bd862846e7f89910252cbef8718a757950f1683 Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Fri, 28 Feb 2025 11:58:07 +0530 Subject: [PATCH 200/651] ASoC: Intel: avs: use devm_kmemdup_array() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert to use devm_kmemdup_array() and while at it, use source size instead of destination. Signed-off-by: Raag Jadav Acked-by: Mark Brown Reviewed-by: Amadeusz SÅ‚awiÅ„ski Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20250228062812.150004-2-raag.jadav@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/da7219.c | 3 ++- sound/soc/intel/avs/boards/es8336.c | 3 ++- sound/soc/intel/avs/boards/nau8825.c | 3 ++- sound/soc/intel/avs/boards/rt274.c | 3 ++- sound/soc/intel/avs/boards/rt286.c | 3 ++- sound/soc/intel/avs/boards/rt298.c | 3 ++- sound/soc/intel/avs/boards/rt5663.c | 3 ++- sound/soc/intel/avs/boards/rt5682.c | 3 ++- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 76078a7005b0..9507a96f26ac 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -113,7 +113,8 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) } num_pins = ARRAY_SIZE(card_headset_pins); - pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins, + sizeof(card_headset_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/es8336.c b/sound/soc/intel/avs/boards/es8336.c index 426ce37105ae..6f3c4f6c9302 100644 --- a/sound/soc/intel/avs/boards/es8336.c +++ b/sound/soc/intel/avs/boards/es8336.c @@ -109,7 +109,8 @@ static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime) data = snd_soc_card_get_drvdata(card); num_pins = ARRAY_SIZE(card_headset_pins); - pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins, + sizeof(card_headset_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c index bf902540744c..6833eebd82d6 100644 --- a/sound/soc/intel/avs/boards/nau8825.c +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -88,7 +88,8 @@ static int avs_nau8825_codec_init(struct snd_soc_pcm_runtime *runtime) jack = snd_soc_card_get_drvdata(card); num_pins = ARRAY_SIZE(card_headset_pins); - pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins, + sizeof(card_headset_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index 4b6c02a40204..f5caafc21861 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -98,7 +98,8 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) jack = snd_soc_card_get_drvdata(card); num_pins = ARRAY_SIZE(card_headset_pins); - pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins, + sizeof(card_headset_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c index e40563ca99fd..1eb0399c0fae 100644 --- a/sound/soc/intel/avs/boards/rt286.c +++ b/sound/soc/intel/avs/boards/rt286.c @@ -59,7 +59,8 @@ static int avs_rt286_codec_init(struct snd_soc_pcm_runtime *runtime) jack = snd_soc_card_get_drvdata(card); num_pins = ARRAY_SIZE(card_headset_pins); - pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins, + sizeof(card_headset_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index 94fce07c83f9..85269a3be981 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -70,7 +70,8 @@ static int avs_rt298_codec_init(struct snd_soc_pcm_runtime *runtime) jack = snd_soc_card_get_drvdata(card); num_pins = ARRAY_SIZE(card_headset_pins); - pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins, + sizeof(card_headset_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/rt5663.c b/sound/soc/intel/avs/boards/rt5663.c index b456b9d14665..e3310b3268ba 100644 --- a/sound/soc/intel/avs/boards/rt5663.c +++ b/sound/soc/intel/avs/boards/rt5663.c @@ -65,7 +65,8 @@ static int avs_rt5663_codec_init(struct snd_soc_pcm_runtime *runtime) jack = &priv->jack; num_pins = ARRAY_SIZE(card_headset_pins); - pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_headset_pins, num_pins, + sizeof(card_headset_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c index 335960cfd7ba..339df0b944c1 100644 --- a/sound/soc/intel/avs/boards/rt5682.c +++ b/sound/soc/intel/avs/boards/rt5682.c @@ -102,7 +102,8 @@ static int avs_rt5682_codec_init(struct snd_soc_pcm_runtime *runtime) jack = snd_soc_card_get_drvdata(card); num_pins = ARRAY_SIZE(card_jack_pins); - pins = devm_kmemdup(card->dev, card_jack_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + pins = devm_kmemdup_array(card->dev, card_jack_pins, num_pins, + sizeof(card_jack_pins[0]), GFP_KERNEL); if (!pins) return -ENOMEM; From 3e706be02befae55b50b240d4360b5993f9879a8 Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Fri, 28 Feb 2025 11:58:08 +0530 Subject: [PATCH 201/651] ASoC: hdac_hdmi: use devm_kmemdup_array() Convert to use devm_kmemdup_array() and while at it, make the size robust against type changes. Signed-off-by: Raag Jadav Link: https://patch.msgid.link/20250228062812.150004-3-raag.jadav@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index e1a7f0b0c0f3..3bea5d09219a 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1017,8 +1017,7 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_device *hdev, return -ENOMEM; } - se->texts = devm_kmemdup(&hdev->dev, items, - (num_items * sizeof(char *)), GFP_KERNEL); + se->texts = devm_kmemdup_array(&hdev->dev, items, num_items, sizeof(items[0]), GFP_KERNEL); if (!se->texts) return -ENOMEM; From 69aaab0e65e9bd7601740c1e14cc6de86dafb621 Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Fri, 28 Feb 2025 11:58:09 +0530 Subject: [PATCH 202/651] ASoC: tlv320dac33: use devm_kmemdup_array() Convert to use devm_kmemdup_array() and while at it, make the size robust against type changes. Signed-off-by: Raag Jadav Link: https://patch.msgid.link/20250228062812.150004-4-raag.jadav@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320dac33.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index fa46f51d4341..423b9264a205 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1477,10 +1477,8 @@ static int dac33_i2c_probe(struct i2c_client *client) if (dac33 == NULL) return -ENOMEM; - dac33->reg_cache = devm_kmemdup(&client->dev, - dac33_reg, - ARRAY_SIZE(dac33_reg) * sizeof(u8), - GFP_KERNEL); + dac33->reg_cache = devm_kmemdup_array(&client->dev, dac33_reg, ARRAY_SIZE(dac33_reg), + sizeof(dac33_reg[0]), GFP_KERNEL); if (!dac33->reg_cache) return -ENOMEM; From d9d71a6e2d19a2f3ccebea0092b8ddc1e935886f Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Fri, 28 Feb 2025 11:58:10 +0530 Subject: [PATCH 203/651] ASoC: uda1380: use devm_kmemdup_array() Convert to use devm_kmemdup_array() and while at it, make the size robust against type changes. Signed-off-by: Raag Jadav Link: https://patch.msgid.link/20250228062812.150004-5-raag.jadav@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/uda1380.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 4f8fdd574585..c179d865b938 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -766,10 +766,8 @@ static int uda1380_i2c_probe(struct i2c_client *i2c) return ret; } - uda1380->reg_cache = devm_kmemdup(&i2c->dev, - uda1380_reg, - ARRAY_SIZE(uda1380_reg) * sizeof(u16), - GFP_KERNEL); + uda1380->reg_cache = devm_kmemdup_array(&i2c->dev, uda1380_reg, ARRAY_SIZE(uda1380_reg), + sizeof(uda1380_reg[0]), GFP_KERNEL); if (!uda1380->reg_cache) return -ENOMEM; From b26205e172ca035e327e49edb0c2611e5d2ede8d Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Fri, 28 Feb 2025 11:58:11 +0530 Subject: [PATCH 204/651] ASoC: meson: axg-tdm-interface: use devm_kmemdup_array() Convert to use devm_kmemdup_array() which is more robust. Signed-off-by: Raag Jadav Link: https://patch.msgid.link/20250228062812.150004-6-raag.jadav@intel.com Signed-off-by: Mark Brown --- sound/soc/meson/axg-tdm-interface.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c index 09103eef2a97..421b5d719fb3 100644 --- a/sound/soc/meson/axg-tdm-interface.c +++ b/sound/soc/meson/axg-tdm-interface.c @@ -529,7 +529,6 @@ static int axg_tdm_iface_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct snd_soc_dai_driver *dai_drv; struct axg_tdm_iface *iface; - int i; iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL); if (!iface) @@ -541,15 +540,11 @@ static int axg_tdm_iface_probe(struct platform_device *pdev) * We'll change the number of channel provided by DAI stream, so dpcm * channel merge can be done properly */ - dai_drv = devm_kcalloc(dev, ARRAY_SIZE(axg_tdm_iface_dai_drv), - sizeof(*dai_drv), GFP_KERNEL); + dai_drv = devm_kmemdup_array(dev, axg_tdm_iface_dai_drv, ARRAY_SIZE(axg_tdm_iface_dai_drv), + sizeof(axg_tdm_iface_dai_drv[0]), GFP_KERNEL); if (!dai_drv) return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(axg_tdm_iface_dai_drv); i++) - memcpy(&dai_drv[i], &axg_tdm_iface_dai_drv[i], - sizeof(*dai_drv)); - /* Bit clock provided on the pad */ iface->sclk = devm_clk_get(dev, "sclk"); if (IS_ERR(iface->sclk)) From c173b5ee81a25e8aafb21ccdb7ab457da7783bf1 Mon Sep 17 00:00:00 2001 From: Raag Jadav Date: Fri, 28 Feb 2025 11:58:12 +0530 Subject: [PATCH 205/651] ASoC: uniphier: use devm_kmemdup_array() Convert to use devm_kmemdup_array() and while at it, make the size robust against type changes. Signed-off-by: Raag Jadav Link: https://patch.msgid.link/20250228062812.150004-7-raag.jadav@intel.com Signed-off-by: Mark Brown --- sound/soc/uniphier/aio-cpu.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c index 470f129166a4..3224c11a527f 100644 --- a/sound/soc/uniphier/aio-cpu.c +++ b/sound/soc/uniphier/aio-cpu.c @@ -762,14 +762,10 @@ int uniphier_aio_probe(struct platform_device *pdev) return -ENOMEM; chip->num_plls = chip->chip_spec->num_plls; - chip->plls = devm_kcalloc(dev, - chip->num_plls, - sizeof(struct uniphier_aio_pll), - GFP_KERNEL); + chip->plls = devm_kmemdup_array(dev, chip->chip_spec->plls, chip->num_plls, + sizeof(*chip->chip_spec->plls), GFP_KERNEL); if (!chip->plls) return -ENOMEM; - memcpy(chip->plls, chip->chip_spec->plls, - sizeof(struct uniphier_aio_pll) * chip->num_plls); for (i = 0; i < chip->num_aios; i++) { struct uniphier_aio *aio = &chip->aios[i]; From b686559772d1baa28e2ad346d5a9932863d9523c Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:51 +0100 Subject: [PATCH 206/651] ASoC: codecs: rt1011: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1011.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c index a0e75b03e9dc..fb76f9e020ff 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -2192,15 +2192,15 @@ static const struct regmap_config rt1011_regmap = { #if defined(CONFIG_OF) static const struct of_device_id rt1011_of_match[] = { { .compatible = "realtek,rt1011", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt1011_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt1011_acpi_match[] = { - {"10EC1011", 0,}, - {}, + { "10EC1011" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt1011_acpi_match); #endif From a859d2383f66002a442218bf5083faaa674bc4e4 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:52 +0100 Subject: [PATCH 207/651] ASoC: codecs: rt1015: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 0f806dde9c39..ea8037117d42 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -1105,15 +1105,15 @@ MODULE_DEVICE_TABLE(i2c, rt1015_i2c_id); #if defined(CONFIG_OF) static const struct of_device_id rt1015_of_match[] = { { .compatible = "realtek,rt1015", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt1015_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt1015_acpi_match[] = { - {"10EC1015", 0,}, - {}, + { "10EC1015" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt1015_acpi_match); #endif From e7795c17b82684afb9390b8788f781c07be1a368 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:53 +0100 Subject: [PATCH 208/651] ASoC: codecs: rt1016: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1016.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt1016.c b/sound/soc/codecs/rt1016.c index fed4da23cba2..132c102983bf 100644 --- a/sound/soc/codecs/rt1016.c +++ b/sound/soc/codecs/rt1016.c @@ -616,15 +616,15 @@ MODULE_DEVICE_TABLE(i2c, rt1016_i2c_id); #if defined(CONFIG_OF) static const struct of_device_id rt1016_of_match[] = { { .compatible = "realtek,rt1016", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt1016_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt1016_acpi_match[] = { - {"10EC1016", 0,}, - {}, + { "10EC1016" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt1016_acpi_match); #endif From 689e4d5fd8a76c676f04bc8916d78ca5db3130db Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:54 +0100 Subject: [PATCH 209/651] ASoC: codecs: rt1019: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1019.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt1019.c b/sound/soc/codecs/rt1019.c index d989d06a2614..86539c6f6cc1 100644 --- a/sound/soc/codecs/rt1019.c +++ b/sound/soc/codecs/rt1019.c @@ -547,14 +547,14 @@ MODULE_DEVICE_TABLE(i2c, rt1019_i2c_id); static const struct of_device_id rt1019_of_match[] __maybe_unused = { { .compatible = "realtek,rt1019", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt1019_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id rt1019_acpi_match[] = { - { "10EC1019", 0}, - { }, + { "10EC1019" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt1019_acpi_match); #endif From 0440f938aacf54a3e7dc67cd898f76bbd371da49 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:55 +0100 Subject: [PATCH 210/651] ASoC: codecs: rt1305: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1305.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt1305.c b/sound/soc/codecs/rt1305.c index c2b55be8d165..59ddc4b21803 100644 --- a/sound/soc/codecs/rt1305.c +++ b/sound/soc/codecs/rt1305.c @@ -966,16 +966,16 @@ static const struct regmap_config rt1305_regmap = { static const struct of_device_id rt1305_of_match[] = { { .compatible = "realtek,rt1305", }, { .compatible = "realtek,rt1306", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt1305_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt1305_acpi_match[] = { - {"10EC1305", 0,}, - {"10EC1306", 0,}, - {}, + { "10EC1305" }, + { "10EC1306" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt1305_acpi_match); #endif From 30e03871146129acb75adac48405c203f5bdb3c2 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:56 +0100 Subject: [PATCH 211/651] ASoC: codecs: rt1308: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1308.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt1308.c b/sound/soc/codecs/rt1308.c index b366338cea71..90d14e2d62f1 100644 --- a/sound/soc/codecs/rt1308.c +++ b/sound/soc/codecs/rt1308.c @@ -781,15 +781,15 @@ static const struct regmap_config rt1308_regmap = { #ifdef CONFIG_OF static const struct of_device_id rt1308_of_match[] = { { .compatible = "realtek,rt1308", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, rt1308_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt1308_acpi_match[] = { - { "10EC1308", 0, }, - { }, + { "10EC1308" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt1308_acpi_match); #endif From acac29fa62a8b738569a99da2f6458bc21aa55ae Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:57 +0100 Subject: [PATCH 212/651] ASoC: codecs: rt1318: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1318.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt1318.c b/sound/soc/codecs/rt1318.c index e12b1e96a53a..ae01b2ce630b 100644 --- a/sound/soc/codecs/rt1318.c +++ b/sound/soc/codecs/rt1318.c @@ -1147,14 +1147,14 @@ MODULE_DEVICE_TABLE(i2c, rt1318_i2c_id); static const struct of_device_id rt1318_of_match[] = { { .compatible = "realtek,rt1318", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt1318_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id rt1318_acpi_match[] = { - { "10EC1318", 0}, - { }, + { "10EC1318" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt1318_acpi_match); #endif From 5a84cbb03094fd903ed79ca6c06e558821a69be4 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:58 +0100 Subject: [PATCH 213/651] ASoC: codecs: rt274: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt274.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index bd61a257d7b5..b27e9d06e32d 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -1091,7 +1091,7 @@ static const struct regmap_config rt274_regmap = { #ifdef CONFIG_OF static const struct of_device_id rt274_of_match[] = { {.compatible = "realtek,rt274"}, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt274_of_match); #endif @@ -1104,9 +1104,9 @@ MODULE_DEVICE_TABLE(i2c, rt274_i2c_id); #ifdef CONFIG_ACPI static const struct acpi_device_id rt274_acpi_match[] = { - { "10EC0274", 0 }, - { "INT34C2", 0 }, - {}, + { "10EC0274" }, + { "INT34C2" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt274_acpi_match); #endif From 1c418cf146380031b13b6fde02f944830e5b9155 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:25:59 +0100 Subject: [PATCH 214/651] ASoC: codecs: rt5514: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5514.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 9cb74962161a..a7f984b5d80f 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -1206,15 +1206,15 @@ MODULE_DEVICE_TABLE(i2c, rt5514_i2c_id); #if defined(CONFIG_OF) static const struct of_device_id rt5514_of_match[] = { { .compatible = "realtek,rt5514", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5514_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5514_acpi_match[] = { - { "10EC5514", 0}, - {}, + { "10EC5514" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5514_acpi_match); #endif From dfc6b8ccb1bb8d591cd26571e554208fc4af7d0c Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:00 +0100 Subject: [PATCH 215/651] ASoC: codecs: rt5640: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. While at it, sort the IDs alphabetically. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 855139348edb..391df62491fa 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2963,19 +2963,19 @@ MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); static const struct of_device_id rt5640_of_match[] = { { .compatible = "realtek,rt5639", }, { .compatible = "realtek,rt5640", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5640_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5640_acpi_match[] = { - { "INT33CA", 0 }, - { "10EC3276", 0 }, - { "10EC5640", 0 }, - { "10EC5642", 0 }, - { "INTCCFFD", 0 }, - { }, + { "10EC3276" }, + { "10EC5640" }, + { "10EC5642" }, + { "INT33CA" }, + { "INTCCFFD" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match); #endif From d3a37a664ebe57471bd7ab2486dd3072a9c07378 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:01 +0100 Subject: [PATCH 216/651] ASoC: codecs: rt5645: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. While at it, sort the IDs alphabetically. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-12-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 51187b1e0ed2..56cf410926e3 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3660,12 +3660,12 @@ MODULE_DEVICE_TABLE(of, rt5645_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id rt5645_acpi_match[] = { - { "10EC5645", 0 }, - { "10EC5648", 0 }, - { "10EC5650", 0 }, - { "10EC5640", 0 }, - { "10EC3270", 0 }, - {}, + { "10EC3270" }, + { "10EC5640" }, + { "10EC5645" }, + { "10EC5648" }, + { "10EC5650" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); #endif From 85188e3bd7cb4141181f24a59f9057c38ffa37bf Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:02 +0100 Subject: [PATCH 217/651] ASoC: codecs: rt5651: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. While at it, sort the IDs alphabetically. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-13-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5651.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 00421a1f54bf..2c1fad3ee690 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -2184,16 +2184,16 @@ static const struct regmap_config rt5651_regmap = { #if defined(CONFIG_OF) static const struct of_device_id rt5651_of_match[] = { { .compatible = "realtek,rt5651", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5651_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5651_acpi_match[] = { - { "10EC5651", 0 }, - { "10EC5640", 0 }, - { }, + { "10EC5640" }, + { "10EC5651" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5651_acpi_match); #endif From 24a4302478118ff1caf39fb48809c0127f608664 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:03 +0100 Subject: [PATCH 218/651] ASoC: codecs: rt5659: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. While at it, sort the IDs alphabetically. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-14-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5659.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index a2652fa6e1d7..e5e8ccc604eb 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -4315,16 +4315,16 @@ static void rt5659_i2c_shutdown(struct i2c_client *client) static const struct of_device_id rt5659_of_match[] = { { .compatible = "realtek,rt5658", }, { .compatible = "realtek,rt5659", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, rt5659_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5659_acpi_match[] = { - { "10EC5658", 0, }, - { "10EC5659", 0, }, - { }, + { "10EC5658" }, + { "10EC5659" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match); #endif From 4d34ea6709894243d55ae6a6b63834851f9c5d6f Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:04 +0100 Subject: [PATCH 219/651] ASoC: codecs: rt5660: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. While at it, sort the IDs alphabetically. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-15-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5660.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index 3ac41d2c279b..7e8ac735b82c 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1232,16 +1232,16 @@ MODULE_DEVICE_TABLE(i2c, rt5660_i2c_id); #ifdef CONFIG_OF static const struct of_device_id rt5660_of_match[] = { { .compatible = "realtek,rt5660", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5660_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5660_acpi_match[] = { - { "10EC5660", 0 }, - { "10EC3277", 0 }, - { }, + { "10EC3277" }, + { "10EC5660" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match); #endif From e9d9a43e3f00b9313013b78d915a1f97dd215bf5 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:05 +0100 Subject: [PATCH 220/651] ASoC: codecs: rt5663: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-16-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 9d32debd3689..874c5ea3efb5 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -3315,15 +3315,15 @@ MODULE_DEVICE_TABLE(i2c, rt5663_i2c_id); #if defined(CONFIG_OF) static const struct of_device_id rt5663_of_match[] = { { .compatible = "realtek,rt5663", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5663_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5663_acpi_match[] = { - { "10EC5663", 0}, - {}, + { "10EC5663" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5663_acpi_match); #endif From b89d9d26fb6cbc9f6e0aae72a2a76b5d8e5f1023 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:06 +0100 Subject: [PATCH 221/651] ASoC: codecs: rt5665: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-17-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5665.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 47df14ba5278..be5ddb4be6df 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -4949,16 +4949,16 @@ static void rt5665_i2c_shutdown(struct i2c_client *client) static const struct of_device_id rt5665_of_match[] = { {.compatible = "realtek,rt5665"}, {.compatible = "realtek,rt5666"}, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5665_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5665_acpi_match[] = { - {"10EC5665", 0,}, - {"10EC5666", 0,}, - {}, + { "10EC5665" }, + { "10EC5666" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5665_acpi_match); #endif From a06ef7754b8e6f45d78c0015c3edb2117945adfb Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:07 +0100 Subject: [PATCH 222/651] ASoC: codecs: rt5668: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-18-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5668.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c index 494ca3ce9b96..51be7b1f900b 100644 --- a/sound/soc/codecs/rt5668.c +++ b/sound/soc/codecs/rt5668.c @@ -2598,15 +2598,15 @@ static void rt5668_i2c_shutdown(struct i2c_client *client) #ifdef CONFIG_OF static const struct of_device_id rt5668_of_match[] = { {.compatible = "realtek,rt5668b"}, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5668_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5668_acpi_match[] = { - {"10EC5668", 0,}, - {}, + { "10EC5668" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5668_acpi_match); #endif From 9aa85f433bb1f51b599278b29b3d6224ca5147cf Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:08 +0100 Subject: [PATCH 223/651] ASoC: codecs: rt5670: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. While at it, sort the IDs alphabetically. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-19-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 30bf96c35b58..c18fc86a2513 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2880,10 +2880,10 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); #ifdef CONFIG_ACPI static const struct acpi_device_id rt5670_acpi_match[] = { - { "10EC5670", 0}, - { "10EC5672", 0}, - { "10EC5640", 0}, /* quirk */ - { }, + { "10EC5640" }, /* quirk */ + { "10EC5670" }, + { "10EC5672" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); #endif From 6de7c4def7a6bf967d6603f7e1abda5231ccc312 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:09 +0100 Subject: [PATCH 224/651] ASoC: codecs: rt5682: Fix definition of device_id tables There shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-20-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt5682-i2c.c b/sound/soc/codecs/rt5682-i2c.c index a8820435d1e0..bba987308e15 100644 --- a/sound/soc/codecs/rt5682-i2c.c +++ b/sound/soc/codecs/rt5682-i2c.c @@ -313,13 +313,13 @@ static void rt5682_i2c_remove(struct i2c_client *client) static const struct of_device_id rt5682_of_match[] = { {.compatible = "realtek,rt5682i"}, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5682_of_match); static const struct acpi_device_id rt5682_acpi_match[] = { - {"10EC5682", 0,}, - {}, + { "10EC5682" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5682_acpi_match); From 7f15da9a55d3ba9f8c3af545246a4588102a38db Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:10 +0100 Subject: [PATCH 225/651] ASoC: codecs: rt286: Update definition of device_id tables Follow PCI-based format (10ECxxxx) for ACPI IDs by adding relevant entries to the existing table. While at it, there shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-21-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index d0f533120c33..5ad1b9311d11 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1083,8 +1083,9 @@ MODULE_DEVICE_TABLE(i2c, rt286_i2c_id); #ifdef CONFIG_ACPI static const struct acpi_device_id rt286_acpi_match[] = { - { "INT343A", 0 }, - {}, + { "10EC0286" }, + { "INT343A" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); #endif From ed4bef1d52ce0d6c96a86b6a470d6777034c564c Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:11 +0100 Subject: [PATCH 226/651] ASoC: codecs: rt298: Update definition of device_id tables Follow PCI-based format (10ECxxxx) for ACPI IDs by adding relevant entries to the existing table. While at it, there shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-22-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt298.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index 13aef6c5e91c..dd2d27515e7e 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1144,8 +1144,9 @@ MODULE_DEVICE_TABLE(i2c, rt298_i2c_id); #ifdef CONFIG_ACPI static const struct acpi_device_id rt298_acpi_match[] = { - { "INT343A", 0 }, - {}, + { "10EC0298" }, + { "INT343A" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt298_acpi_match); #endif From 739db0529c2a3ac5a0dc3e5a76a46ce80735dcfa Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Feb 2025 12:26:12 +0100 Subject: [PATCH 227/651] ASoC: codecs: rt5677: Update definition of device_id tables Follow PCI-based format (10ECxxxx) for ACPI IDs by adding relevant entries to the existing table. While at it, there shall be no comma after the terminator entry and initializing fields with 0 for statically defined structs is redundant. Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250226112612.166989-23-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677-spi.c | 3 ++- sound/soc/codecs/rt5677.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c index d91a2184f67c..abe0a5a95770 100644 --- a/sound/soc/codecs/rt5677-spi.c +++ b/sound/soc/codecs/rt5677-spi.c @@ -617,7 +617,8 @@ static int rt5677_spi_probe(struct spi_device *spi) #ifdef CONFIG_ACPI static const struct acpi_device_id rt5677_spi_acpi_id[] = { - { "RT5677AA", 0 }, + { "10EC5677" }, + { "RT5677AA" }, { } }; MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id); diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 0e70a3ab42b5..d1e0b93d6ee6 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5201,6 +5201,7 @@ static const struct of_device_id rt5677_of_match[] = { MODULE_DEVICE_TABLE(of, rt5677_of_match); static const struct acpi_device_id rt5677_acpi_match[] = { + { "10EC5677", RT5677 }, { "RT5677CE", RT5677 }, { } }; From 8450fa6b16e2f46f5b880e0b80d55ab9fc4524ca Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:29:45 +0000 Subject: [PATCH 228/651] ASoC: Documentation: Codec to Codec: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczlh4s7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- Documentation/sound/soc/codec-to-codec.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/sound/soc/codec-to-codec.rst b/Documentation/sound/soc/codec-to-codec.rst index 0418521b6e03..973c147d9d82 100644 --- a/Documentation/sound/soc/codec-to-codec.rst +++ b/Documentation/sound/soc/codec-to-codec.rst @@ -68,7 +68,7 @@ file: .codec_dai_name = "codec-2-dai_name", .platform_name = "samsung-i2s.0", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, .c2c_params = &dsp_codec_params, .num_c2c_params = 1, @@ -80,7 +80,7 @@ file: .codec_name = "codec-3, .codec_dai_name = "codec-3-dai_name", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, .c2c_params = &dsp_codec_params, .num_c2c_params = 1, From 231bf041d425a086ec08231c98cf02b6fb16b169 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:29:51 +0000 Subject: [PATCH 229/651] ASoC: ti: n810: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyf5h4s0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/n810.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/n810.c b/sound/soc/ti/n810.c index 50a8ec97cf20..345c98765380 100644 --- a/sound/soc/ti/n810.c +++ b/sound/soc/ti/n810.c @@ -258,7 +258,7 @@ static struct snd_soc_dai_link n810_dai = { .name = "TLV320AIC33", .stream_name = "AIC33", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ops = &n810_ops, SND_SOC_DAILINK_REG(aic33), }; From dfdc0debf1b82354e301843f8cbd16eaf05a01c6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:29:55 +0000 Subject: [PATCH 230/651] ASoC: ti: osk5912: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjuph4rw.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/osk5912.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/osk5912.c b/sound/soc/ti/osk5912.c index 98714c593496..fa5ef7814dab 100644 --- a/sound/soc/ti/osk5912.c +++ b/sound/soc/ti/osk5912.c @@ -86,7 +86,7 @@ static struct snd_soc_dai_link osk_dai = { .name = "TLV320AIC23", .stream_name = "AIC23", .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ops = &osk_ops, SND_SOC_DAILINK_REG(aic23), }; From 48d5e50e4fe78bf9cc5b4eca72798d4507da62fb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:00 +0000 Subject: [PATCH 231/651] ASoC: ti: ams-delta: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5a9h4rr.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/ams-delta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c index 94645f275495..8a4423646aea 100644 --- a/sound/soc/ti/ams-delta.c +++ b/sound/soc/ti/ams-delta.c @@ -532,7 +532,7 @@ static struct snd_soc_dai_link ams_delta_dai_link = { .init = ams_delta_cx20442_init, .ops = &ams_delta_ops, .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(cx20442), }; From 5cfb2f62242b41e2b60cadf21b28ee43cf615ec2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:09 +0000 Subject: [PATCH 232/651] ASoC: ti: j721e-evm: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qpth4ri.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/j721e-evm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c index d9d1e021f5b2..c0fa72e626ff 100644 --- a/sound/soc/ti/j721e-evm.c +++ b/sound/soc/ti/j721e-evm.c @@ -37,7 +37,7 @@ enum j721e_audio_domain_id { #define J721E_DAI_FMT (SND_SOC_DAIFMT_RIGHT_J | \ SND_SOC_DAIFMT_NB_NF | \ - SND_SOC_DAIFMT_CBS_CFS) + SND_SOC_DAIFMT_CBC_CFC) enum j721e_board_type { J721E_BOARD_CPB = 1, From bc17eaf1b925595fb9f945ced5d70fe82ce11e78 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:13 +0000 Subject: [PATCH 233/651] ASoC: ti: davinci-evm: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c5dh4re.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/davinci-evm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ti/davinci-evm.c b/sound/soc/ti/davinci-evm.c index 1bf333d2740d..2a2f5bc95576 100644 --- a/sound/soc/ti/davinci-evm.c +++ b/sound/soc/ti/davinci-evm.c @@ -152,7 +152,7 @@ static struct snd_soc_dai_link evm_dai_tlv320aic3x = { .stream_name = "AIC3X", .ops = &evm_ops, .init = evm_aic3x_init, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBP_CFP | SND_SOC_DAIFMT_IB_NF, SND_SOC_DAILINK_REG(evm), }; From 9fde82ea39a7f52c23de366c8592d4805634f45c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:17 +0000 Subject: [PATCH 234/651] ASoC: ti: omap-twl4030: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/875xkxh4ra.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/omap-twl4030.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/ti/omap-twl4030.c b/sound/soc/ti/omap-twl4030.c index a402d66e4f4d..3548b58002c4 100644 --- a/sound/soc/ti/omap-twl4030.c +++ b/sound/soc/ti/omap-twl4030.c @@ -42,12 +42,12 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream, case 2: /* Stereo I2S mode */ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM; + SND_SOC_DAIFMT_CBP_CFP; break; case 4: /* Four channel TDM mode */ fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBM_CFM; + SND_SOC_DAIFMT_CBP_CFP; break; default: return -EINVAL; @@ -218,7 +218,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { .name = "TWL4030 Voice", .stream_name = "TWL4030 Voice", .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(voice), }, }; From 941abe67e176a3ddbe59cd4323b13f69515f6628 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:22 +0000 Subject: [PATCH 235/651] ASoC: ti: omap3pandora: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/874j0hh4r5.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ti/omap3pandora.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/ti/omap3pandora.c b/sound/soc/ti/omap3pandora.c index be69476e59d6..808fb6765c05 100644 --- a/sound/soc/ti/omap3pandora.c +++ b/sound/soc/ti/omap3pandora.c @@ -189,7 +189,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { .name = "PCM1773", .stream_name = "HiFi Out", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &omap3pandora_ops, .init = omap3pandora_out_init, SND_SOC_DAILINK_REG(out), @@ -197,7 +197,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { .name = "TWL4030", .stream_name = "Line/Mic In", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &omap3pandora_ops, .init = omap3pandora_in_init, SND_SOC_DAILINK_REG(in), From df95f0157ba1ea7b73b3f1db4abfdb4b05e0bfd9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:27 +0000 Subject: [PATCH 236/651] ASoC: amd: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/8734g1h4r0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-mach-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index f7602c1769bf..a0dab85088ec 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -919,7 +919,7 @@ static int acp_max98388_hw_params(struct snd_pcm_substream *substream, int ret; ret = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF); if (ret < 0) return ret; From 2920be2fabcb8010fefdf101d84fe0867730d925 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:35 +0000 Subject: [PATCH 237/651] ASoC: fsl: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/871pvlh4qs.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl-asoc-card.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 2bad9cb1daaf..ab583b432c60 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -759,7 +759,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP; } else if (of_device_is_compatible(np, "fsl,imx-audio-tlv320aic31xx")) { codec_dai_name[0] = "tlv320dac31xx-hifi"; - priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; + priv->dai_fmt |= SND_SOC_DAIFMT_CBC_CFC; priv->dai_link[1].playback_only = 1; priv->dai_link[2].playback_only = 1; priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT; @@ -818,7 +818,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->codec_priv[0].mclk_id = NAU8822_CLK_MCLK; priv->codec_priv[0].fll_id = NAU8822_CLK_PLL; priv->codec_priv[0].pll_id = NAU8822_CLK_PLL; - priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; + priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP; if (codec_dev[0]) priv->codec_priv[0].mclk = devm_clk_get(codec_dev[0], NULL); } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8904")) { From 74f6e045d879414ae4c352dc7f4e8d438ea9d55d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:40 +0000 Subject: [PATCH 238/651] ASoC: mxs: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87zfi9fq68.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-sgtl5000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index a41a13ae38a5..245f17411638 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -59,7 +59,7 @@ static const struct snd_soc_ops mxs_sgtl5000_hifi_ops = { }; #define MXS_SGTL5000_DAI_FMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ - SND_SOC_DAIFMT_CBS_CFS) + SND_SOC_DAIFMT_CBC_CFC) SND_SOC_DAILINK_DEFS(hifi_tx, From e42ec97657fa5ee40fd2358c973d273edd7999bd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:44 +0000 Subject: [PATCH 239/651] ASoC: pxa: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87y0xtfq64.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/pxa/spitz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 8caa1aa99bdc..6ca0a6bcd34c 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -260,7 +260,7 @@ static struct snd_soc_dai_link spitz_dai = { .name = "wm8750", .stream_name = "WM8750", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &spitz_ops, SND_SOC_DAILINK_REG(wm8750), }; From a1cadae42c9bc52cff24b22b0c4986be8d82ae16 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:48 +0000 Subject: [PATCH 240/651] ASoC: qcom: sc7180: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmddfq5z.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/qcom/sc7180.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/sc7180.c b/sound/soc/qcom/sc7180.c index d95710b1ea4e..84b6ac5d2a20 100644 --- a/sound/soc/qcom/sc7180.c +++ b/sound/soc/qcom/sc7180.c @@ -397,7 +397,7 @@ static int sc7180_adau7002_snd_startup(struct snd_pcm_substream *substream) switch (cpu_dai->id) { case MI2S_PRIMARY: snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_CBS_CFS | + SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S); runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; From f8ca280bf5c2a3fb08890bdd212a3f3c00589f87 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:53 +0000 Subject: [PATCH 241/651] ASoC: qcom: sc7280: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7sxfq5v.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/qcom/sc7280.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c index 230af8d7b205..af412bd0c89f 100644 --- a/sound/soc/qcom/sc7280.c +++ b/sound/soc/qcom/sc7280.c @@ -342,8 +342,8 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) static int sc7280_snd_startup(struct snd_pcm_substream *substream) { - unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; - unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS; + unsigned int fmt = SND_SOC_DAIFMT_CBC_CFC; + unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBC_CFC; struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); From 3c2e63a3a0efa8c52f9fd67f58a71af48957ca7a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:30:56 +0000 Subject: [PATCH 242/651] ASoC: codec: cs4234: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8hfq5r.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs4234.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index 69287ba7e955..df160db5bbb5 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -307,9 +307,9 @@ static int cs4234_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int format } switch (format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: if (cs4234->format == SND_SOC_DAIFMT_DSP_A) { dev_err(component->dev, "Unsupported DSP A format in master mode\n"); return -EINVAL; From c974655b0c7f82a760bd22d9ef9db281e765a9a2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:00 +0000 Subject: [PATCH 243/651] ASoC: codec: cs4265: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87seo1fq5n.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs4265.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 78ffb7fa7fc5..3f759c13d6d1 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -344,12 +344,12 @@ static int cs4265_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u8 iface = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: snd_soc_component_update_bits(component, CS4265_ADC_CTL, CS4265_ADC_MASTER, CS4265_ADC_MASTER); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: snd_soc_component_update_bits(component, CS4265_ADC_CTL, CS4265_ADC_MASTER, 0); From 46dbe25747fca3d82e98dca488fa9be6b809d522 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:04 +0000 Subject: [PATCH 244/651] ASoC: codec: cs4270: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87r03lfq5j.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs4270.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 67e92bfecb56..9f9dc8b017a3 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -287,10 +287,10 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: cs4270->slave_mode = 1; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: cs4270->slave_mode = 0; break; default: From e9ab4b38205a34fffe537b4db721458b5d07066e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:09 +0000 Subject: [PATCH 245/651] ASoC: codec: cs4271: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87plj5fq5e.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs4271.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index e864188ae5eb..6a3cca3d26c7 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -209,10 +209,10 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai, int ret; switch (format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: cs4271->master = false; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: cs4271->master = true; val |= CS4271_MODE1_MASTER; break; From 0d41068ca151a6368ab4591c13e9a7a9fb92a56f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:13 +0000 Subject: [PATCH 246/651] ASoC: codec: cs4341: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6ypfq5a.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs4341.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs4341.c b/sound/soc/codecs/cs4341.c index d87aae31c516..b726e22ef57d 100644 --- a/sound/soc/codecs/cs4341.c +++ b/sound/soc/codecs/cs4341.c @@ -49,7 +49,7 @@ static int cs4341_set_fmt(struct snd_soc_dai *dai, unsigned int format) struct cs4341_priv *cs4341 = snd_soc_component_get_drvdata(component); switch (format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 0c57e55719681412e87db7bb81b8255b43d6162f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:17 +0000 Subject: [PATCH 247/651] ASoC: codec: cs530x: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mse9fq56.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs530x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs530x.c b/sound/soc/codecs/cs530x.c index 252e66c8449e..b9eff240b929 100644 --- a/sound/soc/codecs/cs530x.c +++ b/sound/soc/codecs/cs530x.c @@ -557,9 +557,9 @@ static int cs530x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int asp_fmt, asp_cfg = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: asp_cfg = CS530X_ASP_PRIMARY; break; default: From b26c604a0dcef62e7c61bd1d560c63547c9bbfe8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:25 +0000 Subject: [PATCH 248/651] ASoC: codec: cs35l32: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldttfq4y.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 96555263e10b..6d78fa953c89 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -153,12 +153,12 @@ static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) struct snd_soc_component *component = codec_dai->component; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: snd_soc_component_update_bits(component, CS35L32_ADSP_CTL, CS35L32_ADSP_MASTER_MASK, CS35L32_ADSP_MASTER_MASK); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: snd_soc_component_update_bits(component, CS35L32_ADSP_CTL, CS35L32_ADSP_MASTER_MASK, 0); break; From ea38f63c4afdd5531fbd8f0f881594a94c4bd413 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:29 +0000 Subject: [PATCH 249/651] ASoC: codec: cs35l33: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jz9dfq4u.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l33.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index b03aab147530..02a420659a33 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -438,12 +438,12 @@ static int cs35l33_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) struct cs35l33_private *priv = snd_soc_component_get_drvdata(component); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL, CS35L33_MS_MASK, CS35L33_MS_MASK); dev_dbg(component->dev, "Audio port in master mode\n"); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL, CS35L33_MS_MASK, 0); dev_dbg(component->dev, "Audio port in slave mode\n"); From d21e3b442ff6401511831ae1b8be11d530f063de Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:33 +0000 Subject: [PATCH 250/651] ASoC: codec: cs35l34: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikoxfq4r.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l34.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 287b27476a10..6d098bfd38f6 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -523,11 +523,11 @@ static int cs35l34_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) struct cs35l34_private *priv = snd_soc_component_get_drvdata(component); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL, 0x80, 0x80); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL, 0x80, 0x00); break; From 952b334dcfcf641a6290b876bdc226c23772287e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:36 +0000 Subject: [PATCH 251/651] ASoC: codec: cs42l42: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64hfq4n.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l42.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 501c951cc327..56668c392063 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -830,11 +830,11 @@ static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u32 asp_cfg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: asp_cfg_val |= CS42L42_ASP_MASTER_MODE << CS42L42_ASP_MODE_SHIFT; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: asp_cfg_val |= CS42L42_ASP_SLAVE_MODE << CS42L42_ASP_MODE_SHIFT; break; From fad200733e5026b103ec2504ad3dfc2843216cc8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:40 +0000 Subject: [PATCH 252/651] ASoC: codec: cs42l51: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frk1fq4j.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l51.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6e51954bdb1e..0602d03095d6 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -322,10 +322,10 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai, } switch (format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: cs42l51->func = MODE_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: cs42l51->func = MODE_SLAVE_AUTO; break; default: From 1ef8b1c830a0b5a6600d803a8bbeb7179d3ca4da Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:44 +0000 Subject: [PATCH 253/651] ASoC: codec: cs42l52: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczlfq4f.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l52.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 7128d4c62f50..cd3f92c19045 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -733,10 +733,10 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u8 iface = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: iface = CS42L52_IFACE_CTL1_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: iface = CS42L52_IFACE_CTL1_SLAVE; break; default: From b9dde447dd27f1b3ca21e07da1d885fd342cfa62 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:48 +0000 Subject: [PATCH 254/651] ASoC: codec: cs42l56: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyf5fq4b.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l56.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index aaa10c459b52..aaf90c8b7339 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -757,10 +757,10 @@ static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: cs42l56->iface = CS42L56_MASTER_MODE; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: cs42l56->iface = CS42L56_SLAVE_MODE; break; default: From 8f5ae83953335d9c4c8d1cb698b87cea1ac8aeca Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:51 +0000 Subject: [PATCH 255/651] ASoC: codec: cs42l73: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjupfq48.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l73.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 21ba796a5cd9..ddf36001100e 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -943,11 +943,11 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) mmcc = snd_soc_component_read(component, CS42L73_MMCC(id)); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: mmcc |= CS42L73_MS_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: mmcc &= ~CS42L73_MS_MASTER; break; From 90fd7bb1af1733685f0aece12dd7264d4ef68422 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:31:56 +0000 Subject: [PATCH 256/651] ASoC: codec: cs42xx8: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5a9fq43.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42xx8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 9c44b6283b8f..8887db653dbf 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c @@ -242,10 +242,10 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai, /* Set master/slave audio interface */ switch (format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: cs42xx8->slave_mode = true; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: cs42xx8->slave_mode = false; break; default: From dc946ef548aeeea258b040087b88c9b7fae5cb6d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:00 +0000 Subject: [PATCH 257/651] ASoC: codec: cs43130: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qptfq3z.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs43130.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index f8e2fb69ada2..cd535be0b4ba 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -640,10 +640,10 @@ static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk, } switch (cs43130->dais[dai_id].dai_mode) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: dai_mode_val = 0; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: dai_mode_val = 1; break; default: @@ -851,7 +851,7 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - if (cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM) + if (cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBP_CFP) regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG, CS43130_DSD_MASTER, CS43130_DSD_MASTER); else @@ -951,7 +951,7 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream, break; } - if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM) + if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBP_CFP) /* Calculate SCLK in master mode if unassigned */ sclk = params_rate(params) * bitwidth_dai * params_channels(params); @@ -1516,11 +1516,11 @@ static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS; + case SND_SOC_DAIFMT_CBC_CFC: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBC_CFC; break; - case SND_SOC_DAIFMT_CBM_CFM: - cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM; + case SND_SOC_DAIFMT_CBP_CFP: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBP_CFP; break; default: dev_err(cs43130->dev, "unsupported mode\n"); @@ -1579,11 +1579,11 @@ static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS; + case SND_SOC_DAIFMT_CBC_CFC: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBC_CFC; break; - case SND_SOC_DAIFMT_CBM_CFM: - cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM; + case SND_SOC_DAIFMT_CBP_CFP: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBP_CFP; break; default: dev_err(cs43130->dev, "Unsupported DAI format.\n"); From e759aeeb1d09147891e08682df3a70dfbd15724a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:04 +0000 Subject: [PATCH 258/651] ASoC: codec: cs53l30: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c5dfq3v.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs53l30.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 28f4be37dec1..aea4244fb275 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -572,10 +572,10 @@ static int cs53l30_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) u8 aspcfg = 0, aspctl1 = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aspcfg |= CS53L30_ASP_MS; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From b50e5b9694e2a4355f2abeaa711dae5190661c27 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:08 +0000 Subject: [PATCH 259/651] ASoC: codec: da7210: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/875xkxfq3r.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/da7210.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index da2d0242019e..a889f05119f8 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -882,11 +882,11 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) return -EINVAL; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: da7210->master = 1; dai_cfg1 |= DA7210_DAI_MODE_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: da7210->master = 0; dai_cfg1 |= DA7210_DAI_MODE_SLAVE; break; From 7177a7a8e10d7722d0b9d4be4eea7dde014527b9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:12 +0000 Subject: [PATCH 260/651] ASoC: codec: da7218: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/874j0hfq3n.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/da7218.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 8aacd7350798..5f2f67e3bd29 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -1935,10 +1935,10 @@ static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u8 dai_clk_mode = 0, dai_ctrl = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: da7218->master = true; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: da7218->master = false; break; default: From fc0a8ee9921f50ac23b3264846720d1d15be539e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:16 +0000 Subject: [PATCH 261/651] ASoC: codec: da7219: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/8734g1fq3k.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/da7219.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index e2da3e317b5a..3958e88a2445 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -1312,10 +1312,10 @@ static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u8 dai_clk_mode = 0, dai_ctrl = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: da7219->master = true; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: da7219->master = false; break; default: From e5f0c2ad987b494ab94bcb1331667d189249f234 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:19 +0000 Subject: [PATCH 262/651] ASoC: codec: da732x: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/871pvlfq3g.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/da732x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index b747f6fa12e4..016c9be3ebda 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1034,11 +1034,11 @@ static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: aif1 = DA732X_AIF_SLAVE; aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif1 = DA732X_AIF_CLK_FROM_SRC; aif_mclk = DA732X_CLK_GENERATION_AIF_A; break; From 6f8ac982806a104e4e816e12279d85440b6f703f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:24 +0000 Subject: [PATCH 263/651] ASoC: codec: da9055: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87zfi9ebiw.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/da9055.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 8bb8fef2a1d1..eb795abe9acd 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1160,12 +1160,12 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u8 aif_clk_mode, aif_ctrl, mode; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: /* DA9055 in I2S Master Mode */ mode = 1; aif_clk_mode = DA9055_AIF_CLK_EN_MASTER_MODE; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: /* DA9055 in I2S Slave Mode */ mode = 0; aif_clk_mode = DA9055_AIF_CLK_EN_SLAVE_MODE; From 739f4f44dc42b866090297adc1f007ffcdefb602 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:27 +0000 Subject: [PATCH 264/651] ASoC: codec: nau8540: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87y0xtebis.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8540.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index 7e59448e7ac6..caf2edb23088 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -482,10 +482,10 @@ static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int ctrl1_val = 0, ctrl2_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ctrl2_val |= NAU8540_I2S_MS_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From a3c86259f8a402aa050fc5f3039f94c7872e4657 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:31 +0000 Subject: [PATCH 265/651] ASoC: codec: nau8810: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmddebio.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8810.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index dc3aaca89919..6f432b992941 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -613,10 +613,10 @@ static int nau8810_set_dai_fmt(struct snd_soc_dai *codec_dai, u16 ctrl1_val = 0, ctrl2_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ctrl2_val |= NAU8810_CLKIO_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 1fca457c22a277ba47ae1bdd2a09d42926a5beed Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:35 +0000 Subject: [PATCH 266/651] ASoC: codec: nau8822: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7sxebik.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8822.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index fd4a96a12060..15d6f8d01f78 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -806,10 +806,10 @@ static int nau8822_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) dev_dbg(component->dev, "%s\n", __func__); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ctrl2_val |= 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: ctrl2_val &= ~1; break; default: From e23d68d7d3b35a44eb83d834b65cd28ca08844ec Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:39 +0000 Subject: [PATCH 267/651] ASoC: codec: nau8824: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8hebig.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8824.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 5aaf8c496300..542bd22e6180 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -1159,10 +1159,10 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int ctrl1_val = 0, ctrl2_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ctrl2_val |= NAU8824_I2S_MS_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 2f120ee8026ab9630dc7f93dd4bafdcd56c82056 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:43 +0000 Subject: [PATCH 268/651] ASoC: codec: nau8825: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87seo1ebic.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8825.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index bde25bc6909d..25b8b19e27ec 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -1356,10 +1356,10 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) unsigned int ctrl1_val = 0, ctrl2_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ctrl2_val |= NAU8825_I2S_MS_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 5f2d29942c82d229dbdafe4bd21585d1b67f31ee Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:46 +0000 Subject: [PATCH 269/651] ASoC: codec: rk817: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87r03lebi9.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rk817_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rk817_codec.c b/sound/soc/codecs/rk817_codec.c index 3c5b66357661..3c9957b00881 100644 --- a/sound/soc/codecs/rk817_codec.c +++ b/sound/soc/codecs/rk817_codec.c @@ -303,10 +303,10 @@ static int rk817_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int i2s_mst = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: i2s_mst |= RK817_I2S_MODE_SLV; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: i2s_mst |= RK817_I2S_MODE_MST; break; default: From 9c7cf29bdb11cfdd1b59d1ea1eb852245b26e93a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:51 +0000 Subject: [PATCH 270/651] ASoC: codec: rt274: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87plj5ebi4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt274.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index bd61a257d7b5..92ff78aa536b 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -706,12 +706,12 @@ static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: snd_soc_component_update_bits(component, RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_M); rt274->master = true; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: snd_soc_component_update_bits(component, RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_S); rt274->master = false; From a212edb16ca0698c488c6adfa6854224666c8cc1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:55 +0000 Subject: [PATCH 271/651] ASoC: codec: rt286: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6ypebi0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index d0f533120c33..8a4bd8d5ee39 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -765,11 +765,11 @@ static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct snd_soc_component *component = dai->component; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: snd_soc_component_update_bits(component, RT286_I2S_CTRL1, 0x800, 0x800); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: snd_soc_component_update_bits(component, RT286_I2S_CTRL1, 0x800, 0x0); break; From 84f32702f3efe02c2622b9151d4e08c436249a8c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:32:59 +0000 Subject: [PATCH 272/651] ASoC: codec: rt298: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mse9ebhx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt298.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index 13aef6c5e91c..b1fb8f365fc2 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -829,11 +829,11 @@ static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct snd_soc_component *component = dai->component; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: snd_soc_component_update_bits(component, RT298_I2S_CTRL1, 0x800, 0x800); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: snd_soc_component_update_bits(component, RT298_I2S_CTRL1, 0x800, 0x0); break; From b865e0823cbffb747173b7dd4f4c8d82491d111f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:03 +0000 Subject: [PATCH 273/651] ASoC: codec: rt1011: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldttebhs.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c index a0e75b03e9dc..93ad078cdd25 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -1671,7 +1671,7 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) snd_soc_dapm_mutex_lock(dapm); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT1011_I2S_TDM_MS_S; break; default: From 2281565db79b5fd6b539e73a28e73fc960ee34d4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:07 +0000 Subject: [PATCH 274/651] ASoC: codec: rt1015: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jz9debho.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1015.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 0f806dde9c39..a85dd0bcf438 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -753,10 +753,10 @@ static int rt1015_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0, reg_val2 = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: reg_val |= RT1015_TCON_TDM_MS_M; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT1015_TCON_TDM_MS_S; break; default: From f9ef0947ba848467e4dcca6b5ab3a4ff2e218df6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:11 +0000 Subject: [PATCH 275/651] ASoC: codec: rt1016: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikoxebhl.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1016.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt1016.c b/sound/soc/codecs/rt1016.c index fed4da23cba2..2f38a35f0768 100644 --- a/sound/soc/codecs/rt1016.c +++ b/sound/soc/codecs/rt1016.c @@ -367,11 +367,11 @@ static int rt1016_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: reg_val |= RT1016_I2S_MS_M; rt1016->master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT1016_I2S_MS_S; break; default: From 9261d67d8bd2d9e787ceee8ff593f105bb3f5176 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:15 +0000 Subject: [PATCH 276/651] ASoC: codec: rt1305: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64hebhh.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1305.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt1305.c b/sound/soc/codecs/rt1305.c index c2b55be8d165..311a974654ff 100644 --- a/sound/soc/codecs/rt1305.c +++ b/sound/soc/codecs/rt1305.c @@ -697,11 +697,11 @@ static int rt1305_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0, reg1_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: reg_val |= RT1305_SEL_I2S_OUT_MODE_M; rt1305->master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT1305_SEL_I2S_OUT_MODE_S; rt1305->master = 0; break; From 668db717850296122fa0e2aff471cd20a722e0c5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:18 +0000 Subject: [PATCH 277/651] ASoC: codec: rt1308: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frk1ebhd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1308.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt1308.c b/sound/soc/codecs/rt1308.c index b366338cea71..871391f8ffe1 100644 --- a/sound/soc/codecs/rt1308.c +++ b/sound/soc/codecs/rt1308.c @@ -523,7 +523,7 @@ static int rt1308_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0, reg1_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: rt1308->master = 0; break; default: From 2d5e9d40998b441485376b8729c69073d8f2ab9d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:23 +0000 Subject: [PATCH 278/651] ASoC: codec: rt5616: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczlebh9.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5616.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index 34461c462009..1ec486707ff9 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c @@ -1015,10 +1015,10 @@ static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5616->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5616_I2S_MS_S; rt5616->master[dai->id] = 0; break; From 1b16920e651d11811ca4b3a5d92cfb3d817b1a14 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:26 +0000 Subject: [PATCH 279/651] ASoC: codec: rt5631: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyf5ebh5.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5631.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 12df0c4f2097..d523477c5102 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1411,10 +1411,10 @@ static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, dev_dbg(component->dev, "enter %s\n", __func__); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5631->master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: iface |= RT5631_SDP_MODE_SEL_SLAVE; rt5631->master = 0; break; From 60143172c63daa49fef6eb9daa066fb7f1360bbe Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:30 +0000 Subject: [PATCH 280/651] ASoC: codec: rt5640: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjupebh1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 855139348edb..bf5dfcdd36d9 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1773,10 +1773,10 @@ static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) int dai_sel; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5640->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5640_I2S_MS_S; rt5640->master[dai->id] = 0; break; From 3165df2f130d567e6cf05d789ecc28810519e5f7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:34 +0000 Subject: [PATCH 281/651] ASoC: codec: rt5645: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5a9ebgx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 51187b1e0ed2..2d4ad416c186 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -2841,10 +2841,10 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5645->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5645_I2S_MS_S; rt5645->master[dai->id] = 0; break; From e41ebb0a1f8bff63c8e333eec34ff64e748227d0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:38 +0000 Subject: [PATCH 282/651] ASoC: codec: rt5651: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qptebgt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5651.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 00421a1f54bf..7be9f9f0f34f 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1352,10 +1352,10 @@ static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5651->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5651_I2S_MS_S; rt5651->master[dai->id] = 0; break; From f1205656ef2334e860ced588e76dd88119394166 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:41 +0000 Subject: [PATCH 283/651] ASoC: codec: rt5659: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c5debgq.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5659.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index a2652fa6e1d7..1083e7bffcfa 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -3363,10 +3363,10 @@ static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5659->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5659_I2S_MS_S; rt5659->master[dai->id] = 0; break; From 67f2243f2b1f1936c4dc22897289f5815a0e224a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:45 +0000 Subject: [PATCH 284/651] ASoC: codec: rt5660: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/875xkxebgm.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5660.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index 3ac41d2c279b..e335fec9fc56 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -905,11 +905,11 @@ static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5660->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5660_I2S_MS_S; rt5660->master[dai->id] = 0; break; From 0ad3a7d311f0e93f2e838b4e47a7da57c501d737 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:49 +0000 Subject: [PATCH 285/651] ASoC: codec: rt5663: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/874j0hebgj.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 9d32debd3689..b86bc0285266 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -2814,9 +2814,9 @@ static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5663_I2S_MS_S; break; default: From 0b74ed5533c87db1abe3967e3a370bc3046892c7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:52 +0000 Subject: [PATCH 286/651] ASoC: codec: rt5665: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/8734g1ebgf.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5665.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 47df14ba5278..7c5a03b0e918 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -4219,10 +4219,10 @@ static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5665->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5665_I2S_MS_S; rt5665->master[dai->id] = 0; break; From 4869417f4a2b010e9ee00f611265f551a47e4f1a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:56 +0000 Subject: [PATCH 287/651] ASoC: codec: rt5668: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/871pvlebgc.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5668.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c index 494ca3ce9b96..dbb5912e5e2c 100644 --- a/sound/soc/codecs/rt5668.c +++ b/sound/soc/codecs/rt5668.c @@ -2010,10 +2010,10 @@ static int rt5668_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0, tdm_ctrl = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5668->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: rt5668->master[dai->id] = 0; break; default: From b3a3eda6cb30f21b818f40795468ff0a9f629990 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:33:59 +0000 Subject: [PATCH 288/651] ASoC: codec: rt5670: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87zfi9cwvs.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5670.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 30bf96c35b58..4129071f6b83 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2439,10 +2439,10 @@ static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5670->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5670_I2S_MS_S; rt5670->master[dai->id] = 0; break; From 40213f8d5b498f5eb2f3297ee0f9c84d98737ee9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:03 +0000 Subject: [PATCH 289/651] ASoC: codec: rt5677: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87y0xtcwvp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5677.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 0e70a3ab42b5..753dc3c85630 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -4377,10 +4377,10 @@ static int rt5677_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5677->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5677_I2S_MS_S; rt5677->master[dai->id] = 0; break; From f61c11db0f598eed6dd35a2d700ca54c6c74af4a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:06 +0000 Subject: [PATCH 290/651] ASoC: codec: rt5682: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmddcwvl.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index b4d72fc4a44d..7c88370e2dee 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -2225,10 +2225,10 @@ static int rt5682_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0, tdm_ctrl = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5682->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: rt5682->master[dai->id] = 0; break; default: From bd178280c7d967e87e217b51c0647a2bfdf5deec Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:10 +0000 Subject: [PATCH 291/651] ASoC: codec: rt5682s: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7sxcwvh.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index ce2e88e066f3..73c4b3c31f8c 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -2132,10 +2132,10 @@ static int rt5682s_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0, tdm_ctrl = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5682s->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: rt5682s->master[dai->id] = 0; break; default: From 461deb4911f39e455756cbc42928b12b04e82851 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:14 +0000 Subject: [PATCH 292/651] ASoC: codec: wm2200: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8hcwvd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm2200.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 841247173d98..7ed4ac5cce3c 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -1576,15 +1576,15 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: lrclk |= WM2200_AIF1TX_LRCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: bclk |= WM2200_AIF1_BCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: lrclk |= WM2200_AIF1TX_LRCLK_MSTR; bclk |= WM2200_AIF1_BCLK_MSTR; break; From 4042bb6e973aded1de6ce83436804a90181d6357 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:17 +0000 Subject: [PATCH 293/651] ASoC: codec: wm5100: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87seo1cwva.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm5100.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 11bbc94a282c..dfeec55159a6 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -1303,15 +1303,15 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: lrclk |= WM5100_AIF1TX_LRCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: bclk |= WM5100_AIF1_BCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: lrclk |= WM5100_AIF1TX_LRCLK_MSTR; bclk |= WM5100_AIF1_BCLK_MSTR; break; From 474cd6355413b264087ddc66b1dbc6c7e59fb76f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:21 +0000 Subject: [PATCH 294/651] ASoC: codec: wm8350: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87r03lcwv6.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8350.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 66bd281095e1..b1fe6f4e0c10 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -846,12 +846,12 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: master |= WM8350_BCLK_MSTR; dac_lrc |= WM8350_DACLRC_ENA; adc_lrc |= WM8350_ADCLRC_ENA; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 24684cc2060150afd7a1ea47c586f9c09330633c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:24 +0000 Subject: [PATCH 295/651] ASoC: codec: wm8400: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87plj5cwv3.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8400.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 19ce839f6ef7..5ad6d5b63ffc 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -986,10 +986,10 @@ static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: audio3 &= ~WM8400_AIF_MSTR1; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: audio3 |= WM8400_AIF_MSTR1; break; default: From 420663ae8fa2d70d2b824848763ca15bb5b2b585 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:28 +0000 Subject: [PATCH 296/651] ASoC: codec: wm8510: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6ypcwv0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8510.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 4a31d6f89502..79adbcc90d4a 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -389,10 +389,10 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: clk |= 0x0001; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From e2bcc61a4481c3de4747014895cef45d701956bf Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:31 +0000 Subject: [PATCH 297/651] ASoC: codec: wm8523: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mse9cwuw.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8523.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 138eba7e577a..6671e13c320c 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -264,10 +264,10 @@ static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai, WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aifctrl1 |= WM8523_AIF_MSTR; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From dee14c5b6d29886255c4a54599590d49fc1754be Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:35 +0000 Subject: [PATCH 298/651] ASoC: codec: wm8524: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldttcwut.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8524.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c index fa9942a08927..403e513f3fa8 100644 --- a/sound/soc/codecs/wm8524.c +++ b/sound/soc/codecs/wm8524.c @@ -139,7 +139,7 @@ static int wm8524_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) SND_SOC_DAIFMT_MASTER_MASK); if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS)) { + SND_SOC_DAIFMT_CBC_CFC)) { dev_err(codec_dai->dev, "Invalid DAI format\n"); return -EINVAL; } From 1b94f3874d61b34febd5ddf3482a90107dc80082 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:38 +0000 Subject: [PATCH 299/651] ASoC: codec: wm8580: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jz9dcwup.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8580.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 73a8edc797fb..ba4a08456e78 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -614,10 +614,10 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai, aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: aifa &= ~WM8580_AIF_MS; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aifa |= WM8580_AIF_MS; break; default: From 042ecb2ab2361f77b34a7d3c642bd378f6ecc73a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:41 +0000 Subject: [PATCH 300/651] ASoC: codec: wm8711: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikoxcwum.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8711.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index a1c99bbf5aa1..481088987742 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -243,10 +243,10 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: iface |= 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 4d20a35acef6fb8c42eff953a11759e94710ba8b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:45 +0000 Subject: [PATCH 301/651] ASoC: codec: wm8728: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64hcwui.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8728.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 2cbd6b189416..ea0a588da40f 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -128,7 +128,7 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai, /* The hardware only support full slave mode */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From bb0b8a07192d86b291c5b13fb64ef984930f8ea6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:49 +0000 Subject: [PATCH 302/651] ASoC: codec: wm8737: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frk1cwuf.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8737.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index efdc242c2ede..f7e48f27649d 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -404,10 +404,10 @@ static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai, u16 af = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: af |= WM8737_MS; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From a018b6601c47e7d989f1fe5c175325f85dceb264 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:53 +0000 Subject: [PATCH 303/651] ASoC: codec: wm8741: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczlcwub.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8741.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 4863d6ac461b..4dfbb33edb09 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -308,7 +308,7 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai, /* check master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 4be54b6bdafad7656fd85c1fa6b7bebb7700a3d2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:56 +0000 Subject: [PATCH 304/651] ASoC: codec: wm8750: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyf5cwu7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8750.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index cae97fa3bcb0..312be0721b5d 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -522,10 +522,10 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: iface = 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 92acd9f7409d2939e5fef8bde5ad527b9e525229 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:34:59 +0000 Subject: [PATCH 305/651] ASoC: codec: wm8753: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjupcwu4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8753.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 38b76b7275e5..43cc368cf3f3 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -963,12 +963,12 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_component *component, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ioctl |= 0x2; fallthrough; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: voice |= 0x0040; break; default: @@ -1089,12 +1089,12 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_component *component, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ioctl |= 0x1; fallthrough; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: hifi |= 0x0040; break; default: From d17b39f6d3e635b039314726fbc66dcef286ed79 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:03 +0000 Subject: [PATCH 306/651] ASoC: codec: wm8770: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5a9cwu0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8770.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 38376b605201..5685c3bb5555 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -349,10 +349,10 @@ static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) component = dai->component; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: master = 0x100; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: master = 0; break; default: From 9b9cbc6b4fa312d963f4373e88b6e27106f2051a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:06 +0000 Subject: [PATCH 307/651] ASoC: codec: wm8776: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qptcwtx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8776.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 166e00fcd11d..7b73c825aed4 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -182,9 +182,9 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) iface = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: master = 0; break; default: From ad3993c449637fcec1e05bd2b63c24d34cb82243 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:10 +0000 Subject: [PATCH 308/651] ASoC: codec: wm8804: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c5dcwtu.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8804.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index cfa78e4d8b73..0a879c29eb04 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -243,10 +243,10 @@ static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) snd_soc_component_update_bits(component, WM8804_AIFRX, 0x3, format); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: master = 0; break; default: From 2f8b07842e9e95122b848727ea73504a035e7c12 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:14 +0000 Subject: [PATCH 309/651] ASoC: codec: wm8900: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/875xkxcwtp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8900.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index e44fdf97796f..6fb25588ca81 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -867,22 +867,22 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR; aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR; aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR; aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR; aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR; aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR; aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR; aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR; aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR; From 1a126668ab0946ebb7d1450742cd14775aa298fa Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:18 +0000 Subject: [PATCH 310/651] ASoC: codec: wm8903: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/874j0hcwtl.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index c643b5377d3a..03902909f27e 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1229,15 +1229,15 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai, WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: aif1 |= WM8903_LRCLK_DIR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif1 |= WM8903_LRCLK_DIR | WM8903_BCLK_DIR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: aif1 |= WM8903_BCLK_DIR; break; default: From 25baeacd9c6307830e2ed9f586f81fc23d4d1002 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:21 +0000 Subject: [PATCH 311/651] ASoC: codec: wm8904: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/8734g1cwti.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index aef82532f8cf..207d3bd2e729 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1424,15 +1424,15 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int aif3 = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: aif3 |= WM8904_LRCLK_DIR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: aif1 |= WM8904_BCLK_DIR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif1 |= WM8904_BCLK_DIR; aif3 |= WM8904_LRCLK_DIR; break; From 2d2223d742d968fec77ed056db9f158e7cb3ca94 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:25 +0000 Subject: [PATCH 312/651] ASoC: codec: wm8940: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/871pvlcwte.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8940.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 8a532f7d750c..401ee20897b1 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -343,10 +343,10 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai, u16 clk = snd_soc_component_read(component, WM8940_CLOCK) & 0x1fe; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: clk |= 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From fb44bd4902cd5df526ad432015edcfaf163999e2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:28 +0000 Subject: [PATCH 313/651] ASoC: codec: wm8955: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87zfi9bi8v.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8955.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index bae52a8a2e11..bca83410b432 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -671,9 +671,9 @@ static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) u16 aif = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif |= WM8955_MS; break; default: From 541e0b4947a92f4bf1d60ef7e55f0a254d9c41a0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:32 +0000 Subject: [PATCH 314/651] ASoC: codec: wm8960: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87y0xtbi8r.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8960.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 00858b9c9568..e6525b4cedfb 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -540,10 +540,10 @@ static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: iface |= 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From b99c850bd41e8f6f142bb24c3c2485043b552621 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:36 +0000 Subject: [PATCH 315/651] ASoC: codec: wm8961: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmddbi8o.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8961.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index d1c731e25777..1ec7c5e8fd69 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -627,10 +627,10 @@ static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) WM8961_MS | WM8961_FORMAT_MASK); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif |= WM8961_MS; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From c6472392301fc15a09d5435f1f89421270aed81c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:41 +0000 Subject: [PATCH 316/651] ASoC: codec: wm8962: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7sxbi8j.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 08d164ce3e49..0aaac24eeb5a 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2762,10 +2762,10 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif0 |= WM8962_MSTR; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From ed86f7b7e5f676c24ba0ddd86de6614a4b69a9e4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:44 +0000 Subject: [PATCH 317/651] ASoC: codec: wm8971: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8hbi8f.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8971.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index b97c7d5bd4e7..62dcddeb78b3 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -452,10 +452,10 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: iface = 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From 68084db5e7a5eb1e4901e2158565cfc59873756d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:48 +0000 Subject: [PATCH 318/651] ASoC: codec: wm8974: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87seo1bi8b.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8974.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 0ee3655cad01..bdf437a5403f 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -454,10 +454,10 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: clk |= 0x0001; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From f0bd6cb02505eca6adbe2e3ad3445a2420637c19 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:51 +0000 Subject: [PATCH 319/651] ASoC: codec: wm8978: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87r03lbi88.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8978.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 40d22b36b7a9..8c45ba6fc4c3 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -660,10 +660,10 @@ static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: clk |= 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: clk &= ~1; break; default: From 93b1fefd8b1a004c6c8f8c92085e7bfb694dfe98 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:54 +0000 Subject: [PATCH 320/651] ASoC: codec: wm8983: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87plj5bi85.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8983.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 252b4a6cac04..6a83afe6400b 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -594,10 +594,10 @@ static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) WM8983_FMT_MASK, format << WM8983_FMT_SHIFT); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: master = 0; break; default: From 7f3ed7ea52f21d5b8ecc01a17fb8f7209d337cbe Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:35:58 +0000 Subject: [PATCH 321/651] ASoC: codec: wm8985: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6ypbi82.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8985.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index da00db5b0172..2e2d07193c41 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -688,10 +688,10 @@ static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) WM8985_FMT_MASK, format << WM8985_FMT_SHIFT); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: master = 0; break; default: From 2725c018785d52286dd5b4ff7e087d2ff455a1a8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:01 +0000 Subject: [PATCH 322/651] ASoC: codec: wm8988: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mse9bi7y.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8988.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index f0e9d6e38dc0..cf6d642b7bfe 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -589,10 +589,10 @@ static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: iface = 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; From d542f5bfa3e4e16aac6141abdd44bb8a2a6f0761 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:04 +0000 Subject: [PATCH 323/651] ASoC: codec: wm8990: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldttbi7v.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8990.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 573bd3d487ba..89df406bf552 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -897,10 +897,10 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: audio3 &= ~WM8990_AIF_MSTR1; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: audio3 |= WM8990_AIF_MSTR1; break; default: From 0d4291fa3a8945d97d26a6bac8a4068f116f2885 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:08 +0000 Subject: [PATCH 324/651] ASoC: codec: wm8991: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jz9dbi7s.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8991.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 3bd9b362051b..c3dd44c1dd0c 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -958,10 +958,10 @@ static int wm8991_set_dai_fmt(struct snd_soc_dai *codec_dai, /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: audio3 &= ~WM8991_AIF_MSTR1; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: audio3 |= WM8991_AIF_MSTR1; break; default: From 291b4eb984792fcc0bd3dec9ad9a69c3c6988951 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:11 +0000 Subject: [PATCH 325/651] ASoC: codec: wm8993: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikoxbi7o.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8993.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index f257980f9b56..9be4f6cadba3 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1098,18 +1098,18 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai, aif4 &= ~WM8993_LRCLK_DIR; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: wm8993->master = 0; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: aif4 |= WM8993_LRCLK_DIR; wm8993->master = 1; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: aif1 |= WM8993_BCLK_DIR; wm8993->master = 1; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif1 |= WM8993_BCLK_DIR; aif4 |= WM8993_LRCLK_DIR; wm8993->master = 1; From 35492f84fbd6d790ad7f93bffaaa6823890c103a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:15 +0000 Subject: [PATCH 326/651] ASoC: codec: wm8994: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64hbi7l.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index a4abe6e53bfc..69a22992c281 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2783,9 +2783,9 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ms = WM8994_AIF1_MSTR; break; default: From c417a7cf976eb8ecd8ebca439ec0cb0fe9ddc7ec Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:18 +0000 Subject: [PATCH 327/651] ASoC: codec: wm8995: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frk1bi7h.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8995.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 1f9a9b636935..a88170a3ed91 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -1448,9 +1448,9 @@ static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) master = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: master = WM8995_AIF1_MSTR; break; default: From cc49a35ab19565c5eaef070755b6fba235f9d05a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:22 +0000 Subject: [PATCH 328/651] ASoC: codec: wm8996: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczlbi7e.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8996.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 5c06cea09bd1..c2af8d7ecdd8 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -1672,16 +1672,16 @@ static int wm8996_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR; lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: bclk |= WM8996_AIF1_BCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: bclk |= WM8996_AIF1_BCLK_MSTR; lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR; lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR; From cfb91be8f9c8e54e517a9a539012309101abcac5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:26 +0000 Subject: [PATCH 329/651] ASoC: codec: wm9081: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyf5bi7a.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm9081.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index cb9d040b34d6..94d8571360c4 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -907,18 +907,18 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai, WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: wm9081->master = 0; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: aif2 |= WM9081_LRCLK_DIR; wm9081->master = 1; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: aif2 |= WM9081_BCLK_DIR; wm9081->master = 1; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: aif2 |= WM9081_LRCLK_DIR | WM9081_BCLK_DIR; wm9081->master = 1; break; From 9c914ef3b876a6f6c0059b4f4323fc1b76fa05e4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:29 +0000 Subject: [PATCH 330/651] ASoC: codec: wm9713: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjupbi76.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 64b69316e4c7..5b0fa1b20d76 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -944,19 +944,19 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai, /* clock masters */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: reg |= 0x4000; gpio |= 0x0010; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: reg |= 0x6000; gpio |= 0x0018; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg |= 0x2000; gpio |= 0x001a; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: gpio |= 0x0012; break; } From 74da545ec6a8b41de96b4c350bb59dfe45c0d822 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:32 +0000 Subject: [PATCH 331/651] ASoC: codec: madera: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5a9bi73.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/madera.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c index a840a2eb92b9..b0b5973509e4 100644 --- a/sound/soc/codecs/madera.c +++ b/sound/soc/codecs/madera.c @@ -2776,7 +2776,7 @@ static int madera_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) break; case SND_SOC_DAIFMT_DSP_B: if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != - SND_SOC_DAIFMT_CBM_CFM) { + SND_SOC_DAIFMT_CBP_CFP) { madera_aif_err(dai, "DSP_B not valid in slave mode\n"); return -EINVAL; } @@ -2787,7 +2787,7 @@ static int madera_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) break; case SND_SOC_DAIFMT_LEFT_J: if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != - SND_SOC_DAIFMT_CBM_CFM) { + SND_SOC_DAIFMT_CBP_CFP) { madera_aif_err(dai, "LEFT_J not valid in slave mode\n"); return -EINVAL; } @@ -2800,15 +2800,15 @@ static int madera_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: lrclk |= MADERA_AIF1TX_LRCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: bclk |= MADERA_AIF1_BCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: bclk |= MADERA_AIF1_BCLK_MSTR; lrclk |= MADERA_AIF1TX_LRCLK_MSTR; break; From 1af0148c3f871e55a6c4adf544af77a19fd17671 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:36 +0000 Subject: [PATCH 332/651] ASoC: codec: arizona: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qptbi6z.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 402b9a2ff024..6bb1e8698d41 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1457,7 +1457,7 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) break; case SND_SOC_DAIFMT_DSP_B: if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) - != SND_SOC_DAIFMT_CBM_CFM) { + != SND_SOC_DAIFMT_CBP_CFP) { arizona_aif_err(dai, "DSP_B not valid in slave mode\n"); return -EINVAL; } @@ -1468,7 +1468,7 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) break; case SND_SOC_DAIFMT_LEFT_J: if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) - != SND_SOC_DAIFMT_CBM_CFM) { + != SND_SOC_DAIFMT_CBP_CFP) { arizona_aif_err(dai, "LEFT_J not valid in slave mode\n"); return -EINVAL; } @@ -1481,15 +1481,15 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: bclk |= ARIZONA_AIF1_BCLK_MSTR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: bclk |= ARIZONA_AIF1_BCLK_MSTR; lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; break; From c80956630fa077646f971ff5d3e9452339742def Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:40 +0000 Subject: [PATCH 333/651] ASoC: codec: twl4030: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c5dbi6v.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index e3782762139f..609886461805 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -2049,7 +2049,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_CBP_CFP: format &= ~(TWL4030_VIF_SLAVE_EN); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: format |= TWL4030_VIF_SLAVE_EN; break; default: From 27f5e88fdc8ab577dbff389085ae6ad41e994ae7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:43 +0000 Subject: [PATCH 334/651] ASoC: codec: src4xxx: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/875xkxbi6s.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/src4xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/src4xxx.c b/sound/soc/codecs/src4xxx.c index db4e280dd055..5a3489475225 100644 --- a/sound/soc/codecs/src4xxx.c +++ b/sound/soc/codecs/src4xxx.c @@ -158,11 +158,11 @@ static int src4xxx_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int ctrl; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: ctrl = SRC4XXX_BUS_MASTER; src4xxx->master[dai->id] = true; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: ctrl = 0; src4xxx->master[dai->id] = false; break; From 6575dd53217ee5686d48a35f48415b113518d2a9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:48 +0000 Subject: [PATCH 335/651] ASoC: codec: sgtl5000: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/874j0hbi6n.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 7aa89e34657e..2cc8efe3d896 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -806,9 +806,9 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) * - clock and frame master */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: i2sctl |= SGTL5000_I2S_MASTER; sgtl5000->master = 1; break; From 6dd61011a67e35b8d5f3b94193ed66d0c19ba425 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:51 +0000 Subject: [PATCH 336/651] ASoC: codec: lochnagar-sc: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/8734g1bi6k.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/lochnagar-sc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/lochnagar-sc.c b/sound/soc/codecs/lochnagar-sc.c index 5e0bd0d24ed3..a3d6318c9050 100644 --- a/sound/soc/codecs/lochnagar-sc.c +++ b/sound/soc/codecs/lochnagar-sc.c @@ -129,12 +129,12 @@ static int lochnagar_sc_check_fmt(struct snd_soc_dai *dai, unsigned int fmt, static int lochnagar_sc_set_line_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - return lochnagar_sc_check_fmt(dai, fmt, SND_SOC_DAIFMT_CBS_CFS); + return lochnagar_sc_check_fmt(dai, fmt, SND_SOC_DAIFMT_CBC_CFC); } static int lochnagar_sc_set_usb_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - return lochnagar_sc_check_fmt(dai, fmt, SND_SOC_DAIFMT_CBM_CFM); + return lochnagar_sc_check_fmt(dai, fmt, SND_SOC_DAIFMT_CBP_CFP); } static const struct snd_soc_dai_ops lochnagar_sc_line_ops = { From 521c04c6e32ac110d942fa0e11bea4b91cc3241d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:55 +0000 Subject: [PATCH 337/651] ASoC: ux500: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/871pvlbi6h.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/ux500/mop500_ab8500.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c index 710b6744e013..5246f73ef12e 100644 --- a/sound/soc/ux500/mop500_ab8500.c +++ b/sound/soc/ux500/mop500_ab8500.c @@ -275,12 +275,12 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, if (driver_mode == DRIVERMODE_NORMAL) { fmt = SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_CBP_CFP | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CONT; } else { fmt = SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_CBP_CFP | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_GATED; } From 6cc4d2c11537d66e9d4a7356a576f1bea6f4009f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:36:58 +0000 Subject: [PATCH 338/651] ASoC: meson: t9015: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87zfi9a3lx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/meson/t9015.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c index 571f65788c59..a80e9c9d6288 100644 --- a/sound/soc/meson/t9015.c +++ b/sound/soc/meson/t9015.c @@ -57,11 +57,11 @@ static int t9015_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int val; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: val = I2S_MODE; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: val = 0; break; From 4586b056956995754e95456312b2a9ce36c8de21 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:02 +0000 Subject: [PATCH 339/651] ASoC: meson: meson-card-utils: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87y0xta3lt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/meson/meson-card-utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/meson/meson-card-utils.c b/sound/soc/meson/meson-card-utils.c index 1a4ef124e4e2..cfc7f6e41ab5 100644 --- a/sound/soc/meson/meson-card-utils.c +++ b/sound/soc/meson/meson-card-utils.c @@ -119,10 +119,10 @@ unsigned int meson_card_parse_daifmt(struct device_node *node, /* If no master is provided, default to cpu master */ if (!bitclkmaster || bitclkmaster == cpu_node) { daifmt |= (!framemaster || framemaster == cpu_node) ? - SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBS_CFM; + SND_SOC_DAIFMT_CBC_CFC : SND_SOC_DAIFMT_CBC_CFP; } else { daifmt |= (!framemaster || framemaster == cpu_node) ? - SND_SOC_DAIFMT_CBM_CFS : SND_SOC_DAIFMT_CBM_CFM; + SND_SOC_DAIFMT_CBP_CFC : SND_SOC_DAIFMT_CBP_CFP; } of_node_put(bitclkmaster); From 04ea3e0d2e10642f0a0199081e9aa8fd5e1bbea6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:06 +0000 Subject: [PATCH 340/651] ASoC: tegra: tegra_asoc_machine: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmdda3lp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_asoc_machine.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/tegra/tegra_asoc_machine.c b/sound/soc/tegra/tegra_asoc_machine.c index 775ce433fdbf..62f896772731 100644 --- a/sound/soc/tegra/tegra_asoc_machine.c +++ b/sound/soc/tegra/tegra_asoc_machine.c @@ -637,7 +637,7 @@ static struct snd_soc_dai_link tegra_wm8753_dai = { .stream_name = "WM8753 PCM", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(wm8753_hifi), }; @@ -701,7 +701,7 @@ static struct snd_soc_dai_link tegra_max98090_dai = { .init = tegra_asoc_machine_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(max98090_hifi), }; @@ -736,7 +736,7 @@ static struct snd_soc_dai_link tegra_max98088_dai = { .init = tegra_asoc_machine_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(max98088_hifi), }; @@ -769,7 +769,7 @@ static struct snd_soc_dai_link tegra_sgtl5000_dai = { .stream_name = "HiFi", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(sgtl5000_hifi), }; @@ -812,7 +812,7 @@ static struct snd_soc_dai_link tegra_tlv320aic23_dai = { .stream_name = "AIC23", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(tlv320aic23_hifi), }; @@ -861,7 +861,7 @@ static struct snd_soc_dai_link tegra_rt5677_dai = { .init = tegra_rt5677_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(rt5677_aif1), }; @@ -895,7 +895,7 @@ static struct snd_soc_dai_link tegra_rt5640_dai = { .init = tegra_asoc_machine_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(rt5640_aif1), }; @@ -928,7 +928,7 @@ static struct snd_soc_dai_link tegra_rt5632_dai = { .init = tegra_rt5677_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(rt5632_hifi), }; @@ -961,7 +961,7 @@ static struct snd_soc_dai_link tegra_rt5631_dai = { .init = tegra_asoc_machine_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(rt5631_hifi), }; From b15ea10972a1b4db23f7495003fccc6fe59e44bd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:09 +0000 Subject: [PATCH 341/651] ASoC: tegra: tegra_wm8903: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7sxa3lm.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8903.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 6116d2e30fca..78b02c64d95c 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -124,7 +124,7 @@ static struct snd_soc_dai_link tegra_wm8903_dai = { .init = tegra_wm8903_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(hifi), }; From 836d2924c05edb06e32eeede8bc12c4c96da0b3d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:13 +0000 Subject: [PATCH 342/651] ASoC: intel: rt274: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8ha3li.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt274.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index f5caafc21861..29977aee2153 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -179,7 +179,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->init = avs_rt274_codec_init; dl->exit = avs_rt274_codec_exit; dl->be_hw_params_fixup = avs_rt274_be_fixup; From ccf2a77a5d1504ca95c1ae5f37ed184e62dcd2f2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:16 +0000 Subject: [PATCH 343/651] ASoC: intel: rt286: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87seo1a3lf.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt286.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c index 1eb0399c0fae..6a27c6a9f394 100644 --- a/sound/soc/intel/avs/boards/rt286.c +++ b/sound/soc/intel/avs/boards/rt286.c @@ -147,7 +147,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->init = avs_rt286_codec_init; dl->exit = avs_rt286_codec_exit; dl->be_hw_params_fixup = avs_rt286_be_fixup; From f5617b647c8597e2437b3899f520fdf65e0f277a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:20 +0000 Subject: [PATCH 344/651] ASoC: intel: rt298: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87r03la3lb.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt298.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index 85269a3be981..a7a463d6f852 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -165,9 +165,9 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->num_platforms = 1; dl->id = 0; if (dmi_first_match(kblr_dmi_table)) - dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; else - dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->init = avs_rt298_codec_init; dl->exit = avs_rt298_codec_exit; dl->be_hw_params_fixup = avs_rt298_be_fixup; From 6d41096d7df609992479d6a3a43bc60e21b8e165 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:27 +0000 Subject: [PATCH 345/651] ASoC: intel: rt5514: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87plj5a3l4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt5514.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/rt5514.c b/sound/soc/intel/avs/boards/rt5514.c index 30588d9e9ba3..d1c3e29a28ff 100644 --- a/sound/soc/intel/avs/boards/rt5514.c +++ b/sound/soc/intel/avs/boards/rt5514.c @@ -116,7 +116,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->init = avs_rt5514_codec_init; dl->be_hw_params_fixup = avs_rt5514_be_fixup; dl->nonatomic = 1; From e15abfa60107f97fd8297faad8cc3dc4eae0b5cc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:31 +0000 Subject: [PATCH 346/651] ASoC: intel: da7219: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6ypa3l1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/da7219.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 9507a96f26ac..7217ae51e89c 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -198,7 +198,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->be_hw_params_fixup = avs_da7219_be_fixup; dl->init = avs_da7219_codec_init; dl->exit = avs_da7219_codec_exit; From 0808c1ab8d1a1222194d830870f6b2b47220b1d7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:35 +0000 Subject: [PATCH 347/651] ASoC: intel: ssm4567: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mse9a3kx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/ssm4567.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c index cfef00462f66..c9d89bfe7178 100644 --- a/sound/soc/intel/avs/boards/ssm4567.c +++ b/sound/soc/intel/avs/boards/ssm4567.c @@ -116,7 +116,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->init = avs_ssm4567_codec_init; dl->be_hw_params_fixup = avs_ssm4567_be_fixup; dl->nonatomic = 1; From 4994da5c7fea1ede9b71ae66e3b906ea56b9a929 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:38 +0000 Subject: [PATCH 348/651] ASoC: intel: nau8825: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldtta3kt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/nau8825.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c index 6833eebd82d6..e203ceb83b87 100644 --- a/sound/soc/intel/avs/boards/nau8825.c +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -204,7 +204,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->init = avs_nau8825_codec_init; dl->exit = avs_nau8825_codec_exit; dl->be_hw_params_fixup = avs_nau8825_be_fixup; From bcb896a69864aec4dd0251732a380bcdbeff8c51 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:42 +0000 Subject: [PATCH 349/651] ASoC: intel: max98927: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jz9da3kq.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/max98927.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c index ad18c4e9a670..e8e5d1c717cd 100644 --- a/sound/soc/intel/avs/boards/max98927.c +++ b/sound/soc/intel/avs/boards/max98927.c @@ -127,7 +127,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->be_hw_params_fixup = avs_max98927_be_fixup; dl->nonatomic = 1; dl->no_pcm = 1; From d2f277bf8aaed8c5307ab998b2de4346bed6e884 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:46 +0000 Subject: [PATCH 350/651] ASoC: intel: max98357a: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikoxa3km.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/max98357a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/max98357a.c b/sound/soc/intel/avs/boards/max98357a.c index 6570209c1a63..c55c1d60b777 100644 --- a/sound/soc/intel/avs/boards/max98357a.c +++ b/sound/soc/intel/avs/boards/max98357a.c @@ -78,7 +78,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; dl->be_hw_params_fixup = avs_max98357a_be_fixup; dl->nonatomic = 1; dl->no_pcm = 1; From 69e35d9bfd6ba2837fe18bebf97ea747ceb110d5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:49 +0000 Subject: [PATCH 351/651] ASoC: samsung: snow: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64ha3ki.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/snow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c index 4bbe7bcdb845..66ef49dff1ba 100644 --- a/sound/soc/samsung/snow.c +++ b/sound/soc/samsung/snow.c @@ -137,7 +137,7 @@ static int snow_probe(struct platform_device *pdev) link = &priv->dai_link; link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS; + SND_SOC_DAIFMT_CBC_CFC; link->name = "Primary"; link->stream_name = link->name; From 5dc6b4a351de9804932c4475a2c73c22c0b59369 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:52 +0000 Subject: [PATCH 352/651] ASoC: samsung: bells: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frk1a3kf.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/bells.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index 365b1aca4855..ba9b0b1fba03 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -256,14 +256,14 @@ static struct snd_soc_dai_link bells_dai_wm2200[] = { .name = "CPU-DSP", .stream_name = "CPU-DSP", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(wm2200_cpu_dsp), }, { .name = "DSP-CODEC", .stream_name = "DSP-CODEC", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .c2c_params = &sub_params, .num_c2c_params = 1, .ignore_suspend = 1, @@ -293,14 +293,14 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { .name = "CPU-DSP", .stream_name = "CPU-DSP", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(wm5102_cpu_dsp), }, { .name = "DSP-CODEC", .stream_name = "DSP-CODEC", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .c2c_params = &sub_params, .num_c2c_params = 1, .ignore_suspend = 1, @@ -310,7 +310,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { .name = "Baseband", .stream_name = "Baseband", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, .c2c_params = &baseband_params, .num_c2c_params = 1, @@ -320,7 +320,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { .name = "Sub", .stream_name = "Sub", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBS_CFS, + | SND_SOC_DAIFMT_CBC_CFC, .ignore_suspend = 1, .c2c_params = &sub_params, .num_c2c_params = 1, @@ -351,14 +351,14 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { .name = "CPU-DSP", .stream_name = "CPU-DSP", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(wm5110_cpu_dsp), }, { .name = "DSP-CODEC", .stream_name = "DSP-CODEC", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .c2c_params = &sub_params, .num_c2c_params = 1, .ignore_suspend = 1, @@ -368,7 +368,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { .name = "Baseband", .stream_name = "Baseband", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, .c2c_params = &baseband_params, .num_c2c_params = 1, @@ -378,7 +378,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { .name = "Sub", .stream_name = "Sub", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBS_CFS, + | SND_SOC_DAIFMT_CBC_CFC, .ignore_suspend = 1, .c2c_params = &sub_params, .num_c2c_params = 1, From 06d07a4f5b98c71c696fa8f8718050b656ab99ba Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:37:57 +0000 Subject: [PATCH 353/651] ASoC: samsung: odroid: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczla3ka.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/odroid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 40ac12c07145..ab3398f39f4a 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c @@ -180,7 +180,7 @@ static struct snd_soc_dai_link odroid_card_dais[] = { .no_pcm = 1, .playback_only = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(mixer), }, { /* Secondary FE <-> BE link */ From 3f97e52562dd1ad041f63c910a746eab695f40c1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:00 +0000 Subject: [PATCH 354/651] ASoC: samsung: arndale: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyf5a3k7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/arndale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/arndale.c b/sound/soc/samsung/arndale.c index 9619f550608c..172943bb3b24 100644 --- a/sound/soc/samsung/arndale.c +++ b/sound/soc/samsung/arndale.c @@ -95,7 +95,7 @@ static struct snd_soc_dai_link arndale_rt5631_dai[] = { .stream_name = "Primary", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBS_CFS, + | SND_SOC_DAIFMT_CBC_CFC, .ops = &arndale_rt5631_ops, SND_SOC_DAILINK_REG(rt5631_hifi), }, @@ -112,7 +112,7 @@ static struct snd_soc_dai_link arndale_wm1811_dai[] = { .stream_name = "Primary", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ops = &arndale_wm1811_ops, SND_SOC_DAILINK_REG(wm1811_hifi), }, From 9ef6a439bc987753b7e5af5a926f05debe82bd1c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:04 +0000 Subject: [PATCH 355/651] ASoC: samsung: lowland: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjupa3k3.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/lowland.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 702cb4cc1ce9..2cb19f4b9dad 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c @@ -105,7 +105,7 @@ static struct snd_soc_dai_link lowland_dai[] = { .name = "CPU", .stream_name = "CPU", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .init = lowland_wm5100_init, SND_SOC_DAILINK_REG(cpu), }, @@ -113,7 +113,7 @@ static struct snd_soc_dai_link lowland_dai[] = { .name = "Baseband", .stream_name = "Baseband", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, SND_SOC_DAILINK_REG(baseband), }, @@ -121,7 +121,7 @@ static struct snd_soc_dai_link lowland_dai[] = { .name = "Sub Speaker", .stream_name = "Sub Speaker", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, .c2c_params = &sub_params, .num_c2c_params = 1, From 3d5f026256d985e8b81e7657a5430a9ff14e651c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:07 +0000 Subject: [PATCH 356/651] ASoC: samsung: speyside: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5a9a3k0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/speyside.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 79476e8eb680..64d3e4ea66b0 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -210,7 +210,7 @@ static struct snd_soc_dai_link speyside_dai[] = { .stream_name = "CPU-DSP", .init = speyside_wm0010_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(cpu_dsp), }, { @@ -218,7 +218,7 @@ static struct snd_soc_dai_link speyside_dai[] = { .stream_name = "DSP-CODEC", .init = speyside_wm8996_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .c2c_params = &dsp_codec_params, .num_c2c_params = 1, .ignore_suspend = 1, @@ -228,7 +228,7 @@ static struct snd_soc_dai_link speyside_dai[] = { .name = "Baseband", .stream_name = "Baseband", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, SND_SOC_DAILINK_REG(baseband), }, From 29664312a75e47f989ad32e43682746d8681a02b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:11 +0000 Subject: [PATCH 357/651] ASoC: samsung: tobermory: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qpta3jx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/tobermory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 2bdd81bf821a..39a8c129dfdb 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c @@ -119,7 +119,7 @@ static struct snd_soc_dai_link tobermory_dai[] = { .name = "CPU", .stream_name = "CPU", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ops = &tobermory_ops, SND_SOC_DAILINK_REG(cpu), }, From 1455b3857ca2d05966005f7172210f6bd00048c3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:14 +0000 Subject: [PATCH 358/651] ASoC: samsung: tm2_wm5110: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c5da3jt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/tm2_wm5110.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c index 2417b91a328f..db853833f0d4 100644 --- a/sound/soc/samsung/tm2_wm5110.c +++ b/sound/soc/samsung/tm2_wm5110.c @@ -451,21 +451,21 @@ static struct snd_soc_dai_link tm2_dai_links[] = { .stream_name = "HiFi Primary", .ops = &tm2_aif1_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(aif1), }, { .name = "WM5110 Voice", .stream_name = "Voice call", .ops = &tm2_aif2_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, SND_SOC_DAILINK_REG(voice), }, { .name = "WM5110 BT", .stream_name = "Bluetooth", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, SND_SOC_DAILINK_REG(bt), }, { @@ -473,7 +473,7 @@ static struct snd_soc_dai_link tm2_dai_links[] = { .stream_name = "i2s1", .ops = &tm2_hdmi_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(hdmi), } }; From 2c4a2b5d084b06e1a9fd2e85866b51f6118dd254 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:18 +0000 Subject: [PATCH 359/651] ASoC: samsung: littlemill: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/875xkxa3jq.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/littlemill.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index c5260e101c2a..b32ce027be8e 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c @@ -157,7 +157,7 @@ static struct snd_soc_dai_link littlemill_dai[] = { .name = "CPU", .stream_name = "CPU", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ops = &littlemill_ops, SND_SOC_DAILINK_REG(cpu), }, @@ -165,7 +165,7 @@ static struct snd_soc_dai_link littlemill_dai[] = { .name = "Baseband", .stream_name = "Baseband", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, .c2c_params = &baseband_params, .num_c2c_params = 1, From 795aad6b179de4c3f68b18132bd183931d09c462 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:21 +0000 Subject: [PATCH 360/651] ASoC: samsung: smdk_wm8994: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/874j0ha3jn.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm8994.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index def92cc09f9c..acb29cd785a9 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -106,14 +106,14 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Pri_Dai", .init = smdk_wm8994_init_paiftx, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ops = &smdk_ops, SND_SOC_DAILINK_REG(aif1), }, { /* Sec_Fifo Playback i/f */ .name = "Sec_FIFO TX", .stream_name = "Sec_Dai", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ops = &smdk_ops, SND_SOC_DAILINK_REG(fifo_tx), }, From 697c58941c0a0d1a5ea3f323cf0231018d3ec4b3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:24 +0000 Subject: [PATCH 361/651] ASoC: samsung: aries_wm8994: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/8734g1a3jj.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/aries_wm8994.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c index 01716df0c842..3723329b266d 100644 --- a/sound/soc/samsung/aries_wm8994.c +++ b/sound/soc/samsung/aries_wm8994.c @@ -474,7 +474,7 @@ static struct snd_soc_dai_link aries_dai[] = { .name = "WM8994 AIF1", .stream_name = "HiFi", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .ops = &aries_ops, SND_SOC_DAILINK_REG(aif1), }, @@ -510,13 +510,13 @@ static struct snd_soc_card aries_card = { }; static const struct aries_wm8994_variant fascinate4g_variant = { - .modem_dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS + .modem_dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_IB_NF, .has_fm_radio = false, }; static const struct aries_wm8994_variant aries_variant = { - .modem_dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM + .modem_dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBP_CFP | SND_SOC_DAIFMT_IB_NF, .has_fm_radio = true, }; From 22bbcab0a2a100827a26833b7cab16ae8b1a3f9e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:27 +0000 Subject: [PATCH 362/651] ASoC: samsung: midas_wm1811: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/871pvla3jg.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/midas_wm1811.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/midas_wm1811.c b/sound/soc/samsung/midas_wm1811.c index bbfe5fef59af..239e958b88d3 100644 --- a/sound/soc/samsung/midas_wm1811.c +++ b/sound/soc/samsung/midas_wm1811.c @@ -537,7 +537,7 @@ static struct snd_soc_dai_link midas_dai[] = { .stream_name = "HiFi Primary", .ops = &midas_aif1_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(wm1811_hifi), }, { .name = "WM1811 Voice", From cc8e22b6b1622f44654a9ce70c1285c15c1b8414 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:31 +0000 Subject: [PATCH 363/651] ASoC: samsung: smdk_wm8994pcm: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87zfi98oyx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm8994pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index 5802f92ab8ba..a3f539fbde5f 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c @@ -99,7 +99,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .name = "WM8994 PAIF PCM", .stream_name = "Primary PCM", .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &smdk_wm8994_pcm_ops, SND_SOC_DAILINK_REG(paif_pcm), }, From 862123a0a41647bd130a2d0edefc76a52dc8b8f8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:34 +0000 Subject: [PATCH 364/651] ASoC: mediatek: mt2701-wm8960: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87y0xt8oyt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt2701/mt2701-wm8960.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt2701/mt2701-wm8960.c b/sound/soc/mediatek/mt2701/mt2701-wm8960.c index 2814f0570928..84b3d6cd77a5 100644 --- a/sound/soc/mediatek/mt2701/mt2701-wm8960.c +++ b/sound/soc/mediatek/mt2701/mt2701-wm8960.c @@ -83,7 +83,7 @@ static struct snd_soc_dai_link mt2701_wm8960_dai_links[] = { { .name = "wm8960-codec", .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_GATED, .ops = &mt2701_wm8960_be_ops, SND_SOC_DAILINK_REG(codec), From b1f5886cca25a6957b5541031376e2c06c5bd621 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:38 +0000 Subject: [PATCH 365/651] ASoC: mediatek: mt2701-cs42448: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmdd8oyp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt2701/mt2701-cs42448.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/mediatek/mt2701/mt2701-cs42448.c b/sound/soc/mediatek/mt2701/mt2701-cs42448.c index 00a79867235d..778a9dccfcaa 100644 --- a/sound/soc/mediatek/mt2701/mt2701-cs42448.c +++ b/sound/soc/mediatek/mt2701/mt2701-cs42448.c @@ -266,7 +266,7 @@ static struct snd_soc_dai_link mt2701_cs42448_dai_links[] = { [DAI_LINK_BE_I2S0] = { .name = "mt2701-cs42448-I2S0", .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_GATED, .ops = &mt2701_cs42448_be_ops, SND_SOC_DAILINK_REG(be_i2s0), @@ -274,7 +274,7 @@ static struct snd_soc_dai_link mt2701_cs42448_dai_links[] = { [DAI_LINK_BE_I2S1] = { .name = "mt2701-cs42448-I2S1", .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_GATED, .ops = &mt2701_cs42448_be_ops, SND_SOC_DAILINK_REG(be_i2s1), @@ -282,7 +282,7 @@ static struct snd_soc_dai_link mt2701_cs42448_dai_links[] = { [DAI_LINK_BE_I2S2] = { .name = "mt2701-cs42448-I2S2", .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_GATED, .ops = &mt2701_cs42448_be_ops, SND_SOC_DAILINK_REG(be_i2s2), @@ -290,7 +290,7 @@ static struct snd_soc_dai_link mt2701_cs42448_dai_links[] = { [DAI_LINK_BE_I2S3] = { .name = "mt2701-cs42448-I2S3", .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_GATED, .ops = &mt2701_cs42448_be_ops, SND_SOC_DAILINK_REG(be_i2s3), From c709a876b7de676d49b00b624b37d208e452cc7e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:42 +0000 Subject: [PATCH 366/651] ASoC: mediatek: mt7986-wm8960: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7sx8oyl.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt7986/mt7986-wm8960.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt7986/mt7986-wm8960.c b/sound/soc/mediatek/mt7986/mt7986-wm8960.c index c3d1e2eeb0e5..f1dc18222be7 100644 --- a/sound/soc/mediatek/mt7986/mt7986-wm8960.c +++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c @@ -63,7 +63,7 @@ static struct snd_soc_dai_link mt7986_wm8960_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS | + SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_GATED, SND_SOC_DAILINK_REG(codec), }, From d8c808af2a9bf731f72fcb772cf22886c6d00d99 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:46 +0000 Subject: [PATCH 367/651] ASoC: mediatek: mt7986-dai-etdm: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8h8oyh.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt7986/mt7986-dai-etdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c b/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c index d57971413a04..fc55ff47b7bc 100644 --- a/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c +++ b/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c @@ -348,10 +348,10 @@ static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: etdm_data->slave_mode = true; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: etdm_data->slave_mode = false; break; default: From eeb25b3ca1ef57d57906295d829febbd30cf4d8d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:50 +0000 Subject: [PATCH 368/651] ASoC: mediatek: mt8173-rt5650: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87seo18oyd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-rt5650.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c index 59c19fdd8675..7d6a3586cdd5 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c @@ -235,7 +235,7 @@ static struct snd_soc_dai_link mt8173_rt5650_dais[] = { .no_pcm = 1, .init = mt8173_rt5650_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &mt8173_rt5650_ops, .ignore_pmdown_time = 1, SND_SOC_DAILINK_REG(codec), From 47c59833c42a99bd27826f4f369bf4bb433c7ff9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:38:55 +0000 Subject: [PATCH 369/651] ASoC: mediatek: mt8173-max98090: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87r03l8oy8.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-max98090.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c index 0724564cee6a..49ebb67c818a 100644 --- a/sound/soc/mediatek/mt8173/mt8173-max98090.c +++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c @@ -122,7 +122,7 @@ static struct snd_soc_dai_link mt8173_max98090_dais[] = { .init = mt8173_max98090_init, .ops = &mt8173_max98090_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(hifi), }, }; From b73c2719c951868efc15181269a3caeb99157f29 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:01 +0000 Subject: [PATCH 370/651] ASoC: mediatek: mt8173-rt5650-rt5676: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87plj58oy2.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c index 488f2314dbf7..a1ba5df87e1e 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c @@ -197,7 +197,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { .no_pcm = 1, .init = mt8173_rt5650_rt5676_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &mt8173_rt5650_rt5676_ops, .ignore_pmdown_time = 1, SND_SOC_DAILINK_REG(codec), @@ -214,7 +214,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { .stream_name = "rt5650_rt5676 intercodec", .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, SND_SOC_DAILINK_REG(intercodec), }, }; From 522f5021cfb5a74e9b7aa3cbf365471f7a564c0a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:05 +0000 Subject: [PATCH 371/651] ASoC: mediatek: mt8173-rt5650-rt5514: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6yp8oxy.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c index d8e4e70d834c..dc063d85e62f 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c @@ -156,7 +156,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5514_dais[] = { .no_pcm = 1, .init = mt8173_rt5650_rt5514_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ops = &mt8173_rt5650_rt5514_ops, .ignore_pmdown_time = 1, SND_SOC_DAILINK_REG(codec), From 711035c043b3a5116860b3a25d808572f70e1dc1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:08 +0000 Subject: [PATCH 372/651] ASoC: mediatek: mt8183-da7219-max98357: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mse98oxv.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c index 1d8881e0a361..3388e076ccc9 100644 --- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c @@ -563,7 +563,7 @@ static struct snd_soc_dai_link mt8183_da7219_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_IF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .playback_only = 1, .ignore_suspend = 1, .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, From e33d0569d7a1d041e37fb93094e70807856531c2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:12 +0000 Subject: [PATCH 373/651] ASoC: mediatek: mt8183-mt6358-ts3a227-max98357: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldtt8oxs.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c index 6267c8554c15..497a9043be7b 100644 --- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c @@ -575,7 +575,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_IF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .playback_only = 1, .ignore_suspend = 1, .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, @@ -783,7 +783,7 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) strcmp(dai_link->name, "I2S3") == 0) dai_link->dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM; + SND_SOC_DAIFMT_CBP_CFP; } if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) { From 38cc5b0bed6c57367dca3725d01857fa0876899a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:15 +0000 Subject: [PATCH 374/651] ASoC: mediatek: mt8186-mt6366: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jz9d8oxo.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-mt6366.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366.c b/sound/soc/mediatek/mt8186/mt8186-mt6366.c index a5ef913743d4..43546012cf61 100644 --- a/sound/soc/mediatek/mt8186/mt8186-mt6366.c +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366.c @@ -875,7 +875,7 @@ static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_IF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .playback_only = 1, .ignore_suspend = 1, .init = mt8186_mt6366_rt1019_rt5682s_hdmi_init, From d4ee06219f2fffb71e2a23fc5060fdd3c7bb2cf7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:19 +0000 Subject: [PATCH 375/651] ASoC: mediatek: mt8192-mt6359-rt1015-rt5682: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ikox8oxk.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c index b1598cc5587e..bf483a8fb34a 100644 --- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c @@ -920,7 +920,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAIFMT_CBP_CFP, .playback_only = 1, .ignore_suspend = 1, .be_hw_params_fixup = mt8192_i2s_hw_params_fixup, From cb1ebf6e20371208c49d59615bf4b46d92991fc4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:22 +0000 Subject: [PATCH 376/651] ASoC: mediatek: mt8195-mt6359: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87h64h8oxh.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8195/mt8195-mt6359.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c index 2b9cb3248795..df29a9fa5aee 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c @@ -1114,7 +1114,7 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .capture_only = 1, SND_SOC_DAILINK_REG(ETDM1_IN_BE), }, @@ -1123,7 +1123,7 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .capture_only = 1, .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, SND_SOC_DAILINK_REG(ETDM2_IN_BE), @@ -1133,7 +1133,7 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .playback_only = 1, .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, SND_SOC_DAILINK_REG(ETDM1_OUT_BE), @@ -1143,7 +1143,7 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .playback_only = 1, SND_SOC_DAILINK_REG(ETDM2_OUT_BE), }, @@ -1152,7 +1152,7 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .playback_only = 1, SND_SOC_DAILINK_REG(ETDM3_OUT_BE), }, @@ -1161,7 +1161,7 @@ static struct snd_soc_dai_link mt8195_mt6359_dai_links[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(PCM1_BE), }, [DAI_LINK_UL_SRC1_BE] = { From db9912ce99c346c948c8fa774c0afc7d80d0ec20 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:26 +0000 Subject: [PATCH 377/651] ASoC: mediatek: mt8365-mt6357: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87frk18oxe.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8365/mt8365-mt6357.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt8365/mt8365-mt6357.c b/sound/soc/mediatek/mt8365/mt8365-mt6357.c index 9f28d6bf0323..a998fba82bfe 100644 --- a/sound/soc/mediatek/mt8365/mt8365-mt6357.c +++ b/sound/soc/mediatek/mt8365/mt8365-mt6357.c @@ -225,7 +225,7 @@ static struct snd_soc_dai_link mt8365_mt6357_dais[] = { .id = DAI_LINK_2ND_I2S_INTF, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(i2s3), }, [DAI_LINK_DMIC] = { From 9002421ebb1409e2f47062722aad598b561cf9eb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:29 +0000 Subject: [PATCH 378/651] ASoC: mediatek: mt8365-dai-i2s: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87eczl8oxa.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8365/mt8365-dai-i2s.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c b/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c index 11b9a5bc7163..cae51756cead 100644 --- a/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c +++ b/sound/soc/mediatek/mt8365/mt8365-dai-i2s.c @@ -313,7 +313,7 @@ static int mt8365_dai_set_config(struct mtk_base_afe *afe, } if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == - SND_SOC_DAIFMT_CBM_CFM) { + SND_SOC_DAIFMT_CBP_CFP) { val |= AFE_I2S_CON_SRC_SLAVE; val &= ~(u32)AFE_I2S_CON_FROM_IO_MUX;//from consys } @@ -523,7 +523,7 @@ static int mt8365_dai_i2s_startup(struct snd_pcm_substream *substream, bool i2s_in_slave = (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == - SND_SOC_DAIFMT_CBM_CFM); + SND_SOC_DAIFMT_CBP_CFP); mt8365_afe_enable_main_clk(afe); @@ -551,7 +551,7 @@ static void mt8365_dai_i2s_shutdown(struct snd_pcm_substream *substream, bool i2s_in_slave = (substream->stream == SNDRV_PCM_STREAM_CAPTURE) && ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) == - SND_SOC_DAIFMT_CBM_CFM); + SND_SOC_DAIFMT_CBP_CFP); if (be->prepared[substream->stream]) { if (reset_i2s_out_change) @@ -613,7 +613,7 @@ static int mt8365_dai_i2s_prepare(struct snd_pcm_substream *substream, if (apply_i2s_in_change) { if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) - == SND_SOC_DAIFMT_CBM_CFM) { + == SND_SOC_DAIFMT_CBP_CFP) { ret = mt8365_afe_set_2nd_i2s_asrc(afe, 32000, rate, (unsigned int)bit_width, 0, 0, 1); @@ -659,7 +659,7 @@ static int mt8365_dai_i2s_prepare(struct snd_pcm_substream *substream, mt8365_dai_set_enable(afe, i2s_data, true, true); if ((be->fmt_mode & SND_SOC_DAIFMT_MASTER_MASK) - == SND_SOC_DAIFMT_CBM_CFM) + == SND_SOC_DAIFMT_CBP_CFP) mt8365_afe_set_2nd_i2s_asrc_enable(afe, true); be->prepared[SNDRV_PCM_STREAM_CAPTURE] = true; @@ -712,7 +712,7 @@ static int mt8365_afe_2nd_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) be->fmt_mode |= (fmt & SND_SOC_DAIFMT_INV_MASK); - if (((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)) + if (((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBP_CFP)) be->fmt_mode |= (fmt & SND_SOC_DAIFMT_MASTER_MASK); return 0; From 0526b0b88c3092e38ba2d05f480b66bd5a1e1004 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:33 +0000 Subject: [PATCH 379/651] ASoC: mediatek: mt8365-dai-pcm: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87cyf58ox6.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8365/mt8365-dai-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c index 3373b88da28e..0ec114a566ad 100644 --- a/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c +++ b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c @@ -189,10 +189,10 @@ static int mt8365_dai_pcm1_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: pcm_priv->slave_mode = true; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: pcm_priv->slave_mode = false; break; default: From 99239dc5147ea4678e871e5c9d068a36f154558b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:37 +0000 Subject: [PATCH 380/651] ASoC: rockchip: rk3288_hdmi_analog: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87bjup8ox3.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rk3288_hdmi_analog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c index a65d923d94dc..ffbc5a39b493 100644 --- a/sound/soc/rockchip/rk3288_hdmi_analog.c +++ b/sound/soc/rockchip/rk3288_hdmi_analog.c @@ -148,7 +148,7 @@ static struct snd_soc_dai_link rk_dailink = { .ops = &rk_ops, /* Set codecs as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(audio), }; From 8410a099c88d1d720c9780b0ed716e544ea5a6d2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:40 +0000 Subject: [PATCH 381/651] ASoC: rockchip: rk3399_gru_sound: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87a5a98owz.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rk3399_gru_sound.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index 6c89c7331229..c8137e8883c4 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c @@ -338,7 +338,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = { .stream_name = "DP PCM", .init = rockchip_sound_cdndp_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(cdndp), }, [DAILINK_DA7219] = { @@ -348,7 +348,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = { .ops = &rockchip_sound_da7219_ops, /* set da7219 as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(da7219), }, [DAILINK_DMIC] = { @@ -356,7 +356,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = { .stream_name = "DMIC PCM", .ops = &rockchip_sound_dmic_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(dmic), }, [DAILINK_MAX98357A] = { @@ -365,7 +365,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = { .ops = &rockchip_sound_max98357a_ops, /* set max98357a as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(max98357a), }, [DAILINK_RT5514] = { @@ -374,7 +374,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = { .ops = &rockchip_sound_rt5514_ops, /* set rt5514 as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(rt5514), }, /* RT5514 DSP for voice wakeup via spi bus */ From edca7ad57c50483ec81ab5b74ff1d71dca62e5cb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:44 +0000 Subject: [PATCH 382/651] ASoC: rockchip: rockchip_max98090: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/878qpt8owv.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_max98090.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c index 783956dc83b5..b8326e9143b6 100644 --- a/sound/soc/rockchip/rockchip_max98090.c +++ b/sound/soc/rockchip/rockchip_max98090.c @@ -247,7 +247,7 @@ static struct snd_soc_dai_link rk_max98090_dailinks[] = { .ops = &rk_aif1_ops, /* set max98090 as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(analog), }, }; @@ -260,7 +260,7 @@ static struct snd_soc_dai_link rk_hdmi_dailinks[] = { .init = rk_hdmi_init, .ops = &rk_aif1_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(hdmi), } }; @@ -274,7 +274,7 @@ static struct snd_soc_dai_link rk_max98090_hdmi_dailinks[] = { .ops = &rk_aif1_ops, /* set max98090 as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(analog), }, [DAILINK_HDMI] = { @@ -283,7 +283,7 @@ static struct snd_soc_dai_link rk_max98090_hdmi_dailinks[] = { .init = rk_hdmi_init, .ops = &rk_aif1_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(hdmi), } }; From 7370a8fe5bd211042610ec200dcc83de5ccc50cd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:47 +0000 Subject: [PATCH 383/651] ASoC: rockchip: rockchip_rt5645: use inclusive language for SND_SOC_DAIFMT_CBx_CFx In SND_SOC_DAIFMT_CBx_CFx, M/S are no longer used. use P/C. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/877c5d8ows.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_rt5645.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_rt5645.c b/sound/soc/rockchip/rockchip_rt5645.c index b085d80ea2e4..590b64b362f6 100644 --- a/sound/soc/rockchip/rockchip_rt5645.c +++ b/sound/soc/rockchip/rockchip_rt5645.c @@ -145,7 +145,7 @@ static struct snd_soc_dai_link rk_dailink = { .ops = &rk_aif1_ops, /* set rt5645 as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, SND_SOC_DAILINK_REG(pcm), }; From 0f68f56ab7be101fc949177774107769e63f13e9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 26 Feb 2025 01:39:54 +0000 Subject: [PATCH 384/651] ASoC: soc-dai: remove SND_SOC_DAIFMT_CB{MS}_CF{MS} No drivers are using SND_SOC_DAIFMT_CB{MS}_CF{MS}. Let's remove it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/875xkx8owm.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index a11501752637..c3a3ba4b0bb7 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -118,12 +118,6 @@ struct snd_compr_stream; #define SND_SOC_DAIFMT_CBP_CFC (3 << 12) /* codec clk provider & frame consumer */ #define SND_SOC_DAIFMT_CBC_CFC (4 << 12) /* codec clk consumer & frame consumer */ -/* previous definitions kept for backwards-compatibility, do not use in new contributions */ -#define SND_SOC_DAIFMT_CBM_CFM SND_SOC_DAIFMT_CBP_CFP -#define SND_SOC_DAIFMT_CBS_CFM SND_SOC_DAIFMT_CBC_CFP -#define SND_SOC_DAIFMT_CBM_CFS SND_SOC_DAIFMT_CBP_CFC -#define SND_SOC_DAIFMT_CBS_CFS SND_SOC_DAIFMT_CBC_CFC - /* when passed to set_fmt directly indicate if the device is provider or consumer */ #define SND_SOC_DAIFMT_BP_FP SND_SOC_DAIFMT_CBP_CFP #define SND_SOC_DAIFMT_BC_FP SND_SOC_DAIFMT_CBC_CFP From 22e5c40fda71d0b6cdf83af9418403808d5d06bd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 18 Feb 2025 01:14:47 +0000 Subject: [PATCH 385/651] ASoC: audio-graph-card2-custom-sample1.dtsi: Separate Sample DT audio-graph-card2-custom-sample has many sample connections, but because ALSA card has number limition for links, it is impossible to have all samples into 1 ASoC card. Separate it and took the normal connection part. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87wmdo9hq0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- .../audio-graph-card2-custom-sample1.dtsi | 396 ++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 sound/soc/generic/audio-graph-card2-custom-sample1.dtsi diff --git a/sound/soc/generic/audio-graph-card2-custom-sample1.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample1.dtsi new file mode 100644 index 000000000000..12d40e05de46 --- /dev/null +++ b/sound/soc/generic/audio-graph-card2-custom-sample1.dtsi @@ -0,0 +1,396 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * audio-graph-card2-custom-sample1.dtsi + * + * Copyright (C) 2020 Renesas Electronics Corp. + * Copyright (C) 2020 Kuninori Morimoto + * + * This sample indicates how to use audio-graph-card2 and its + * custom driver. "audio-graph-card2-custom-sample" is the custome driver + * which is using audio-graph-card2. + * + * You can easily use this sample by adding below line on your DT file, + * and add new CONFIG to your .config. + * + * #include "../../../../../sound/soc/generic/audio-graph-card2-custom-sample1.dtsi" + * + * CONFIG_SND_AUDIO_GRAPH_CARD2 + * CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE + * CONFIG_SND_TEST_COMPONENT + * + * + * You can indicate more detail each device behavior as debug if you modify + * "compatible" on each test-component. see below + * + * test_cpu { + * - compatible = "test-cpu"; + * + compatible = "test-cpu-verbose"; + * ... + * }; + * + * test_codec { + * - compatible = "test-codec"; + * + compatible = "test-codec-verbose"; + * ... + * }; + * + * + * Below sample doesn't use "format" property, + * because test-component driver (test-cpu/test-codec) is supporting + * snd_soc_dai_ops :: .auto_selectable_formats. + * see + * snd_soc_runtime_get_dai_fmt() + * linux/sound/soc/generic/test-component.c :: test_dai_formats + */ +/ { + audio-graph-card2-custom-sample-1 { + /* + * You can use audio-graph-card2 directly by using + * + * compatible = "audio-graph-card2"; + */ + compatible = "audio-graph-card2-custom-sample"; + label = "card2-custom-sample-1"; + + /* + * @ : used at links + */ + links = < + /* + * + * [Normal] + * + * + * cpu1_0 <-@-----> codec1_0 + */ + &cpu1_0 /* CPU side only */ + + /* + * [Semi-Multi] + * + * CPU:Codec = 1:N + * + * +-+ + * cpu1_1 <--@---->| |-> codec1_1 + * | |-> codec1_2 + * +-+ + */ + &sm /* CPU side only */ + + /* + * [Multi-CPU/Codec-A] + * + * +-+ +-+ + * cpu1_2 <-| |<---@------>| |-> codec1_3 + * cpu1_3 <-| | | |-> codec1_4 + * +-+ +-+ + */ + &mcpuA /* CPU side only */ + + /* + * [Multi-CPU/Codec-B] + * + * +-+ +-+ + * | |<---@------>| | + * | | | | + * cpu1_4 <-| |<---------->| |-> codec1_5 + * cpu1_5 <-| |<---+------>| |-> codec1_6 + * +-+ \----->| |-> codec1_7 + * +-+ + */ + &mcpuB /* CPU side only */ + + /* + * [Multi-CPU/Codec-C] + * + * +-+ +-+ + * | |<---@------>| | + * | | | | + * cpu1_6 <-| |<---------->| |-> codec1_8 + * cpu1_7 <-| |<-----+---->| |-> codec1_9 + * cpu1_8 <-| |<----/ +-+ + * +-+ + */ + &mcpuC /* CPU side only */ + >; + + multi { + #address-cells = <1>; + #size-cells = <0>; + + /* + * [Semi-Multi] + * + * +---+ + * cpu1_1 <---@--->|X A|-> codec1_1 + * | B|-> codec1_2 + * +---+ + */ + ports@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + port@0 { reg = <0>; smcodec_ep: endpoint { remote-endpoint = <&cpu1_1_ep>; };};/* (X) to pair */ + port@1 { reg = <1>; smcodec_A_ep: endpoint { remote-endpoint = <&codec1_1_ep>; };};/* (A) Multi Element */ + port@2 { reg = <2>; smcodec_B_ep: endpoint { remote-endpoint = <&codec1_2_ep>; };};/* (B) Multi Element */ + }; + + /* + * [Multi-CPU-A] + * + * +---+ +---+ + * cpu1_2 <-|A X|<---@---->|x a|-> codec1_3 + * cpu1_3 <-|B | | b|-> codec1_4 + * +---+ +---+ + */ + ports@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mcpuA: port@0 { reg = <0>; mcpu_A_ep: endpoint { remote-endpoint = <&mcodec_A_ep>; };}; /* (X) to pair */ + port@1 { reg = <1>; mcpu_AA_ep: endpoint { remote-endpoint = <&cpu1_2_ep>; };}; /* (A) Multi Element */ + port@2 { reg = <2>; mcpu_AB_ep: endpoint { remote-endpoint = <&cpu1_3_ep>; };}; /* (B) Multi Element */ + }; + + /* + * [Multi-Codec-A] + * + * +---+ +---+ + * cpu1_2 <-|A X|<-@------>|x a|-> codec1_3 + * cpu1_3 <-|B | | b|-> codec1_4 + * +---+ +---+ + */ + ports@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + port@0 { reg = <0>; mcodec_A_ep: endpoint { remote-endpoint = <&mcpu_A_ep>; };}; /* (x) to pair */ + port@1 { reg = <1>; mcodec_Aa_ep: endpoint { remote-endpoint = <&codec1_3_ep>; };}; /* (a) Multi Element */ + port@2 { reg = <2>; mcodec_Ab_ep: endpoint { remote-endpoint = <&codec1_4_ep>; };}; /* (b) Multi Element */ + }; + + /* + * [Multi-CPU-B] + * + * +---+ +---+ + * | X|<---@---->|x | + * | | | | + * cpu1_4 <-|A 1|<-------->|3 a|-> codec1_5 + * cpu1_5 <-|B 2|<---+---->|4 b|-> codec1_6 + * +---+ \--->|5 c|-> codec1_7 + * +---+ + */ + ports@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + mcpuB: port@0 { + reg = <0>; + mcpu_BX_ep: endpoint { remote-endpoint = <&mcodec_Bx_ep>; }; /* (X) to pair */ + }; + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + mcpu_BA_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_4_ep>; }; /* (A) Multi Element */ + mcpu_B1_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_B3_ep>; }; /* (1) connected Codec */ + }; + port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + mcpu_BB_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_5_ep>; }; /* (B) Multi Element */ + mcpu_B2_0_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_B4_ep>; }; /* (2) connected Codec */ + mcpu_B2_1_ep: endpoint@2 { reg = <2>; remote-endpoint = <&mcodec_B5_ep>; }; /* (2) connected Codec */ + }; + }; + + /* + * [Multi-Codec-B] + * + * +---+ +---+ + * | X|<-@------>|x | + * | | | | + * cpu1_4 <-|A 1|<-------->|3 a|-> codec1_5 + * cpu1_5 <-|B 2|<---+---->|4 b|-> codec1_6 + * +---+ \--->|5 c|-> codec1_7 + * +---+ + */ + ports@4 { + reg = <4>; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + mcodec_Bx_ep: endpoint { remote-endpoint = <&mcpu_BX_ep>; }; /* (x) to pair */ + }; + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + mcodec_Ba_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_5_ep>;}; /* (a) Multi Element */ + mcodec_B3_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_B1_ep>; }; /* (3) connected CPU */ + }; + port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + mcodec_Bb_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_6_ep>; }; /* (b) Multi Element */ + mcodec_B4_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_B2_0_ep>;}; /* (4) connected CPU */ + }; + port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + mcodec_Bc_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_7_ep>; }; /* (c) Multi Element */ + mcodec_B5_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_B2_1_ep>;}; /* (5) connected CPU */ + }; + }; + + /* + * [Multi-CPU-C] + * + * +---+ +---+ + * | X|<-@------>|x | + * | | | | + * cpu1_6 <-|A 1|<-------->|4 a|-> codec1_8 + * cpu1_7 <-|B 2|<-----+-->|5 b|-> codec1_9 + * cpu1_8 <-|C 3|<----/ +---+ + * +---+ + */ + ports@5 { + reg = <5>; + #address-cells = <1>; + #size-cells = <0>; + mcpuC: port@0 { + reg = <0>; + mcpu_CX_ep: endpoint { remote-endpoint = <&mcodec_Cx_ep>; }; /* (X) to pair */ + }; + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + mcpu_CA_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_6_ep>; }; /* (A) Multi Element */ + mcpu_C1_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_C4_ep>; }; /* (1) connected Codec */ + }; + port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + mcpu_CB_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_7_ep>; }; /* (B) Multi Element */ + mcpu_C2_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_C5_0_ep>; }; /* (2) connected Codec */ + }; + port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + mcpu_CC_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu1_8_ep>; }; /* (C) Multi Element */ + mcpu_C3_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec_C5_1_ep>; }; /* (3) connected Codec */ + }; + }; + + /* + * [Multi-Codec-C] + * + * +---+ +---+ + * | X|<-@------>|x | + * | | | | + * cpu1_6 <-|A 1|<-------->|4 a|-> codec1_8 + * cpu1_7 <-|B 2|<-----+-->|5 b|-> codec1_9 + * cpu1_8 <-|C 3|<----/ +---+ + * +---+ + */ + ports@6 { + reg = <6>; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + mcodec_Cx_ep: endpoint { remote-endpoint = <&mcpu_CX_ep>; }; /* (x) to pair */ + }; + port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + mcodec_Ca_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_8_ep>;}; /* (a) Multi Element */ + mcodec_C4_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_C1_ep>; }; /* (4) connected CPU */ + }; + port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + mcodec_Cb_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec1_9_ep>;}; /* (b) Multi Element */ + mcodec_C5_0_ep: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu_C2_ep>; }; /* (5) connected CPU */ + mcodec_C5_1_ep: endpoint@2 { reg = <2>; remote-endpoint = <&mcpu_C3_ep>; }; /* (5) connected CPU */ + }; + }; + }; + }; + + test_cpu_1 { + /* + * update compatible to indicate more detail behaviour + * if you want. see test-compatible for more detail. + * + * ex) + * - compatible = "test-cpu"; + * + compatible = "test-cpu-verbose"; + */ + compatible = "test-cpu"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + bitclock-master; + frame-master; + + /* [Normal] */ + cpu1_0: port@0 { reg = <0>; cpu1_0_ep: endpoint { remote-endpoint = <&codec1_0_ep>;}; }; + /* [Semi-Multi] */ + sm: port@1 { reg = <1>; cpu1_1_ep: endpoint { remote-endpoint = <&smcodec_ep>; }; }; + /* [Multi-CPU-A] */ + port@2 { reg = <2>; cpu1_2_ep: endpoint { remote-endpoint = <&mcpu_AA_ep>; }; }; + port@3 { reg = <3>; cpu1_3_ep: endpoint { remote-endpoint = <&mcpu_AB_ep>; }; }; + /* [Multi-CPU-B] */ + port@4 { reg = <4>; cpu1_4_ep: endpoint { remote-endpoint = <&mcpu_BA_ep>; }; }; + port@5 { reg = <5>; cpu1_5_ep: endpoint { remote-endpoint = <&mcpu_BB_ep>; }; }; + /* [Multi-CPU-C] */ + port@6 { reg = <6>; cpu1_6_ep: endpoint { remote-endpoint = <&mcpu_CA_ep>; }; }; + port@7 { reg = <7>; cpu1_7_ep: endpoint { remote-endpoint = <&mcpu_CB_ep>; }; }; + port@8 { reg = <8>; cpu1_8_ep: endpoint { remote-endpoint = <&mcpu_CC_ep>; }; }; + }; + }; + + test_codec_1 { + /* + * update compatible to indicate more detail behaviour + * if you want. see test-compatible for more detail. + * + * ex) + * - compatible = "test-codec"; + * + compatible = "test-codec-verbose"; + */ + compatible = "test-codec"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* [Normal] */ + port@0 { reg = <0>; codec1_0_ep: endpoint { remote-endpoint = <&cpu1_0_ep>; }; }; + /* [Semi-Multi] */ + port@1 { reg = <1>; codec1_1_ep: endpoint { remote-endpoint = <&smcodec_A_ep>; }; }; + port@2 { reg = <2>; codec1_2_ep: endpoint { remote-endpoint = <&smcodec_B_ep>; }; }; + /* [Multi-Codec-0] */ + port@3 { reg = <3>; codec1_3_ep: endpoint { remote-endpoint = <&mcodec_Aa_ep>; }; }; + port@4 { reg = <4>; codec1_4_ep: endpoint { remote-endpoint = <&mcodec_Ab_ep>; }; }; + /* [Multi-Codec-1] */ + port@5 { reg = <5>; codec1_5_ep: endpoint { remote-endpoint = <&mcodec_Ba_ep>; }; }; + port@6 { reg = <6>; codec1_6_ep: endpoint { remote-endpoint = <&mcodec_Bb_ep>; }; }; + port@7 { reg = <7>; codec1_7_ep: endpoint { remote-endpoint = <&mcodec_Bc_ep>; }; }; + /* [Multi-Codec-2] */ + port@8 { reg = <8>; codec1_8_ep: endpoint { remote-endpoint = <&mcodec_Ca_ep>; }; }; + port@9 { reg = <9>; codec1_9_ep: endpoint { remote-endpoint = <&mcodec_Cb_ep>; }; }; + }; + }; +}; From 7c0572197faf3b6d6b27271455e76ac8ba84c43f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 18 Feb 2025 01:14:54 +0000 Subject: [PATCH 386/651] ASoC: audio-graph-card2-custom-sample2.dtsi: Separate Sample DT audio-graph-card2-custom-sample has many sample connections, but because ALSA card has number limition for links, it is impossible to have all samples into 1 ASoC card. Separate it and took DPCM / Codec2Codec connection part. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87v7t89hpt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- .../audio-graph-card2-custom-sample2.dtsi | 382 ++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 sound/soc/generic/audio-graph-card2-custom-sample2.dtsi diff --git a/sound/soc/generic/audio-graph-card2-custom-sample2.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample2.dtsi new file mode 100644 index 000000000000..1fb061a10ab1 --- /dev/null +++ b/sound/soc/generic/audio-graph-card2-custom-sample2.dtsi @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * audio-graph-card2-custom-sample2.dtsi + * + * Copyright (C) 2020 Renesas Electronics Corp. + * Copyright (C) 2020 Kuninori Morimoto + * + * This sample indicates how to use audio-graph-card2 and its + * custom driver. "audio-graph-card2-custom-sample" is the custome driver + * which is using audio-graph-card2. + * + * You can easily use this sample by adding below line on your DT file, + * and add new CONFIG to your .config. + * + * #include "../../../../../sound/soc/generic/audio-graph-card2-custom-sample2.dtsi" + * + * CONFIG_SND_AUDIO_GRAPH_CARD2 + * CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE + * CONFIG_SND_TEST_COMPONENT + * + * + * You can indicate more detail each device behavior as debug if you modify + * "compatible" on each test-component. see below + * + * test_cpu { + * - compatible = "test-cpu"; + * + compatible = "test-cpu-verbose"; + * ... + * }; + * + * test_codec { + * - compatible = "test-codec"; + * + compatible = "test-codec-verbose"; + * ... + * }; + * + * + * Below sample doesn't use "format" property, + * because test-component driver (test-cpu/test-codec) is supporting + * snd_soc_dai_ops :: .auto_selectable_formats. + * see + * snd_soc_runtime_get_dai_fmt() + * linux/sound/soc/generic/test-component.c :: test_dai_formats + */ +/ { + audio-graph-card2-custom-sample-2 { + /* + * You can use audio-graph-card2 directly by using + * + * compatible = "audio-graph-card2"; + */ + compatible = "audio-graph-card2-custom-sample"; + label = "card2-custom-sample-2"; + + /* for [DPCM] */ + /* BE FE */ + routing = "TC DAI0 Playback", "DAI0 Playback", + "TC DAI0 Playback", "DAI1 Playback", + "DAI0 Capture", "TC DAI0 Capture", + "DAI1 Capture", "TC DAI0 Capture", + /* for [DPCM-Multi] */ + /* BE FE */ + "TC DAI1 Playback", "DAI2 Playback", + "TC DAI2 Playback", "DAI2 Playback", + "TC DAI1 Playback", "DAI3 Playback", + "TC DAI2 Playback", "DAI3 Playback", + "DAI2 Capture", "TC DAI1 Capture", + "DAI2 Capture", "TC DAI2 Capture", + "DAI3 Capture", "TC DAI1 Capture", + "DAI3 Capture", "TC DAI2 Capture", + /* for [Codec2Codec] */ + "TC OUT", "TC DAI4 Playback", + "TC DAI3 Capture", "TC IN", + /* for [Codec2Codec-Multi] */ + "TC OUT", "TC DAI7 Playback", + "TC DAI5 Capture", "TC IN", + "TC OUT", "TC DAI8 Playback", + "TC DAI6 Capture", "TC IN"; + + /* + * @ : used at links + */ + links = < + /* + * [DPCM] + * + * cpu20/cpu21 are converting rate to 44.1kHz + * + * FE BE + * **** + * cpu2_0 <----@---* *------@---> codec2_0 (44.1kHz) + * cpu2_1 <----@---* * + * **** + */ + &feA &feB &beA /* both FE / BE */ + + /* + * [DPCM-Multi] + * + * FE BE + * **** +-+ + * cpu2_2 <----@---* *------@---> | | -> codec2_1 + * cpu2_3 <----@---* * | | -> codec2_2 + * **** +-+ + */ + &feC &feD &beB /* both FE / BE*/ + + /* + * [Codec2Codec] + * + * + * +-@-> codec2_3 + * | + * +---> codec2_4 + */ + &c2c /* CPU side only */ + + /* + * [Codec2Codec-Multi] + * + * --NOTE-- + * Multi connect N:M is not supported by ASoC. + * + * +-+ + * +---@-->| |-> codec2_5 + * | | |-> codec2_6 + * | +-+ + * | +-+ + * +------>| |-> codec2_7 + * | |-> codec2_8 + * +-+ + */ + &c2c_m /* CPU side only */ + >; + + multi { + #address-cells = <1>; + #size-cells = <0>; + + /* + * [DPCM-Multi]::BE + * + * FE BE + * **** +---+ + * cpu2_2 <----@---* *------@---> |x a| -> codec2_1 + * cpu2_3 <----@---* * | b| -> codec2_2 + * **** +---+ + */ + ports@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + port@0 { reg = <0>; mbe_x_ep: endpoint { remote-endpoint = <&beB_ep>; };};/* (x) to pair */ + port@1 { reg = <1>; mbe_a_ep: endpoint { remote-endpoint = <&codec2_1_ep>; };};/* (a) Multi Element */ + port@2 { reg = <2>; mbe_b_ep: endpoint { remote-endpoint = <&codec2_2_ep>; };};/* (b) Multi Element */ + }; + + /* + * [Codec2Codec-Multi]::CPU + * + * c2cmf +---+ + * +---@---------->|X A|-> codec2_5 + * | | B|-> codec2_6 + * | +---+ + * | c2cmb +---+ + * +-------------->|x a|-> codec2_7 + * | b|-> codec2_8 + * +---+ + */ + ports@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + port@0 { reg = <0>; mc2c0X_ep: endpoint { remote-endpoint = <&c2cmf_ep>; };};/* (X) to pair */ + port@1 { reg = <1>; mc2c0A_ep: endpoint { remote-endpoint = <&codec2_5_ep>; };};/* (A) Multi Element */ + port@2 { reg = <2>; mc2c0B_ep: endpoint { remote-endpoint = <&codec2_6_ep>; };};/* (B) Multi Element */ + }; + + /* + * [Codec2Codec-Multi]::Codec + * + * c2cmf +---+ + * +---@---------->|X A|-> codec2_5 + * | | B|-> codec2_6 + * | +---+ + * | c2cmb +---+ + * +-------------->|x a|-> codec2_7 + * | b|-> codec2_8 + * +---+ + */ + ports@4 { + reg = <4>; + #address-cells = <1>; + #size-cells = <0>; + port@0 { reg = <0>; mc2c1x_ep: endpoint { remote-endpoint = <&c2cmb_ep>; };};/* (x) to pair */ + port@1 { reg = <1>; mc2c1a_ep: endpoint { remote-endpoint = <&codec2_7_ep>; };};/* (a) Multi Element */ + port@2 { reg = <2>; mc2c1b_ep: endpoint { remote-endpoint = <&codec2_8_ep>; };};/* (b) Multi Element */ + }; + }; + + dpcm { + #address-cells = <1>; + #size-cells = <0>; + + /* FE part */ + ports@0 { + reg = <0>; + + #address-cells = <1>; + #size-cells = <0>; + /* + * [DPCM]::FE + * + * FE BE + * **** + * cpu2_0 <----@---* *------@---> codec2_0 (44.1kHz) + * cpu2_1 <----@---* * + * **** + */ + feA: port@0 { reg = <0>; feA_ep: endpoint { remote-endpoint = <&cpu2_0_ep>; }; }; + feB: port@1 { reg = <1>; feB_ep: endpoint { remote-endpoint = <&cpu2_1_ep>; }; }; + + /* + * [DPCM-Multi]::FE + * + * FE BE + * **** +-+ + * cpu2_2 <----@---* *------@---> | | -> codec2_1 + * cpu2_3 <----@---* * | | -> codec2_2 + * **** +-+ + */ + feC: port@2 { reg = <2>; feC_ep: endpoint { remote-endpoint = <&cpu2_2_ep>; }; }; + feD: port@3 { reg = <3>; feD_ep: endpoint { remote-endpoint = <&cpu2_3_ep>; }; }; + }; + + /* BE part */ + ports@1 { + reg = <1>; + + #address-cells = <1>; + #size-cells = <0>; + /* + * [DPCM]::BE + * + * FE BE + * **** + * cpu2_0 <----@---* *------@---> codec2_0 (44.1kHz) + * cpu2_1 <----@---* * + * **** + */ + beA: port@0 { reg = <0>; beA_ep: endpoint { remote-endpoint = <&codec2_0_ep>; }; }; + + /* + * [DPCM-Multi]::BE + * + * FE BE + * **** +-------+ + * cpu2_2 <----@---* *------@---> |mbe_x | -> codec2_1 + * cpu2_3 <----@---* * | | -> codec2_2 + * **** +-------+ + */ + beB: port@1 { reg = <1>; beB_ep: endpoint { remote-endpoint = <&mbe_x_ep>; }; }; + }; + }; + + codec2codec { + #address-cells = <1>; + #size-cells = <0>; + /* + * [Codec2Codec] + * + * + * +-@--> codec2_3 + * | + * +----> codec2_4 + */ + ports@0 { + reg = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + /* use default settings */ + c2c: port@0 { reg = <0>; c2cf_ep: endpoint { remote-endpoint = <&codec2_3_ep>; }; }; + port@1 { reg = <1>; c2cb_ep: endpoint { remote-endpoint = <&codec2_4_ep>; }; }; + }; + + /* + * [Codec2Codec-Multi] + * + * c2cmf +--------+ + * +---@---------->|mc2c0X |-> codec2_5 + * | | |-> codec2_6 + * | +--------+ + * | c2cmb +--------+ + * +-------------->|mc2c1x |-> codec2_7 + * | |-> codec2_8 + * +--------+ + */ + ports@1 { + reg = <1>; + + #address-cells = <1>; + #size-cells = <0>; + + /* use original settings */ + rate = <48000>; + c2c_m: port@0 { reg = <0>; c2cmf_ep: endpoint { remote-endpoint = <&mc2c0X_ep>; }; }; + port@1 { reg = <1>; c2cmb_ep: endpoint { remote-endpoint = <&mc2c1x_ep>; }; }; + }; + }; + }; + + test_cpu_2 { + /* + * update compatible to indicate more detail behaviour + * if you want. see test-compatible for more detail. + * + * ex) + * - compatible = "test-cpu"; + * + compatible = "test-cpu-verbose"; + */ + compatible = "test-cpu"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + bitclock-master; + frame-master; + + /* [DPCM]::FE */ + port@0 { reg = <0>; cpu2_0_ep: endpoint { remote-endpoint = <&feA_ep>; };}; + port@1 { reg = <1>; cpu2_1_ep: endpoint { remote-endpoint = <&feB_ep>; };}; + /* [DPCM-Multi]::FE */ + port@2 { reg = <2>; cpu2_2_ep: endpoint { remote-endpoint = <&feC_ep>; };}; + port@3 { reg = <3>; cpu2_3_ep: endpoint { remote-endpoint = <&feD_ep>; };}; + }; + }; + + test_codec_2 { + /* + * update compatible to indicate more detail behaviour + * if you want. see test-compatible for more detail. + * + * ex) + * - compatible = "test-codec"; + * + compatible = "test-codec-verbose"; + */ + compatible = "test-codec"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* + * prefix can be added to *component*, + * see audio-graph-card2::routing + */ + prefix = "TC"; + + /* [DPCM]::BE */ + port@0 { + convert-rate = <44100>; + reg = <0>; codec2_0_ep: endpoint { remote-endpoint = <&beA_ep>; }; + }; + /* [DPCM-Multi]::BE */ + port@1 { reg = <1>; codec2_1_ep: endpoint { remote-endpoint = <&mbe_a_ep>; };}; + port@2 { reg = <2>; codec2_2_ep: endpoint { remote-endpoint = <&mbe_b_ep>; };}; + /* [Codec2Codec] */ + port@3 { bitclock-master; + frame-master; + reg = <3>; codec2_3_ep: endpoint { remote-endpoint = <&c2cf_ep>; };}; + port@4 { reg = <4>; codec2_4_ep: endpoint { remote-endpoint = <&c2cb_ep>; };}; + /* [Codec2Codec-Multi] */ + port@5 { bitclock-master; + frame-master; + reg = <5>; codec2_5_ep: endpoint { remote-endpoint = <&mc2c0A_ep>; };}; + port@6 { reg = <6>; codec2_6_ep: endpoint { remote-endpoint = <&mc2c0B_ep>; };}; + port@7 { reg = <7>; codec2_7_ep: endpoint { remote-endpoint = <&mc2c1a_ep>; };}; + port@8 { reg = <8>; codec2_8_ep: endpoint { remote-endpoint = <&mc2c1b_ep>; };}; + }; + }; +}; From 7d73a1beaa9428ed4da7786725fcb1a20fd371ab Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 18 Feb 2025 01:14:58 +0000 Subject: [PATCH 387/651] ASoC: audio-graph-card2-custom-sample.dtsi: remove original sample audio-graph-card2-custom-sample has many sample connections, but because ALSA card has number limition for links, it is impossible to have all samples into 1 ASoC card. The sample is separated into 2 samples. Remove original sample. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt8s9hpp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- .../audio-graph-card2-custom-sample.dtsi | 702 ------------------ 1 file changed, 702 deletions(-) delete mode 100644 sound/soc/generic/audio-graph-card2-custom-sample.dtsi diff --git a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample.dtsi deleted file mode 100644 index 9efd31206c9b..000000000000 --- a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi +++ /dev/null @@ -1,702 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * audio-graph-card2-custom-sample.dtsi - * - * Copyright (C) 2020 Renesas Electronics Corp. - * Copyright (C) 2020 Kuninori Morimoto - * - * This sample indicates how to use audio-graph-card2 and its - * custom driver. "audio-graph-card2-custom-sample" is the custome driver - * which is using audio-graph-card2. - * - * You can easily use this sample by adding below line on your DT file, - * and add new CONFIG to your .config. - * - * #include "../../../../../sound/soc/generic/audio-graph-card2-custom-sample.dtsi" - * - * CONFIG_SND_AUDIO_GRAPH_CARD2 - * CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE - * CONFIG_SND_TEST_COMPONENT - * - * - * You can indicate more detail each device behavior as debug if you modify - * "compatible" on each test-component. see below - * - * test_cpu { - * - compatible = "test-cpu"; - * + compatible = "test-cpu-verbose"; - * ... - * }; - * - * test_codec { - * - compatible = "test-codec"; - * + compatible = "test-codec-verbose"; - * ... - * }; - * - * - * Below sample doesn't use "format" property, - * because test-component driver (test-cpu/test-codec) is supporting - * snd_soc_dai_ops :: .auto_selectable_formats. - * see - * snd_soc_runtime_get_dai_fmt() - * linux/sound/soc/generic/test-component.c :: test_dai_formats - */ -/ { - /* - * @ : used at links - * - * [Normal] - * cpu0 <-@-----------------> codec0 - * - * [Semi-Multi] - * - * CPU:Codec = 1:N - * - * +-+ - * cpu7 <-@------->| |-> codec12 - * | |-> codec13 - * +-+ - * - * [Multi-CPU/Codec-0] - * +-+ +-+ - * cpu1 <--| |<-@--------->| |-> codec1 - * cpu2 <--| | | |-> codec2 - * +-+ +-+ - * - * [Multi-CPU/Codec-1] - * - * +-+ +-+ - * | |<-@--------->| | - * | | | | - * cpu8 <--| |<----------->| |-> codec14 - * cpu9 <--| |<---+------->| |-> codec15 - * +-+ \------>| |-> codec16 - * +-+ - * - * [Multi-CPU/Codec-2] - * - * +-+ +-+ - * | |<-@--------->| | - * | | | | - * cpu10 <-| |<----------->| |-> codec17 - * cpu11 <-| |<-----+----->| |-> codec18 - * cpu12 <-| |<----/ +-+ - * +-+ - * - * [DPCM] - * - * CPU3/CPU4 are converting rate to 44100 - * - * FE BE - * **** - * cpu3 <-@--* *--@-> codec3 - * cpu4 <-@--* * (44.1kHz) - * **** - * - * [DPCM-Multi] - * - * --NOTE-- - * Multi-FE is not supported by ASoC. - * - * FE BE - * **** +-+ - * cpu5 <-@--* *--@-> | | -> codec4 - * cpu6 <-@--* * | | -> codec5 - * **** +-+ - * - * [Codec2Codec] - * +-@-> codec6 - * | - * +---> codec7 - * - * [Codec2Codec-Multi] - * - * --NOTE-- - * Multi connect N:M is not supported by ASoC. - * - * +-+ - * +-@->| |-> codec8 - * | | |-> codec9 - * | +-+ - * | +-+ - * +--->| |-> codec10 - * | |-> codec11 - * +-+ - */ - audio-graph-card2-custom-sample { - /* - * You can use audio-graph-card2 directly by using - * - * compatible = "audio-graph-card2"; - */ - compatible = "audio-graph-card2-custom-sample"; - - /* for [DPCM] */ - /* BE FE */ - routing = "TC DAI3 Playback", "DAI3 Playback", - "TC DAI3 Playback", "DAI4 Playback", - "DAI3 Capture", "TC DAI3 Capture", - "DAI4 Capture", "TC DAI3 Capture", - /* for [DPCM-Multi] */ - /* BE FE */ - "TC DAI4 Playback", "DAI5 Playback", - "TC DAI5 Playback", "DAI5 Playback", - "TC DAI4 Playback", "DAI6 Playback", - "TC DAI5 Playback", "DAI6 Playback", - "DAI5 Capture", "TC DAI4 Capture", - "DAI5 Capture", "TC DAI5 Capture", - "DAI6 Capture", "TC DAI4 Capture", - "DAI6 Capture", "TC DAI5 Capture", - /* for [Codec2Codec] */ - "TC OUT", "TC DAI7 Playback", - "TC DAI6 Capture", "TC IN", - /* for [Codec2Codec-Multi] */ - "TC OUT", "TC DAI10 Playback", - "TC DAI8 Capture", "TC IN", - "TC OUT", "TC DAI11 Playback", - "TC DAI9 Capture", "TC IN"; - - links = < - /* - * [Normal]: cpu side only - * cpu0/codec0 - */ - &cpu0 - - /* - * [Semi-Multi] - * cpu7/codec12/codec13 - */ - &sm0 - - /* - * [Multi-CPU/Codec-0]: cpu side only - * cpu1/cpu2/codec1/codec2 - */ - &mcpu0 - - /* - * [Multi-CPU/Codec-1]: cpu side only - * cpu8/cpu9/codec14/codec15/codec16 - * - * Because it will reach to the maximum of sound minor number, - * disable it so far. - * If you want to try it, please disable some other one instead. - */ - //&mcpu1 - - /* - * [Multi-CPU/Codec-2]: cpu side only - * cpu10/cpu11/cpu12/codec17/codec18 - * - * Because it will reach to the maximum of sound minor number, - * disable it so far. - * If you want to try it, please disable some other one instead. - */ - //&mcpu2 - - /* - * [DPCM]: both FE / BE - * cpu3/cpu4/codec3 - */ - &fe00 &fe01 &be0 - - /* - * [DPCM-Multi]: both FE / BE - * cpu5/cpu6/codec4/codec5 - */ - &fe10 &fe11 &be1 - - /* - * [Codec2Codec]: cpu side only - * codec6/codec7 - */ - &c2c - - /* - * [Codec2Codec-Multi]: cpu side only - * codec8/codec9/codec10/codec11 - */ - &c2c_m - >; - - multi { - #address-cells = <1>; - #size-cells = <0>; - - /* - * [Multi-CPU-0] - * - * +---+ +---+ - * cpu1 <--|A X|<-@------->|x a|-> codec1 - * cpu2 <--|B | | b|-> codec2 - * +---+ +---+ - */ - ports@0 { - reg = <0>; - #address-cells = <1>; - #size-cells = <0>; - mcpu0: port@0 { reg = <0>; mcpu00_ep: endpoint { remote-endpoint = <&mcodec00_ep>; };};/* (X) to pair */ - port@1 { reg = <1>; mcpu01_ep: endpoint { remote-endpoint = <&cpu1_ep>; };};/* (A) Multi Element */ - port@2 { reg = <2>; mcpu02_ep: endpoint { remote-endpoint = <&cpu2_ep>; };};/* (B) Multi Element */ - }; - - /* - * [Multi-Codec-0] - * - * +---+ +---+ - * cpu1 <--|A X|<-@------->|x a|-> codec1 - * cpu2 <--|B | | b|-> codec2 - * +---+ +---+ - */ - ports@1 { - reg = <1>; - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; mcodec00_ep: endpoint { remote-endpoint = <&mcpu00_ep>; };};/* (x) to pair */ - port@1 { reg = <1>; mcodec01_ep: endpoint { remote-endpoint = <&codec1_ep>; };};/* (a) Multi Element */ - port@2 { reg = <2>; mcodec02_ep: endpoint { remote-endpoint = <&codec2_ep>; };};/* (b) Multi Element */ - }; - - /* - * [DPCM-Multi]::BE - * - * FE BE - * **** +---+ - * cpu5 <-@--* *-----@--->|x a|-> codec4 - * cpu6 <-@--* * | b|-> codec5 - * **** +---+ - */ - ports@2 { - reg = <2>; - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; mbe_ep: endpoint { remote-endpoint = <&be10_ep>; };};/* (x) to pair */ - port@1 { reg = <1>; mbe1_ep: endpoint { remote-endpoint = <&codec4_ep>; };};/* (a) Multi Element */ - port@2 { reg = <2>; mbe2_ep: endpoint { remote-endpoint = <&codec5_ep>; };};/* (b) Multi Element */ - }; - - /* - * [Codec2Codec-Multi]::CPU - * - * +---+ - * +-@->|X A|-> codec8 - * | | B|-> codec9 - * | +---+ - * | +---+ - * +--->|x a|-> codec10 - * | b|-> codec11 - * +---+ - */ - ports@3 { - reg = <3>; - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; mc2c0_ep: endpoint { remote-endpoint = <&c2cmf_ep>; };};/* (X) to pair */ - port@1 { reg = <1>; mc2c00_ep: endpoint { remote-endpoint = <&codec8_ep>; };};/* (A) Multi Element */ - port@2 { reg = <2>; mc2c01_ep: endpoint { remote-endpoint = <&codec9_ep>; };};/* (B) Multi Element */ - }; - - /* - * [Codec2Codec-Multi]::Codec - * - * +---+ - * +-@->|X A|-> codec8 - * | | B|-> codec9 - * | +---+ - * | +---+ - * +--->|x a|-> codec10 - * | b|-> codec11 - * +---+ - */ - ports@4 { - reg = <4>; - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; mc2c1_ep: endpoint { remote-endpoint = <&c2cmb_ep>; };};/* (x) to pair */ - port@1 { reg = <1>; mc2c10_ep: endpoint { remote-endpoint = <&codec10_ep>; };};/* (a) Multi Element */ - port@2 { reg = <2>; mc2c11_ep: endpoint { remote-endpoint = <&codec11_ep>; };};/* (b) Multi Element */ - }; - - /* - * [Semi-Multi] - * - * +---+ - * cpu7 <-@------->|X A|-> codec12 - * | B|-> codec13 - * +---+ - */ - ports@5 { - reg = <5>; - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; smcodec0_ep: endpoint { remote-endpoint = <&cpu7_ep>; };};/* (X) to pair */ - port@1 { reg = <1>; smcodec1_ep: endpoint { remote-endpoint = <&codec12_ep>; };};/* (A) Multi Element */ - port@2 { reg = <2>; smcodec2_ep: endpoint { remote-endpoint = <&codec13_ep>; };};/* (B) Multi Element */ - }; - - /* - * [Multi-CPU-1] - * - * +---+ +---+ - * | X|<-@------->|x | - * | | | | - * cpu8 <--|A 1|<--------->|3 a|-> codec14 - * cpu9 <--|B 2|<---+----->|4 b|-> codec15 - * +---+ \---->|5 c|-> codec16 - * +---+ - */ - ports@6 { - reg = <6>; - #address-cells = <1>; - #size-cells = <0>; - mcpu1: port@0 { reg = <0>; mcpu10_ep: endpoint { remote-endpoint = <&mcodec10_ep>; };}; /* (X) to pair */ - port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - mcpu11_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu8_ep>; }; /* (A) Multi Element */ - mcpu11_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec11_ep_0>; }; /* (1) connected Codec */ - }; - port@2 { - #address-cells = <1>; - #size-cells = <0>; - reg = <2>; - mcpu12_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu9_ep>; }; /* (B) Multi Element */ - mcpu12_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec12_ep_0>; }; /* (2) connected Codec */ - mcpu12_ep_1: endpoint@2 { reg = <2>; remote-endpoint = <&mcodec13_ep_0>; }; /* (2) connected Codec */ - }; - }; - - /* - * [Multi-Codec-1] - * - * +---+ +---+ - * | X|<-@------->|x | - * | | | | - * cpu8 <--|A 1|<--------->|3 a|-> codec14 - * cpu9 <--|B 2|<---+----->|4 b|-> codec15 - * +---+ \---->|5 c|-> codec16 - * +---+ - */ - ports@7 { - reg = <7>; - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; mcodec10_ep: endpoint { remote-endpoint = <&mcpu10_ep>; };}; /* (x) to pair */ - port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - mcodec11_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec14_ep>; }; /* (a) Multi Element */ - mcodec11_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu11_ep_0>; }; /* (3) connected CPU */ - }; - port@2 { - #address-cells = <1>; - #size-cells = <0>; - reg = <2>; - mcodec12_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec15_ep>; }; /* (b) Multi Element */ - mcodec12_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu12_ep_0>; }; /* (4) connected CPU */ - }; - port@3 { - #address-cells = <1>; - #size-cells = <0>; - reg = <3>; - mcodec13_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec16_ep>; }; /* (c) Multi Element */ - mcodec13_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu12_ep_1>; }; /* (5) connected CPU */ - }; - }; - - /* - * [Multi-CPU-2] - * - * +---+ +---+ - * | X|<-@------->|x | - * | | | | - * cpu10 <-|A 1|<--------->|4 a|-> codec17 - * cpu11 <-|B 2|<-----+--->|5 b|-> codec18 - * cpu12 <-|C 3|<----/ +---+ - * +---+ - */ - ports@8 { - reg = <8>; - #address-cells = <1>; - #size-cells = <0>; - mcpu2: port@0 { reg = <0>; mcpu20_ep: endpoint { remote-endpoint = <&mcodec20_ep>; };}; /* (X) to pair */ - port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - mcpu21_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu10_ep>; }; /* (A) Multi Element */ - mcpu21_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec21_ep_0>; }; /* (1) connected Codec */ - }; - port@2 { - #address-cells = <1>; - #size-cells = <0>; - reg = <2>; - mcpu22_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu11_ep>; }; /* (B) Multi Element */ - mcpu22_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec22_ep_0>; }; /* (2) connected Codec */ - }; - port@3 { - #address-cells = <1>; - #size-cells = <0>; - reg = <3>; - mcpu23_ep: endpoint@0 { reg = <0>; remote-endpoint = <&cpu12_ep>; }; /* (C) Multi Element */ - mcpu23_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcodec22_ep_1>; }; /* (3) connected Codec */ - }; - }; - - /* - * [Multi-Codec-2] - * - * +---+ +---+ - * | X|<-@------->|x | - * | | | | - * cpu10 <-|A 1|<--------->|4 a|-> codec17 - * cpu11 <-|B 2|<-----+--->|5 b|-> codec18 - * cpu12 <-|C 3|<----/ +---+ - * +---+ - */ - ports@9 { - reg = <9>; - #address-cells = <1>; - #size-cells = <0>; - port@0 { reg = <0>; mcodec20_ep: endpoint { remote-endpoint = <&mcpu20_ep>; };}; /* (x) to pair */ - port@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - mcodec21_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec17_ep>; }; /* (a) Multi Element */ - mcodec21_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu21_ep_0>; }; /* (4) connected CPU */ - }; - port@2 { - #address-cells = <1>; - #size-cells = <0>; - reg = <2>; - mcodec22_ep: endpoint@0 { reg = <0>; remote-endpoint = <&codec18_ep>; }; /* (b) Multi Element */ - mcodec22_ep_0: endpoint@1 { reg = <1>; remote-endpoint = <&mcpu22_ep_0>; }; /* (5) connected CPU */ - mcodec22_ep_1: endpoint@2 { reg = <2>; remote-endpoint = <&mcpu23_ep_0>; }; /* (5) connected CPU */ - }; - }; - }; - - dpcm { - #address-cells = <1>; - #size-cells = <0>; - - ports@0 { - reg = <0>; - - #address-cells = <1>; - #size-cells = <0>; - /* - * [DPCM]::FE - * - * FE BE - * **** - * cpu3 <-@(fe00)--* *--(be0)@--> codec3 - * cpu4 <-@(fe01)--* * (44.1kHz) - * **** - */ - fe00: port@0 { reg = <0>; fe00_ep: endpoint { remote-endpoint = <&cpu3_ep>; }; }; - fe01: port@1 { reg = <1>; fe01_ep: endpoint { remote-endpoint = <&cpu4_ep>; }; }; - - /* - * [DPCM-Multi]::FE - * - * FE BE - * **** +-+ - * cpu5 <-@(fe10)--* *---(be1)@-->| |-> codec4 - * cpu6 <-@(fe11)--* * | |-> codec5 - * **** +-+ - */ - fe10: port@2 { reg = <2>; fe10_ep: endpoint { remote-endpoint = <&cpu5_ep>; }; }; - fe11: port@3 { reg = <3>; fe11_ep: endpoint { remote-endpoint = <&cpu6_ep>; }; }; - }; - - ports@1 { - reg = <1>; - - #address-cells = <1>; - #size-cells = <0>; - /* - * [DPCM]::BE - * - * FE BE - * **** - * cpu3 <-@(fe00)--* *--(be0)@--> codec3 - * cpu4 <-@(fe01)--* * (44.1kHz) - * **** - */ - be0: port@0 { reg = <0>; be00_ep: endpoint { remote-endpoint = <&codec3_ep>; }; }; - - /* - * [DPCM-Multi]::BE - * - * FE BE - * **** +-+ - * cpu5 <-@(fe10)--* *---(be1)@-->| |-> codec4 - * cpu6 <-@(fe11)--* * | |-> codec5 - * **** +-+ - */ - be1: port@1 { reg = <1>; be10_ep: endpoint { remote-endpoint = <&mbe_ep>; }; }; - }; - }; - - codec2codec { - #address-cells = <1>; - #size-cells = <0>; - /* - * [Codec2Codec] - * - * +-@(c2c)-> codec6 - * | - * +--------> codec7 - */ - ports@0 { - reg = <0>; - - #address-cells = <1>; - #size-cells = <0>; - - /* use default settings */ - c2c: port@0 { reg = <0>; c2cf_ep: endpoint { remote-endpoint = <&codec6_ep>; }; }; - port@1 { reg = <1>; c2cb_ep: endpoint { remote-endpoint = <&codec7_ep>; }; }; - }; - - /* - * [Codec2Codec-Multi] - * - * +-+ - * +-@(c2c_m)-->| |-> codec8 - * | | |-> codec9 - * | +-+ - * | +-+ - * +----------->| |-> codec10 - * | |-> codec11 - * +-+ - */ - ports@1 { - reg = <1>; - - #address-cells = <1>; - #size-cells = <0>; - - /* use original settings */ - rate = <48000>; - c2c_m: port@0 { reg = <0>; c2cmf_ep: endpoint { remote-endpoint = <&mc2c0_ep>; }; }; - port@1 { reg = <1>; c2cmb_ep: endpoint { remote-endpoint = <&mc2c1_ep>; }; }; - }; - }; - }; - - test_cpu { - /* - * update compatible to indicate more detail behaviour - * if you want. see test-compatible for more detail. - * - * ex) - * - compatible = "test-cpu"; - * + compatible = "test-cpu-verbose"; - */ - compatible = "test-cpu"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - bitclock-master; - frame-master; - /* [Normal] */ - cpu0: port@0 { reg = <0>; cpu0_ep: endpoint { remote-endpoint = <&codec0_ep>; }; }; - - /* [Multi-CPU-0] */ - port@1 { reg = <1>; cpu1_ep: endpoint { remote-endpoint = <&mcpu01_ep>; }; }; - port@2 { reg = <2>; cpu2_ep: endpoint { remote-endpoint = <&mcpu02_ep>; }; }; - - /* [DPCM]::FE */ - port@3 { reg = <3>; cpu3_ep: endpoint { remote-endpoint = <&fe00_ep>; }; }; - port@4 { reg = <4>; cpu4_ep: endpoint { remote-endpoint = <&fe01_ep>; }; }; - - /* [DPCM-Multi]::FE */ - port@5 { reg = <5>; cpu5_ep: endpoint { remote-endpoint = <&fe10_ep>; }; }; - port@6 { reg = <6>; cpu6_ep: endpoint { remote-endpoint = <&fe11_ep>; }; }; - - /* [Semi-Multi] */ - sm0: port@7 { reg = <7>; cpu7_ep: endpoint { remote-endpoint = <&smcodec0_ep>; }; }; - - /* [Multi-CPU-1] */ - port@8 { reg = <8>; cpu8_ep: endpoint { remote-endpoint = <&mcpu11_ep>; }; }; - port@9 { reg = <9>; cpu9_ep: endpoint { remote-endpoint = <&mcpu12_ep>; }; }; - /* [Multi-CPU-2] */ - port@a { reg = <10>; cpu10_ep: endpoint { remote-endpoint = <&mcpu21_ep>; }; }; - port@b { reg = <11>; cpu11_ep: endpoint { remote-endpoint = <&mcpu22_ep>; }; }; - port@c { reg = <12>; cpu12_ep: endpoint { remote-endpoint = <&mcpu23_ep>; }; }; - }; - }; - - test_codec { - /* - * update compatible to indicate more detail behaviour - * if you want. see test-compatible for more detail. - * - * ex) - * - compatible = "test-codec"; - * + compatible = "test-codec-verbose"; - */ - compatible = "test-codec"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - /* - * prefix can be added to *component*, - * see audio-graph-card2::routing - */ - prefix = "TC"; - - /* [Normal] */ - port@0 { reg = <0>; codec0_ep: endpoint { remote-endpoint = <&cpu0_ep>; }; }; - - /* [Multi-Codec-0] */ - port@1 { reg = <1>; codec1_ep: endpoint { remote-endpoint = <&mcodec01_ep>; }; }; - port@2 { reg = <2>; codec2_ep: endpoint { remote-endpoint = <&mcodec02_ep>; }; }; - - /* [DPCM]::BE */ - port@3 { - convert-rate = <44100>; - reg = <3>; codec3_ep: endpoint { remote-endpoint = <&be00_ep>; }; - }; - - /* [DPCM-Multi]::BE */ - port@4 { reg = <4>; codec4_ep: endpoint { remote-endpoint = <&mbe1_ep>; }; }; - port@5 { reg = <5>; codec5_ep: endpoint { remote-endpoint = <&mbe2_ep>; }; }; - - /* [Codec2Codec] */ - port@6 { bitclock-master; - frame-master; - reg = <6>; codec6_ep: endpoint { remote-endpoint = <&c2cf_ep>; }; }; - port@7 { reg = <7>; codec7_ep: endpoint { remote-endpoint = <&c2cb_ep>; }; }; - - /* [Codec2Codec-Multi] */ - port@8 { bitclock-master; - frame-master; - reg = <8>; codec8_ep: endpoint { remote-endpoint = <&mc2c00_ep>; }; }; - port@9 { reg = <9>; codec9_ep: endpoint { remote-endpoint = <&mc2c01_ep>; }; }; - port@a { reg = <10>; codec10_ep: endpoint { remote-endpoint = <&mc2c10_ep>; }; }; - port@b { reg = <11>; codec11_ep: endpoint { remote-endpoint = <&mc2c11_ep>; }; }; - - /* [Semi-Multi] */ - port@c { reg = <12>; codec12_ep: endpoint { remote-endpoint = <&smcodec1_ep>; }; }; - port@d { reg = <13>; codec13_ep: endpoint { remote-endpoint = <&smcodec2_ep>; }; }; - - /* [Multi-Codec-1] */ - port@e { reg = <14>; codec14_ep: endpoint { remote-endpoint = <&mcodec11_ep>; }; }; - port@f { reg = <15>; codec15_ep: endpoint { remote-endpoint = <&mcodec12_ep>; }; }; - port@10 { reg = <16>; codec16_ep: endpoint { remote-endpoint = <&mcodec13_ep>; }; }; - /* [Multi-Codec-2] */ - port@11 { reg = <17>; codec17_ep: endpoint { remote-endpoint = <&mcodec21_ep>; }; }; - port@12 { reg = <18>; codec18_ep: endpoint { remote-endpoint = <&mcodec22_ep>; }; }; - }; - }; -}; From feb849404a8b677aa6760d1539acf597e4574337 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Sun, 23 Feb 2025 21:25:45 +0100 Subject: [PATCH 388/651] ASoC: SOF: Intel: hda-dai: Remove unnecessary bool conversion Remove the unnecessary bool conversion and simplify the code. Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20250223202547.1795-2-thorsten.blum@linux.dev Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index da12aabc1bb8..883d0d3bae9e 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -318,7 +318,7 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: ret = hda_link_dma_cleanup(substream, hext_stream, dai, - cmd == SNDRV_PCM_TRIGGER_STOP ? false : true); + cmd != SNDRV_PCM_TRIGGER_STOP); if (ret < 0) { dev_err(sdev->dev, "%s: failed to clean up link DMA\n", __func__); return ret; From a02c42d41af7d66db71ca43c52531c3253ebe35e Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Fri, 21 Feb 2025 03:21:41 +0000 Subject: [PATCH 389/651] ASoC: codecs: wsa883x: Implement temperature reading and hwmon Read temperature of the amplifier and expose it via hwmon interface, which will be later used during calibration of speaker protection algorithms. The method is the same as for wsa884x and therefore this is based on Krzysztof Kozlowski's approach implemented in commit 6b99dc62d940 ("ASoC: codecs: wsa884x: Implement temperature reading and hwmon"). Cc: Krzysztof Kozlowski Cc: Srinivas Kandagatla Cc: Steev Klimaszewski Signed-off-by: Alexey Klimov Tested-by: Steev Klimaszewski #Thinkpad X13s Link: https://patch.msgid.link/20250221032141.1206902-1-alexey.klimov@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 194 +++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 47da5674d7c9..a5a6cb90bb43 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -156,8 +157,28 @@ #define WSA883X_PA_FSM_ERR_COND (WSA883X_DIG_CTRL_BASE + 0x0014) #define WSA883X_PA_FSM_MSK (WSA883X_DIG_CTRL_BASE + 0x0015) #define WSA883X_PA_FSM_BYP (WSA883X_DIG_CTRL_BASE + 0x0016) +#define WSA883X_PA_FSM_BYP_DC_CAL_EN_MASK 0x01 +#define WSA883X_PA_FSM_BYP_DC_CAL_EN_SHIFT 0 +#define WSA883X_PA_FSM_BYP_CLK_WD_EN_MASK 0x02 +#define WSA883X_PA_FSM_BYP_CLK_WD_EN_SHIFT 1 +#define WSA883X_PA_FSM_BYP_BG_EN_MASK 0x04 +#define WSA883X_PA_FSM_BYP_BG_EN_SHIFT 2 +#define WSA883X_PA_FSM_BYP_BOOST_EN_MASK 0x08 +#define WSA883X_PA_FSM_BYP_BOOST_EN_SHIFT 3 +#define WSA883X_PA_FSM_BYP_PA_EN_MASK 0x10 +#define WSA883X_PA_FSM_BYP_PA_EN_SHIFT 4 +#define WSA883X_PA_FSM_BYP_D_UNMUTE_MASK 0x20 +#define WSA883X_PA_FSM_BYP_D_UNMUTE_SHIFT 5 +#define WSA883X_PA_FSM_BYP_SPKR_PROT_EN_MASK 0x40 +#define WSA883X_PA_FSM_BYP_SPKR_PROT_EN_SHIFT 6 +#define WSA883X_PA_FSM_BYP_TSADC_EN_MASK 0x80 +#define WSA883X_PA_FSM_BYP_TSADC_EN_SHIFT 7 #define WSA883X_PA_FSM_DBG (WSA883X_DIG_CTRL_BASE + 0x0017) #define WSA883X_TADC_VALUE_CTL (WSA883X_DIG_CTRL_BASE + 0x0020) +#define WSA883X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK 0x01 +#define WSA883X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_SHIFT 0 +#define WSA883X_TADC_VALUE_CTL_VBAT_VALUE_RD_EN_MASK 0x02 +#define WSA883X_TADC_VALUE_CTL_VBAT_VALUE_RD_EN_SHIFT 1 #define WSA883X_TEMP_DETECT_CTL (WSA883X_DIG_CTRL_BASE + 0x0021) #define WSA883X_TEMP_MSB (WSA883X_DIG_CTRL_BASE + 0x0022) #define WSA883X_TEMP_LSB (WSA883X_DIG_CTRL_BASE + 0x0023) @@ -427,6 +448,17 @@ SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) +/* Two-point trimming for temperature calibration */ +#define WSA883X_T1_TEMP -10L +#define WSA883X_T2_TEMP 150L + +/* + * Device will report senseless data in many cases, so discard any measurements + * outside of valid range. + */ +#define WSA883X_LOW_TEMP_THRESHOLD 5 +#define WSA883X_HIGH_TEMP_THRESHOLD 45 + struct wsa883x_priv { struct regmap *regmap; struct device *dev; @@ -441,6 +473,13 @@ struct wsa883x_priv { int active_ports; int dev_mode; int comp_offset; + /* + * Protects temperature reading code (related to speaker protection) and + * fields: temperature and pa_on. + */ + struct mutex sp_lock; + unsigned int temperature; + bool pa_on; }; enum { @@ -1186,6 +1225,10 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: + mutex_lock(&wsa883x->sp_lock); + wsa883x->pa_on = true; + mutex_unlock(&wsa883x->sp_lock); + switch (wsa883x->dev_mode) { case RECEIVER: snd_soc_component_write_field(component, WSA883X_CDC_PATH_MODE, @@ -1235,6 +1278,9 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, WSA883X_GLOBAL_PA_EN_MASK, 0); snd_soc_component_write_field(component, WSA883X_PDM_WD_CTL, WSA883X_PDM_EN_MASK, 0); + mutex_lock(&wsa883x->sp_lock); + wsa883x->pa_on = false; + mutex_unlock(&wsa883x->sp_lock); break; } return 0; @@ -1367,6 +1413,140 @@ static struct snd_soc_dai_driver wsa883x_dais[] = { }, }; +static int wsa883x_get_temp(struct wsa883x_priv *wsa883x, long *temp) +{ + unsigned int d1_msb = 0, d1_lsb = 0, d2_msb = 0, d2_lsb = 0; + unsigned int dmeas_msb = 0, dmeas_lsb = 0; + int d1, d2, dmeas; + unsigned int mask; + int ret, range; + long val; + + guard(mutex)(&wsa883x->sp_lock); + + if (wsa883x->pa_on) { + /* + * Reading temperature is possible only when Power Amplifier is + * off. Report last cached data. + */ + *temp = wsa883x->temperature * 1000; + return 0; + } + + ret = pm_runtime_resume_and_get(wsa883x->dev); + if (ret < 0) + return ret; + + mask = WSA883X_PA_FSM_BYP_DC_CAL_EN_MASK | + WSA883X_PA_FSM_BYP_CLK_WD_EN_MASK | + WSA883X_PA_FSM_BYP_BG_EN_MASK | + WSA883X_PA_FSM_BYP_D_UNMUTE_MASK | + WSA883X_PA_FSM_BYP_SPKR_PROT_EN_MASK | + WSA883X_PA_FSM_BYP_TSADC_EN_MASK; + + /* + * Here and further do not care about read or update failures. + * For example, before turning the amplifier on for the first + * time, reading WSA883X_TEMP_DIN_MSB will always return 0. + * Instead, check if returned value is within reasonable + * thresholds. + */ + regmap_update_bits(wsa883x->regmap, WSA883X_PA_FSM_BYP, mask, mask); + + regmap_update_bits(wsa883x->regmap, WSA883X_TADC_VALUE_CTL, + WSA883X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK, + FIELD_PREP(WSA883X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK, 0x0)); + + regmap_read(wsa883x->regmap, WSA883X_TEMP_MSB, &dmeas_msb); + regmap_read(wsa883x->regmap, WSA883X_TEMP_LSB, &dmeas_lsb); + + regmap_update_bits(wsa883x->regmap, WSA883X_TADC_VALUE_CTL, + WSA883X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK, + FIELD_PREP(WSA883X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK, 0x1)); + + regmap_read(wsa883x->regmap, WSA883X_OTP_REG_1, &d1_msb); + regmap_read(wsa883x->regmap, WSA883X_OTP_REG_2, &d1_lsb); + regmap_read(wsa883x->regmap, WSA883X_OTP_REG_3, &d2_msb); + regmap_read(wsa883x->regmap, WSA883X_OTP_REG_4, &d2_lsb); + + regmap_update_bits(wsa883x->regmap, WSA883X_PA_FSM_BYP, mask, 0x0); + + dmeas = (((dmeas_msb & 0xff) << 0x8) | (dmeas_lsb & 0xff)) >> 0x6; + d1 = (((d1_msb & 0xff) << 0x8) | (d1_lsb & 0xff)) >> 0x6; + d2 = (((d2_msb & 0xff) << 0x8) | (d2_lsb & 0xff)) >> 0x6; + + if (d1 == d2) { + /* Incorrect data in OTP? */ + ret = -EINVAL; + goto out; + } + + val = WSA883X_T1_TEMP + (((dmeas - d1) * (WSA883X_T2_TEMP - WSA883X_T1_TEMP)) / (d2 - d1)); + range = WSA883X_HIGH_TEMP_THRESHOLD - WSA883X_LOW_TEMP_THRESHOLD; + if (in_range(val, WSA883X_LOW_TEMP_THRESHOLD, range)) { + wsa883x->temperature = val; + *temp = val * 1000; + ret = 0; + } else { + ret = -EAGAIN; + } +out: + pm_runtime_mark_last_busy(wsa883x->dev); + pm_runtime_put_autosuspend(wsa883x->dev); + + return ret; +} + +static umode_t wsa883x_hwmon_is_visible(const void *data, + enum hwmon_sensor_types type, u32 attr, + int channel) +{ + if (type != hwmon_temp) + return 0; + + switch (attr) { + case hwmon_temp_input: + return 0444; + default: + break; + } + + return 0; +} + +static int wsa883x_hwmon_read(struct device *dev, + enum hwmon_sensor_types type, + u32 attr, int channel, long *temp) +{ + int ret; + + switch (attr) { + case hwmon_temp_input: + ret = wsa883x_get_temp(dev_get_drvdata(dev), temp); + break; + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static const struct hwmon_channel_info *const wsa883x_hwmon_info[] = { + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), + NULL +}; + +static const struct hwmon_ops wsa883x_hwmon_ops = { + .is_visible = wsa883x_hwmon_is_visible, + .read = wsa883x_hwmon_read, +}; + +static const struct hwmon_chip_info wsa883x_hwmon_chip_info = { + .ops = &wsa883x_hwmon_ops, + .info = wsa883x_hwmon_info, +}; + static int wsa883x_probe(struct sdw_slave *pdev, const struct sdw_device_id *id) { @@ -1402,6 +1582,7 @@ static int wsa883x_probe(struct sdw_slave *pdev, wsa883x->sconfig.bps = 1; wsa883x->sconfig.direction = SDW_DATA_DIR_RX; wsa883x->sconfig.type = SDW_STREAM_PDM; + mutex_init(&wsa883x->sp_lock); /** * Port map index starts with 0, however the data port for this codec @@ -1424,6 +1605,19 @@ static int wsa883x_probe(struct sdw_slave *pdev, "regmap_init failed\n"); goto err; } + + if (IS_REACHABLE(CONFIG_HWMON)) { + struct device *hwmon; + + hwmon = devm_hwmon_device_register_with_info(dev, "wsa883x", + wsa883x, + &wsa883x_hwmon_chip_info, + NULL); + if (IS_ERR(hwmon)) + return dev_err_probe(dev, PTR_ERR(hwmon), + "Failed to register hwmon sensor\n"); + } + pm_runtime_set_autosuspend_delay(dev, 3000); pm_runtime_use_autosuspend(dev); pm_runtime_mark_last_busy(dev); From abcb9a1fd89144536f3ef604f700e94424867366 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 26 Feb 2025 18:05:05 +0800 Subject: [PATCH 390/651] ASoC: dt-bindings: fsl,sai: Document audio graph port This device can be used in conjunction with audio-graph-card to provide an endpoint for binding with the other side of the audio link. Signed-off-by: Shengjiu Wang Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250226100508.2352568-2-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl,sai.yaml | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl,sai.yaml b/Documentation/devicetree/bindings/sound/fsl,sai.yaml index a5d9c246cc47..5c95508ee707 100644 --- a/Documentation/devicetree/bindings/sound/fsl,sai.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,sai.yaml @@ -93,6 +93,24 @@ properties: items: - description: receive and transmit interrupt + ports: + $ref: /schemas/graph.yaml#/properties/ports + properties: + port@0: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + description: port for TX and RX + + port@1: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + description: port for TX only + + port@2: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + description: port for RX only + big-endian: description: | required if all the SAI registers are big-endian rather than little-endian. @@ -204,4 +222,37 @@ examples: dma-names = "rx", "tx"; fsl,dataline = <1 0xff 0xff 2 0xff 0x11>; #sound-dai-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + playback-only; + + sai1_endpoint0: endpoint { + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <32>; + dai-tdm-slot-width-map = <32 8 32>; + dai-format = "dsp_a"; + bitclock-master; + frame-master; + remote-endpoint = <&mcodec01_ep>; + }; + }; + + port@2 { + reg = <2>; + capture-only; + + sai1_endpoint1: endpoint { + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <32>; + dai-tdm-slot-width-map = <32 8 32>; + dai-format = "dsp_a"; + remote-endpoint = <&fe02_ep>; + }; + }; + }; }; From 5fee78e517ce0765def9387659fc56a1d5532c60 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 26 Feb 2025 18:05:06 +0800 Subject: [PATCH 391/651] ASoC: dt-bindings: fsl,audmix: Document audio graph port This device can be used in conjunction with audio-graph-card to provide an endpoint for binding with the other side of the audio link. Signed-off-by: Shengjiu Wang Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250226100508.2352568-3-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl,audmix.yaml | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.yaml b/Documentation/devicetree/bindings/sound/fsl,audmix.yaml index 9413b901cf77..d3b93407b4f0 100644 --- a/Documentation/devicetree/bindings/sound/fsl,audmix.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,audmix.yaml @@ -61,6 +61,20 @@ properties: - description: serial audio input 2 maxItems: 1 + ports: + $ref: /schemas/graph.yaml#/properties/ports + patternProperties: + '^port@[0-1]': + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + description: Input port from SAI TX + + properties: + port@2: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + description: Output port to SAI RX + required: - compatible - reg @@ -80,4 +94,50 @@ examples: clock-names = "ipg"; power-domains = <&pd_audmix>; dais = <&sai4>, <&sai5>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + playback-only; + + amix_endpoint0: endpoint { + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <32>; + dai-tdm-slot-width-map = <32 8 32>; + dai-format = "dsp_a"; + remote-endpoint = <&be00_ep>; + }; + }; + + port@1 { + reg = <1>; + playback-only; + + amix_endpoint1: endpoint { + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <32>; + dai-tdm-slot-width-map = <32 8 32>; + dai-format = "dsp_a"; + remote-endpoint = <&be01_ep>; + }; + }; + + port@2 { + reg = <2>; + capture-only; + + amix_endpoint2: endpoint { + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <32>; + dai-tdm-slot-width-map = <32 8 32>; + dai-format = "dsp_a"; + bitclock-master; + frame-master; + remote-endpoint = <&be02_ep>; + }; + }; + }; }; From 597acf1a04bede55e3ad8a7922bba286c11112d3 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 26 Feb 2025 18:05:07 +0800 Subject: [PATCH 392/651] ASoC: dt-bindings: fsl,audmix: make 'dais' property to be optional Make 'dais' property to be optional. When there is no 'dais' property, driver won't register the card, dts should have audio graph card node for linking this device. Signed-off-by: Shengjiu Wang Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250226100508.2352568-4-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl,audmix.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.yaml b/Documentation/devicetree/bindings/sound/fsl,audmix.yaml index d3b93407b4f0..3ad197b3c82c 100644 --- a/Documentation/devicetree/bindings/sound/fsl,audmix.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,audmix.yaml @@ -81,7 +81,6 @@ required: - clocks - clock-names - power-domains - - dais unevaluatedProperties: false From 294a60e5e9830045c161181286d44ce669f88833 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 26 Feb 2025 18:05:08 +0800 Subject: [PATCH 393/651] ASoC: fsl_audmix: register card device depends on 'dais' property In order to make the audmix device linked by audio graph card, make 'dais' property to be optional. If 'dais' property exists, then register the imx-audmix card driver. otherwise, it should be linked by audio graph card. Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20250226100508.2352568-5-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_audmix.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c index 3cd9a66b70a1..7981d598ba13 100644 --- a/sound/soc/fsl/fsl_audmix.c +++ b/sound/soc/fsl/fsl_audmix.c @@ -488,11 +488,17 @@ static int fsl_audmix_probe(struct platform_device *pdev) goto err_disable_pm; } - priv->pdev = platform_device_register_data(dev, "imx-audmix", 0, NULL, 0); - if (IS_ERR(priv->pdev)) { - ret = PTR_ERR(priv->pdev); - dev_err(dev, "failed to register platform: %d\n", ret); - goto err_disable_pm; + /* + * If dais property exist, then register the imx-audmix card driver. + * otherwise, it should be linked by audio graph card. + */ + if (of_find_property(pdev->dev.of_node, "dais", NULL)) { + priv->pdev = platform_device_register_data(dev, "imx-audmix", 0, NULL, 0); + if (IS_ERR(priv->pdev)) { + ret = PTR_ERR(priv->pdev); + dev_err(dev, "failed to register platform: %d\n", ret); + goto err_disable_pm; + } } return 0; From c01a74844b74c584160d5253f794bbd2af015bec Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:12 +0000 Subject: [PATCH 394/651] ASoC: Remove unused helper macro SOC_SINGLE_VALUE_EXT() has no users, so remove it. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 6bb2fca044c5..01151a6ada35 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -51,9 +51,6 @@ struct platform_device; .sign_bit = xsign_bit, .invert = xinvert, .autodisable = xautodisable}) #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, xautodisable) \ SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert, xautodisable) -#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ - ((unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .max = xmax, .invert = xinvert}) #define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \ ((unsigned long)&(struct soc_mixer_control) \ {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ From b2b6913394488e031ee3d726f247b1c967057b40 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:13 +0000 Subject: [PATCH 395/651] ASoC: rt715: Remove duplicate SOC_DOUBLE_R_EXT() helper macro The rt715 does not appear to use the SOC_DOUBLE_R_EXT() macro and even if it did, the macro is defined identically in the ASoC headers. Remove the redundant macro definitions. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt715-sdca.c | 8 -------- sound/soc/codecs/rt715.c | 8 -------- 2 files changed, 16 deletions(-) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 7e10fd913812..7fb02654c16b 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -427,14 +427,6 @@ static int rt715_sdca_fu_info(struct snd_kcontrol *kcontrol, .private_value = RT715_SDCA_PR_VALUE(reg_base, xcount, xmax, \ xshift, xinvert)} -#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\ - xhandler_get, xhandler_put) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .info = snd_soc_info_volsw, \ - .get = xhandler_get, .put = xhandler_put, \ - .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ - xmax, xinvert) } - #define RT715_SDCA_EXT_TLV(xname, reg_base, xhandler_get,\ xhandler_put, tlv_array, xcount, xmax) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 299c9b12377c..2cf461852091 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -486,14 +486,6 @@ static int rt715_vol_info(struct snd_kcontrol *kcontrol, return 0; } -#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\ - xhandler_get, xhandler_put) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .info = snd_soc_info_volsw, \ - .get = xhandler_get, .put = xhandler_put, \ - .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ - xmax, xinvert) } - #define RT715_MAIN_SWITCH_EXT(xname, xhandler_get, xhandler_put) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ .info = rt715_switch_info, \ From 17ec58ac3c08c5c43bbdf5b08020fa4188a3009a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:14 +0000 Subject: [PATCH 396/651] ASoC: sma1307: Use SOC_SINGLE_EXT() helper macro Rather than open coding use the helper macro provided by the ASoC core. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/sma1307.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/sma1307.c b/sound/soc/codecs/sma1307.c index 480bcea48541..dac17da9cedd 100644 --- a/sound/soc/codecs/sma1307.c +++ b/sound/soc/codecs/sma1307.c @@ -1019,14 +1019,9 @@ static const struct snd_kcontrol_new sma1307_aif_out1_source_control = { .private_value = (unsigned long)&sma1307_aif_out_source_enum }; -static const struct snd_kcontrol_new sma1307_sdo_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Switch", - .info = snd_soc_info_volsw, - .get = sma1307_dapm_sdo_enable_get, - .put = sma1307_dapm_sdo_enable_put, - .private_value = SOC_SINGLE_VALUE(SND_SOC_NOPM, 0, 1, 0, 0) -}; +static const struct snd_kcontrol_new sma1307_sdo_control = + SOC_SINGLE_EXT("Switch", SND_SOC_NOPM, 0, 1, 0, + sma1307_dapm_sdo_enable_get, sma1307_dapm_sdo_enable_put); static const struct snd_kcontrol_new sma1307_enable_control = SOC_DAPM_SINGLE("Switch", SMA1307_00_SYSTEM_CTRL, 0, 1, 0); From aecdaa84adafb086b5b2939898d781bd63d6fe2e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:15 +0000 Subject: [PATCH 397/651] ASoC: tas2562: Use SOC_SINGLE_EXT_TLV() helper macro Rather than open coding use the helper macro provided by the ASoC core. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2562.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c index fef7ce39f664..8e00dcc09d0c 100644 --- a/sound/soc/codecs/tas2562.c +++ b/sound/soc/codecs/tas2562.c @@ -513,17 +513,9 @@ static const struct snd_kcontrol_new vsense_switch = static const struct snd_kcontrol_new tas2562_snd_controls[] = { SOC_SINGLE_TLV("Amp Gain Volume", TAS2562_PB_CFG1, 1, 0x1c, 0, tas2562_dac_tlv), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Digital Volume Control", - .index = 0, - .tlv.p = dvc_tlv, - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, - .info = snd_soc_info_volsw, - .get = tas2562_volume_control_get, - .put = tas2562_volume_control_put, - .private_value = SOC_SINGLE_VALUE(TAS2562_DVC_CFG1, 0, 110, 0, 0), - }, + SOC_SINGLE_EXT_TLV("Digital Volume Control", TAS2562_DVC_CFG1, 0, 110, 0, + tas2562_volume_control_get, tas2562_volume_control_put, + dvc_tlv), }; static const struct snd_soc_dapm_widget tas2110_dapm_widgets[] = { From 9bb7d7452363fc470b76766b0a6356807e752795 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:16 +0000 Subject: [PATCH 398/651] ASoC: wcd938x: Use SOC_SINGLE_EXT_TLV() helper macro Rather than open coding use the helper macro provided by the ASoC core. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index f2a4f3262bdb..b536e8bdc5a7 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -70,13 +70,8 @@ #define WCD_MBHC_HS_V_MAX 1600 #define WCD938X_EAR_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ - SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ - .put = wcd938x_ear_pa_put_gain, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } + SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, snd_soc_get_volsw, \ + wcd938x_ear_pa_put_gain, tlv_array) enum { WCD9380 = 0, From bf19467b8512f855bdfae59ae78d326b1f434443 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:17 +0000 Subject: [PATCH 399/651] ASoC: wm9712: Use SOC_SINGLE_EXT() helper macro Rather than open coding use the helper macro provided by the ASoC core. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm9712.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index e63921de0c37..8ff4b5f13b3a 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -275,13 +275,9 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol, return 0; } -#define WM9712_HP_MIXER_CTRL(xname, xmixer, xshift) { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = wm9712_hp_mixer_get, .put = wm9712_hp_mixer_put, \ - .private_value = SOC_SINGLE_VALUE(SND_SOC_NOPM, \ - (xmixer << 8) | xshift, 1, 0, 0) \ -} +#define WM9712_HP_MIXER_CTRL(xname, xmixer, xshift) \ + SOC_SINGLE_EXT(xname, SND_SOC_NOPM, ((xmixer) << 8) | (xshift), \ + 1, 0, wm9712_hp_mixer_get, wm9712_hp_mixer_put) /* Left Headphone Mixers */ static const struct snd_kcontrol_new wm9712_hpl_mixer_controls[] = { From 516493232a9b80dd4f4f6b078541cfad00973dbb Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:18 +0000 Subject: [PATCH 400/651] ASoC: wm9713: Use SOC_DOUBLE_EXT() helper macro Rather than open coding use the helper macro provided by the ASoC core. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-8-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 64b69316e4c7..0aa6491f2c84 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -284,13 +284,9 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol, return 0; } -#define WM9713_HP_MIXER_CTRL(xname, xmixer, xshift) { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = wm9713_hp_mixer_get, .put = wm9713_hp_mixer_put, \ - .private_value = SOC_DOUBLE_VALUE(SND_SOC_NOPM, \ - xshift, xmixer, 1, 0, 0) \ -} +#define WM9713_HP_MIXER_CTRL(xname, xmixer, xshift) \ + SOC_DOUBLE_EXT(xname, SND_SOC_NOPM, xshift, xmixer, 1, 0, \ + wm9713_hp_mixer_get, wm9713_hp_mixer_put) /* Left Headphone Mixers */ static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = { From 98413be56faa1c12494f43e7f77746763fa41c4a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:19 +0000 Subject: [PATCH 401/651] ASoC: wsa881x: Use SOC_SINGLE_EXT_TLV() helper macro Rather than open coding use the helper macro provided by the ASoC core. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa881x.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index dd2d6661adc7..a3999bb6d5e2 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -199,13 +199,8 @@ #define WSA881X_PROBE_TIMEOUT 1000 #define WSA881X_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ - SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ - .put = wsa881x_put_pa_gain, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } + SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \ + snd_soc_get_volsw, wsa881x_put_pa_gain, tlv_array) static struct reg_default wsa881x_defaults[] = { { WSA881X_CHIP_ID0, 0x00 }, From 7c5b07b497eab8eba75cf5da00cba493216dfc12 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:20 +0000 Subject: [PATCH 402/651] ASoC: atmel: tse850-pcm5142: Use SOC_SINGLE_EXT() helper macro The TSE850_DAPM_SINGLE_EXT() macro is an identical duplicate of the core SOC_SINGLE_EXT() marco. Use the macro provided by the core. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-10-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/atmel/tse850-pcm5142.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c index 0a9efd5f2861..2a1d0408a4cf 100644 --- a/sound/soc/atmel/tse850-pcm5142.c +++ b/sound/soc/atmel/tse850-pcm5142.c @@ -227,16 +227,9 @@ static const struct snd_kcontrol_new mux1 = static const struct snd_kcontrol_new mux2 = SOC_DAPM_ENUM_EXT("MUX2", mux_enum, tse850_get_mux2, tse850_put_mux2); -#define TSE850_DAPM_SINGLE_EXT(xname, reg, shift, max, invert, xget, xput) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = xget, \ - .put = xput, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } - static const struct snd_kcontrol_new mix[] = { - TSE850_DAPM_SINGLE_EXT("IN Switch", SND_SOC_NOPM, 0, 1, 0, - tse850_get_mix, tse850_put_mix), + SOC_SINGLE_EXT("IN Switch", SND_SOC_NOPM, 0, 1, 0, + tse850_get_mix, tse850_put_mix), }; static const char * const ana_text[] = { From 9e6e7e088cb78ce58ea442106b1f29cd7b6ff76e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:21 +0000 Subject: [PATCH 403/651] ASoC: dapm: Add missing SOC_DAPM_DOUBLE_R_TLV() helper A few drivers are open coding SOC_DAPM_DOUBLE_R_TLV() add a core helper and use that instead. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-11-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 7 +++++++ sound/soc/codecs/jz4760.c | 32 ++++--------------------------- sound/soc/codecs/jz4770.c | 40 ++++++--------------------------------- 3 files changed, 17 insertions(+), 62 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 7cf52c8c9cf3..bed1c37529ac 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -347,6 +347,13 @@ struct soc_enum; .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) } #define SOC_DAPM_SINGLE_VIRT(xname, max) \ SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0) +#define SOC_DAPM_DOUBLE_R_TLV(xname, lreg, rreg, shift, max, invert, tlv_array) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_volsw, \ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .tlv.p = (tlv_array), \ + .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ + .private_value = SOC_DOUBLE_R_VALUE(lreg, rreg, shift, max, invert) } #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ diff --git a/sound/soc/codecs/jz4760.c b/sound/soc/codecs/jz4760.c index 6217e611259f..e04af1b9ace8 100644 --- a/sound/soc/codecs/jz4760.c +++ b/sound/soc/codecs/jz4760.c @@ -314,37 +314,13 @@ static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = { }; static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Volume", - .info = snd_soc_info_volsw, - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ - | SNDRV_CTL_ELEM_ACCESS_READWRITE, - .tlv.p = dac_tlv, - .get = snd_soc_dapm_get_volsw, - .put = snd_soc_dapm_put_volsw, - .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6, - JZ4760_CODEC_REG_GCR5, - REG_GCR_GAIN_OFFSET, - REG_GCR_GAIN_MAX, 1), - }, + SOC_DAPM_DOUBLE_R_TLV("Volume", JZ4760_CODEC_REG_GCR6, JZ4760_CODEC_REG_GCR5, + REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, dac_tlv), }; static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Volume", - .info = snd_soc_info_volsw, - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ - | SNDRV_CTL_ELEM_ACCESS_READWRITE, - .tlv.p = out_tlv, - .get = snd_soc_dapm_get_volsw, - .put = snd_soc_dapm_put_volsw, - .private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2, - JZ4760_CODEC_REG_GCR1, - REG_GCR_GAIN_OFFSET, - REG_GCR_GAIN_MAX, 1), - }, + SOC_DAPM_DOUBLE_R_TLV("Volume", JZ4760_CODEC_REG_GCR2, JZ4760_CODEC_REG_GCR1, + REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, out_tlv), }; static int hpout_event(struct snd_soc_dapm_widget *w, diff --git a/sound/soc/codecs/jz4770.c b/sound/soc/codecs/jz4770.c index acb9eaa7ea1c..312202ab5cea 100644 --- a/sound/soc/codecs/jz4770.c +++ b/sound/soc/codecs/jz4770.c @@ -331,43 +331,15 @@ static const struct snd_kcontrol_new jz4770_codec_snd_controls[] = { }; static const struct snd_kcontrol_new jz4770_codec_pcm_playback_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Volume", - .info = snd_soc_info_volsw, - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ - | SNDRV_CTL_ELEM_ACCESS_READWRITE, - .tlv.p = dac_tlv, - .get = snd_soc_dapm_get_volsw, - .put = snd_soc_dapm_put_volsw, - /* - * NOTE: DACR/DACL are inversed; the gain value written to DACR - * seems to affect the left channel, and the gain value written - * to DACL seems to affect the right channel. - */ - .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_DACR, - JZ4770_CODEC_REG_GCR_DACL, - REG_GCR_GAIN_OFFSET, - REG_GCR_GAIN_MAX, 1), - }, + SOC_DAPM_DOUBLE_R_TLV("Volume", JZ4770_CODEC_REG_GCR_DACR, + JZ4770_CODEC_REG_GCR_DACL, REG_GCR_GAIN_OFFSET, + REG_GCR_GAIN_MAX, 1, dac_tlv), }; static const struct snd_kcontrol_new jz4770_codec_hp_playback_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Volume", - .info = snd_soc_info_volsw, - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ - | SNDRV_CTL_ELEM_ACCESS_READWRITE, - .tlv.p = out_tlv, - .get = snd_soc_dapm_get_volsw, - .put = snd_soc_dapm_put_volsw, - /* HPR/HPL inversed for the same reason as above */ - .private_value = SOC_DOUBLE_R_VALUE(JZ4770_CODEC_REG_GCR_HPR, - JZ4770_CODEC_REG_GCR_HPL, - REG_GCR_GAIN_OFFSET, - REG_GCR_GAIN_MAX, 1), - }, + SOC_DAPM_DOUBLE_R_TLV("Volume", JZ4770_CODEC_REG_GCR_HPR, + JZ4770_CODEC_REG_GCR_HPL, REG_GCR_GAIN_OFFSET, + REG_GCR_GAIN_MAX, 1, out_tlv), }; static int hpout_event(struct snd_soc_dapm_widget *w, From c951b20766f019a263b3547b07627be52fff87b4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:22 +0000 Subject: [PATCH 404/651] ASoC: dapm: Use ASoC control macros where possible Update the DAPM kcontrol creation macros to use the ASoC macros where a helpful version exists. One minor fixup is required in adau17x1, the compiler doesn't like the extra level of macro indirection coupled with the inline struct definition. Make the struct definition explicit. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-12-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 66 ++++++++++++++----------------------- sound/soc/codecs/adau17x1.c | 10 +++--- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index bed1c37529ac..4b8ef5b8a391 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -326,41 +326,37 @@ struct soc_enum; /* dapm kcontrol types */ #define SOC_DAPM_DOUBLE(xname, reg, lshift, rshift, max, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_DOUBLE_VALUE(reg, lshift, rshift, max, invert, 0) } + SOC_DOUBLE_EXT(xname, reg, lshift, rshift, max, invert, \ + snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw) #define SOC_DAPM_DOUBLE_R(xname, lreg, rreg, shift, max, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_DOUBLE_R_VALUE(lreg, rreg, shift, max, invert) } + SOC_DOUBLE_R_EXT(xname, lreg, rreg, shift, max, invert, \ + snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw) #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } + SOC_SINGLE_EXT(xname, reg, shift, max, invert, \ + snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw) +#define SOC_DAPM_SINGLE_VIRT(xname, max) \ + SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0) +#define SOC_DAPM_DOUBLE_R_TLV(xname, lreg, rreg, shift, max, invert, tlv_array) \ + SOC_DOUBLE_R_EXT_TLV(xname, lreg, rreg, shift, max, invert, \ + snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw, \ + tlv_array) +#define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ + SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \ + snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw, \ + tlv_array) +#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \ + SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array) +#define SOC_DAPM_ENUM(xname, xenum) \ + SOC_ENUM_EXT(xname, xenum, snd_soc_dapm_get_enum_double, \ + snd_soc_dapm_put_enum_double) +#define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \ + SOC_ENUM_EXT(xname, xenum, xget, xput) + #define SOC_DAPM_SINGLE_AUTODISABLE(xname, reg, shift, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) } -#define SOC_DAPM_SINGLE_VIRT(xname, max) \ - SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0) -#define SOC_DAPM_DOUBLE_R_TLV(xname, lreg, rreg, shift, max, invert, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_DOUBLE_R_VALUE(lreg, rreg, shift, max, invert) } -#define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } #define SOC_DAPM_SINGLE_TLV_AUTODISABLE(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ @@ -368,20 +364,6 @@ struct soc_enum; .tlv.p = (tlv_array), \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) } -#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \ - SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array) -#define SOC_DAPM_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_enum_double, \ - .get = snd_soc_dapm_get_enum_double, \ - .put = snd_soc_dapm_put_enum_double, \ - .private_value = (unsigned long)&xenum } -#define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_enum_double, \ - .get = xget, \ - .put = xput, \ - .private_value = (unsigned long)&xenum } #define SOC_DAPM_PIN_SWITCH(xname) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \ .info = snd_soc_dapm_info_pin_switch, \ diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 4dcc984761e0..2ebb5c90bdd9 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -254,11 +254,13 @@ static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol, } #define DECLARE_ADAU17X1_DSP_MUX_CTRL(_name, _label, _stream, _text) \ - const struct snd_kcontrol_new _name = \ - SOC_DAPM_ENUM_EXT(_label, (const struct soc_enum)\ + const struct soc_enum _name##_enum = \ SOC_ENUM_SINGLE(SND_SOC_NOPM, _stream, \ - ARRAY_SIZE(_text), _text), \ - adau17x1_dsp_mux_enum_get, adau17x1_dsp_mux_enum_put) + ARRAY_SIZE(_text), _text); \ + const struct snd_kcontrol_new _name = \ + SOC_DAPM_ENUM_EXT(_label, _name##_enum, \ + adau17x1_dsp_mux_enum_get, \ + adau17x1_dsp_mux_enum_put) static const char * const adau17x1_dac_mux_text[] = { "DSP", From 1743dbb45b2cbe5500068900794a355a7e0dd853 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 3 Mar 2025 17:14:23 +0000 Subject: [PATCH 405/651] ASoC: Tidy up SOC_DOUBLE_R_* helpers Re-implement SOC_DOUBLE_R_VALUE() in terms of SOC_DOUBLE_R_S_VALUE(). SOC_DOUBLE_R_S_VALUE() already had a minimum value so add this to SOC_DOUBLE_R_VALUE() as well, which makes SOC_DOUBLE_R_RANGE_VALUE() redundant, so its usage is replaced. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250303171424.444556-13-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc.h | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 01151a6ada35..390e08ba4dd4 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -51,19 +51,14 @@ struct platform_device; .sign_bit = xsign_bit, .invert = xinvert, .autodisable = xautodisable}) #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, xautodisable) \ SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert, xautodisable) -#define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \ - ((unsigned long)&(struct soc_mixer_control) \ - {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ - .max = xmax, .invert = xinvert}) #define SOC_DOUBLE_R_S_VALUE(xlreg, xrreg, xshift, xmin, xmax, xsign_bit, xinvert) \ ((unsigned long)&(struct soc_mixer_control) \ {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ .max = xmax, .min = xmin, .sign_bit = xsign_bit, \ .invert = xinvert}) -#define SOC_DOUBLE_R_RANGE_VALUE(xlreg, xrreg, xshift, xmin, xmax, xinvert) \ - ((unsigned long)&(struct soc_mixer_control) \ - {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ - .min = xmin, .max = xmax, .invert = xinvert}) +#define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmin, xmax, xinvert) \ + SOC_DOUBLE_R_S_VALUE(xlreg, xrreg, xshift, xmin, xmax, 0, xinvert) + #define SOC_SINGLE(xname, reg, shift, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ @@ -127,13 +122,13 @@ struct platform_device; .info = snd_soc_info_volsw, \ .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ - xmax, xinvert) } + 0, xmax, xinvert) } #define SOC_DOUBLE_R_RANGE(xname, reg_left, reg_right, xshift, xmin, \ xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw_range, \ .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ - .private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \ + .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ @@ -176,7 +171,7 @@ struct platform_device; .info = snd_soc_info_volsw, \ .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ - xmax, xinvert) } + 0, xmax, xinvert) } #define SOC_DOUBLE_R_RANGE_TLV(xname, reg_left, reg_right, xshift, xmin, \ xmax, xinvert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ @@ -185,7 +180,7 @@ struct platform_device; .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw_range, \ .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ - .private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \ + .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_R_SX_TLV(xname, xreg, xrreg, xshift, xmin, xmax, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ @@ -195,10 +190,7 @@ struct platform_device; .info = snd_soc_info_volsw_sx, \ .get = snd_soc_get_volsw_sx, \ .put = snd_soc_put_volsw_sx, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xrreg, \ - .shift = xshift, .rshift = xshift, \ - .max = xmax, .min = xmin} } + .private_value = SOC_DOUBLE_R_VALUE(xreg, xrreg, xshift, xmin, xmax, 0) } #define SOC_DOUBLE_R_S_TLV(xname, reg_left, reg_right, xshift, xmin, xmax, xsign_bit, xinvert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ @@ -272,7 +264,7 @@ struct platform_device; .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ - xmax, xinvert) } + 0, xmax, xinvert) } #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ xhandler_get, xhandler_put, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ @@ -313,7 +305,7 @@ struct platform_device; .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ - xmax, xinvert) } + 0, xmax, xinvert) } #define SOC_DOUBLE_R_S_EXT_TLV(xname, reg_left, reg_right, xshift, xmin, xmax, \ xsign_bit, xinvert, xhandler_get, xhandler_put, \ tlv_array) \ From aa85822c611aef7cd4dc17d27121d43e21bb82f0 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Sun, 16 Feb 2025 22:31:03 +0100 Subject: [PATCH 406/651] ALSA: hda/realtek: Enable PC beep passthrough for HP EliteBook 855 G7 PC speaker works well on this platform in BIOS and in Linux until sound card drivers are loaded. Then it stops working. There seems to be a beep generator node at 0x1a in this CODEC (ALC269_TYPE_ALC215) but it seems to be only connected to capture mixers at nodes 0x22 and 0x23. If I unmute the mixer input for 0x1a at node 0x23 and start recording from its "ALC285 Analog" capture device I can clearly hear beeps in that recording. So the beep generator is indeed working properly, however I wasn't able to figure out any way to connect it to speakers. However, the bits in the "Passthrough Control" register (0x36) seems to work at least partially: by zeroing "B" and "h" and setting "S" I can at least make the PIT PC speaker output appear either in this laptop speakers or headphones (depending on whether they are connected or not). There are some caveats, however: * If the CODEC gets runtime-suspended the beeps stop so it needs HDA beep device for keeping it awake during beeping. * If the beep generator node is generating any beep the PC beep passthrough seems to be temporarily inhibited, so the HDA beep device has to be prevented from using the actual beep generator node - but the beep device is still necessary due to the previous point. * In contrast with other platforms here beep amplification has to be disabled otherwise the beeps output are WAY louder than they were on pure BIOS setup. Unless someone (from Realtek probably) knows how to make the beep generator node output appear in speakers / headphones using PC beep passthrough seems to be the only way to make PC speaker beeping actually work on this platform. Signed-off-by: Maciej S. Szmigiero Acked-by: kailang@realtek.com Link: https://patch.msgid.link/7461f695b4daed80f2fc4b1463ead47f04f9ad05.1739741254.git.mail@maciej.szmigiero.name Signed-off-by: Takashi Iwai --- include/sound/hda_codec.h | 1 + sound/pci/hda/hda_beep.c | 15 +++++++++------ sound/pci/hda/patch_realtek.c | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h index 575e55aa08ca..c1fe6290d04d 100644 --- a/include/sound/hda_codec.h +++ b/include/sound/hda_codec.h @@ -195,6 +195,7 @@ struct hda_codec { /* beep device */ struct hda_beep *beep; unsigned int beep_mode; + bool beep_just_power_on; /* widget capabilities cache */ u32 *wcaps; diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index e51d47572557..13a7d92e8d8d 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -31,8 +31,9 @@ static void generate_tone(struct hda_beep *beep, int tone) beep->power_hook(beep, true); beep->playing = 1; } - snd_hda_codec_write(codec, beep->nid, 0, - AC_VERB_SET_BEEP_CONTROL, tone); + if (!codec->beep_just_power_on) + snd_hda_codec_write(codec, beep->nid, 0, + AC_VERB_SET_BEEP_CONTROL, tone); if (!tone && beep->playing) { beep->playing = 0; if (beep->power_hook) @@ -212,10 +213,12 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) struct hda_beep *beep; int err; - if (!snd_hda_get_bool_hint(codec, "beep")) - return 0; /* disabled explicitly by hints */ - if (codec->beep_mode == HDA_BEEP_MODE_OFF) - return 0; /* disabled by module option */ + if (!codec->beep_just_power_on) { + if (!snd_hda_get_bool_hint(codec, "beep")) + return 0; /* disabled explicitly by hints */ + if (codec->beep_mode == HDA_BEEP_MODE_OFF) + return 0; /* disabled by module option */ + } beep = kzalloc(sizeof(*beep), GFP_KERNEL); if (beep == NULL) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ae0beb52e7b0..3afd86c293ef 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -28,6 +28,7 @@ #include #include "hda_local.h" #include "hda_auto_parser.h" +#include "hda_beep.h" #include "hda_jack.h" #include "hda_generic.h" #include "hda_component.h" @@ -6922,6 +6923,30 @@ static void alc285_fixup_hp_envy_x360(struct hda_codec *codec, } } +static void alc285_fixup_hp_beep(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + codec->beep_just_power_on = true; + } else if (action == HDA_FIXUP_ACT_INIT) { +#ifdef CONFIG_SND_HDA_INPUT_BEEP + /* + * Just enable loopback to internal speaker and headphone jack. + * Disable amplification to get about the same beep volume as + * was on pure BIOS setup before loading the driver. + */ + alc_update_coef_idx(codec, 0x36, 0x7070, BIT(13)); + + snd_hda_enable_beep_device(codec, 1); + +#if !IS_ENABLED(CONFIG_INPUT_PCSPKR) + dev_warn_once(hda_codec_dev(codec), + "enable CONFIG_INPUT_PCSPKR to get PC beeps\n"); +#endif +#endif + } +} + /* for hda_fixup_thinkpad_acpi() */ #include "thinkpad_helper.c" @@ -7706,6 +7731,7 @@ enum { ALC285_FIXUP_HP_GPIO_LED, ALC285_FIXUP_HP_MUTE_LED, ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED, + ALC285_FIXUP_HP_BEEP_MICMUTE_LED, ALC236_FIXUP_HP_MUTE_LED_COEFBIT2, ALC236_FIXUP_HP_GPIO_LED, ALC236_FIXUP_HP_MUTE_LED, @@ -9302,6 +9328,12 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc285_fixup_hp_spectre_x360_mute_led, }, + [ALC285_FIXUP_HP_BEEP_MICMUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_beep, + .chained = true, + .chain_id = ALC285_FIXUP_HP_MUTE_LED, + }, [ALC236_FIXUP_HP_MUTE_LED_COEFBIT2] = { .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_mute_led_coefbit2, @@ -10391,7 +10423,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8735, "HP ProBook 435 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), - SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8760, "HP EliteBook 8{4,5}5 G7", ALC285_FIXUP_HP_BEEP_MICMUTE_LED), SND_PCI_QUIRK(0x103c, 0x876e, "HP ENVY x360 Convertible 13-ay0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED), From 79c080c75cdd0a5ba38be039f6f9bb66ec53b0c4 Mon Sep 17 00:00:00 2001 From: Louis-Alexis Eyraud Date: Fri, 28 Feb 2025 11:32:19 +0100 Subject: [PATCH 407/651] ASoC: mediatek: mt6359: Fix DT parse error due to wrong child node name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A recent dtbs_check error fix in mt6359.dtsi file changed a node name (from "mt6359codec" to "audio-codec") without modifying the mt6539 codec code that uses it. It leads to a probe failure after devicetree parsing returns in error: ``` [ 1.354025] mt6359-sound mt6359-sound: mt6359_platform_driver_probe() failed to parse dts [ 1.355066] mt6359-sound mt6359-sound: probe with driver mt6359-sound failed with error -22 ``` So, add the child node retrieval with the new name and if not found, try with the older one for backward compatibility. Fixes: 76b35f59bbe6 ("arm64: dts: mediatek: mt6359: fix dtbs_check error for audio-codec") Signed-off-by: Louis-Alexis Eyraud Reviewed-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250228-mt6359-fix-probe-failed-v1-1-64941d387b2c@collabora.com Signed-off-by: Mark Brown --- sound/soc/codecs/mt6359.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c index 0b76a55664b0..f73120c6a6ce 100644 --- a/sound/soc/codecs/mt6359.c +++ b/sound/soc/codecs/mt6359.c @@ -2867,9 +2867,12 @@ static int mt6359_parse_dt(struct mt6359_priv *priv) struct device *dev = priv->dev; struct device_node *np; - np = of_get_child_by_name(dev->parent->of_node, "mt6359codec"); - if (!np) - return -EINVAL; + np = of_get_child_by_name(dev->parent->of_node, "audio-codec"); + if (!np) { + np = of_get_child_by_name(dev->parent->of_node, "mt6359codec"); + if (!np) + return -EINVAL; + } ret = of_property_read_u32(np, "mediatek,dmic-mode", &priv->dmic_one_wire_mode); From 1d251a7adc5b720a71641c758a45b8a119971d80 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Mar 2025 11:38:07 +0100 Subject: [PATCH 408/651] ASoC: dt-bindings: everest,es8328: Mark ES8388 compatible with ES8328 Based on Linux driver, the ES8388 looks fully compatible with ES8328. One upstream DTS (ARM rk3288-rock2-square.dts) already uses ES8328 fallback, so mark the devices as compatible in the binding. Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250304103808.75236-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/everest,es8328.yaml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/everest,es8328.yaml b/Documentation/devicetree/bindings/sound/everest,es8328.yaml index ed18e40dcaac..309c4d01db76 100644 --- a/Documentation/devicetree/bindings/sound/everest,es8328.yaml +++ b/Documentation/devicetree/bindings/sound/everest,es8328.yaml @@ -24,9 +24,13 @@ maintainers: properties: compatible: - enum: - - everest,es8328 - - everest,es8388 + oneOf: + - enum: + - everest,es8328 + - items: + - enum: + - everest,es8388 + - const: everest,es8328 reg: maxItems: 1 From 8243a49145e59f19032b86b20d8906f05e31bdcc Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Mar 2025 11:38:08 +0100 Subject: [PATCH 409/651] ASoC: dt-bindings: everest,es8328: Require reg property ES8328 and ES8388 codecs are I2C or SPI devices, thus they are addressable on their bus and 'reg' property should be always provided. Requiring 'reg' is pretty close to redundant, because the I2C and SPI controller/bus bindings require it already, but the convention is to mention 'reg' also in the device schemas. Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250304103808.75236-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/everest,es8328.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/everest,es8328.yaml b/Documentation/devicetree/bindings/sound/everest,es8328.yaml index 309c4d01db76..ddddd7b143ab 100644 --- a/Documentation/devicetree/bindings/sound/everest,es8328.yaml +++ b/Documentation/devicetree/bindings/sound/everest,es8328.yaml @@ -60,6 +60,7 @@ properties: required: - compatible + - reg - clocks - DVDD-supply - AVDD-supply From b19d340d5d08c5940ce612c2a1b5fe3a8a401f9d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 3 Mar 2025 09:41:41 +0100 Subject: [PATCH 410/651] ASoC: samsung: bells: Drop unused include This file does not use the symbols from the legacy header, so let's drop it. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250303-samsung-codecs-v1-1-56a2299dd928@linaro.org Reviewed-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- sound/soc/samsung/bells.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index 365b1aca4855..b4c0857ae351 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "../codecs/wm5102.h" From c4b2d9643a06a5326a778c4d77d6fa60e0f3d6b1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 3 Mar 2025 09:41:42 +0100 Subject: [PATCH 411/651] ASoC: samsung: littlemill: Drop unused include This file does not use the symbols from the legacy header, so let's drop it. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250303-samsung-codecs-v1-2-56a2299dd928@linaro.org Reviewed-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- sound/soc/samsung/littlemill.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index c5260e101c2a..9fa5e3ff9215 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "../codecs/wm8994.h" From 5c06f7f3d8374df1cec3b353306a4d1032a60f44 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 3 Mar 2025 09:41:43 +0100 Subject: [PATCH 412/651] ASoC: samsung: lowland: Drop unused include This file does not use the symbols from the legacy header, so let's drop it. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250303-samsung-codecs-v1-3-56a2299dd928@linaro.org Reviewed-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- sound/soc/samsung/lowland.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 702cb4cc1ce9..d4088b72d43c 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "../codecs/wm5100.h" From da9146c19b1774926148ff271c4a3dc8d7891b18 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 3 Mar 2025 09:41:44 +0100 Subject: [PATCH 413/651] ASoC: samsung: speyside: Convert to GPIO descriptor The Speyside ASoC uses a single GPIO from the WM8996 that we can provide from the local offset on that chip rather than from the global GPIO numberspace as is being done currently. The offset 2 was done by calculating the base offset for the CODEC (i.e. wm8996) GPIOs to 212, by reading arch/arm/mach-s3c/gpio-samsung-s3c64xx.h and arch/arm/mach-s3c/crag6410.h and adding up all the offsets that were occasionally adding a +1 blank GPIO between each GPIO provider. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250303-samsung-codecs-v1-4-56a2299dd928@linaro.org Signed-off-by: Mark Brown --- sound/soc/samsung/speyside.c | 37 +++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 79476e8eb680..947b85ff83f0 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -7,13 +7,13 @@ #include #include #include -#include +#include +#include #include #include "../codecs/wm8996.h" #include "../codecs/wm9081.h" -#define WM8996_HPSEL_GPIO 214 #define MCLK_AUDIO_RATE (512 * 48000) static int speyside_set_bias_level(struct snd_soc_card *card, @@ -105,6 +105,7 @@ static struct snd_soc_jack_pin speyside_headset_pins[] = { }, }; +static struct gpio_desc *speyside_hpsel_gpio; /* Default the headphone selection to active high */ static int speyside_jack_polarity; @@ -123,7 +124,7 @@ static void speyside_set_polarity(struct snd_soc_component *component, int polarity) { speyside_jack_polarity = !polarity; - gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); + gpiod_direction_output(speyside_hpsel_gpio, speyside_jack_polarity); /* Re-run DAPM to make sure we're using the correct mic bias */ snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); @@ -145,16 +146,22 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = dai->component; + enum gpiod_flags flags; int ret; ret = snd_soc_dai_set_sysclk(dai, WM8996_SYSCLK_MCLK2, 32768, 0); if (ret < 0) return ret; - ret = gpio_request(WM8996_HPSEL_GPIO, "HP_SEL"); - if (ret != 0) - pr_err("Failed to request HP_SEL GPIO: %d\n", ret); - gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); + if (speyside_jack_polarity) + flags = GPIOD_OUT_HIGH; + else + flags = GPIOD_OUT_LOW; + speyside_hpsel_gpio = devm_gpiod_get(rtd->card->dev, + "hp-sel", + flags); + if (IS_ERR(speyside_hpsel_gpio)) + return PTR_ERR(speyside_hpsel_gpio); ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", SND_JACK_LINEOUT | SND_JACK_HEADSET | @@ -325,6 +332,21 @@ static struct snd_soc_card speyside = { .late_probe = speyside_late_probe, }; +static struct gpiod_lookup_table wm8996_gpiod_table = { + /* Hardcoded device name in board file mach-crag6410.c */ + .dev_id = "speyside", + .table = { + /* + * This line was hardcoded to 214 in the global GPIO + * number space, S3C GPIO macros seems top set the + * wm8996 codec GPIO start offset to 212, so this will + * be GPIO 214 - 212 = 2 on the wm8996. + */ + GPIO_LOOKUP("wm8996", 2, "hp-sel", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static int speyside_probe(struct platform_device *pdev) { struct snd_soc_card *card = &speyside; @@ -332,6 +354,7 @@ static int speyside_probe(struct platform_device *pdev) card->dev = &pdev->dev; + gpiod_add_lookup_table(&wm8996_gpiod_table); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) dev_err_probe(&pdev->dev, ret, "snd_soc_register_card() failed\n"); From c095b7a27529d1d18b3b36a47f77a1419f0de939 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 3 Mar 2025 09:41:45 +0100 Subject: [PATCH 414/651] ASoC: samsung: tobermory: Drop unused include This file does not use the symbols from the legacy header, so let's drop it. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250303-samsung-codecs-v1-5-56a2299dd928@linaro.org Reviewed-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- sound/soc/samsung/tobermory.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 2bdd81bf821a..bc2608dbaddc 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "../codecs/wm8962.h" From 0a22454ab2eca530702b2689858909b608953703 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 3 Mar 2025 09:41:46 +0100 Subject: [PATCH 415/651] ASoC: samsung: tm2_wm5110: Drop unused include This file does not use the symbols from the legacy header, so let's drop it. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250303-samsung-codecs-v1-6-56a2299dd928@linaro.org Reviewed-by: Bartosz Golaszewski Signed-off-by: Mark Brown --- sound/soc/samsung/tm2_wm5110.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c index 2417b91a328f..cc76963105d9 100644 --- a/sound/soc/samsung/tm2_wm5110.c +++ b/sound/soc/samsung/tm2_wm5110.c @@ -6,7 +6,6 @@ // Sylwester Nawrocki #include -#include #include #include #include From 6db63090272768785e6bb4a3afa16650c1e96c54 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 4 Mar 2025 14:05:00 +0000 Subject: [PATCH 416/651] ASoC: Tidy up SOC_DOUBLE_* and SOC_SINGLE_* helpers Re-implement SOC_DOUBLE_VALUE() in terms of SOC_DOUBLE_S_VALUE(). SOC_DOUBLE_S_VALUE() already had a minimum value so add this to SOC_DOUBLE_VALUE as well, this allows replacement of several hard coded value entries. Likewise update SOC_SINGLE_VALUE to match, which allows replacement of even more hard coded values. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250304140500.976127-14-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 4 +-- include/sound/soc.h | 65 +++++++++++++++------------------------- 2 files changed, 26 insertions(+), 43 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 4b8ef5b8a391..af802ef536e7 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -356,14 +356,14 @@ struct soc_enum; { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) } + .private_value = SOC_SINGLE_VALUE(reg, shift, 0, max, invert, 1) } #define SOC_DAPM_SINGLE_TLV_AUTODISABLE(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) } + .private_value = SOC_SINGLE_VALUE(reg, shift, 0, max, invert, 1) } #define SOC_DAPM_PIN_SWITCH(xname) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \ .info = snd_soc_dapm_info_pin_switch, \ diff --git a/include/sound/soc.h b/include/sound/soc.h index 390e08ba4dd4..de1abad06a9b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -39,18 +39,17 @@ struct platform_device; /* * Convenience kcontrol builders */ -#define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmax, xinvert, xautodisable) \ - ((unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, .shift = shift_left, \ - .rshift = shift_right, .max = xmax, \ - .invert = xinvert, .autodisable = xautodisable}) -#define SOC_DOUBLE_S_VALUE(xreg, shift_left, shift_right, xmin, xmax, xsign_bit, xinvert, xautodisable) \ +#define SOC_DOUBLE_S_VALUE(xreg, shift_left, shift_right, xmin, xmax, xsign_bit, \ + xinvert, xautodisable) \ ((unsigned long)&(struct soc_mixer_control) \ {.reg = xreg, .rreg = xreg, .shift = shift_left, \ .rshift = shift_right, .min = xmin, .max = xmax, \ .sign_bit = xsign_bit, .invert = xinvert, .autodisable = xautodisable}) -#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, xautodisable) \ - SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert, xautodisable) +#define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmin, xmax, xinvert, xautodisable) \ + SOC_DOUBLE_S_VALUE(xreg, shift_left, shift_right, xmin, xmax, 0, xinvert, \ + xautodisable) +#define SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, xautodisable) \ + SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmin, xmax, xinvert, xautodisable) #define SOC_DOUBLE_R_S_VALUE(xlreg, xrreg, xshift, xmin, xmax, xsign_bit, xinvert) \ ((unsigned long)&(struct soc_mixer_control) \ {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ @@ -63,15 +62,12 @@ struct platform_device; { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ .put = snd_soc_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } + .private_value = SOC_SINGLE_VALUE(reg, shift, 0, max, invert, 0) } #define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \ .put = snd_soc_put_volsw_range, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, .shift = xshift, \ - .rshift = xshift, .min = xmin, .max = xmax, \ - .invert = xinvert} } + .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ @@ -79,7 +75,7 @@ struct platform_device; .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ .put = snd_soc_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) } + .private_value = SOC_SINGLE_VALUE(reg, shift, 0, max, invert, 0) } #define SOC_SINGLE_SX_TLV(xname, xreg, xshift, xmin, xmax, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ @@ -88,10 +84,7 @@ struct platform_device; .info = snd_soc_info_volsw_sx, \ .get = snd_soc_get_volsw_sx,\ .put = snd_soc_put_volsw_sx, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, \ - .shift = xshift, .rshift = xshift, \ - .max = xmax, .min = xmin} } + .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, 0, 0) } #define SOC_SINGLE_RANGE_TLV(xname, xreg, xshift, xmin, xmax, xinvert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ @@ -99,16 +92,13 @@ struct platform_device; .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw_range, \ .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, .shift = xshift, \ - .rshift = xshift, .min = xmin, .max = xmax, \ - .invert = xinvert} } + .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \ - max, invert, 0) } + 0, max, invert, 0) } #define SOC_DOUBLE_STS(xname, reg, shift_left, shift_right, max, invert) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ @@ -116,7 +106,7 @@ struct platform_device; .access = SNDRV_CTL_ELEM_ACCESS_READ | \ SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \ - max, invert, 0) } + 0, max, invert, 0) } #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ .info = snd_soc_info_volsw, \ @@ -138,7 +128,7 @@ struct platform_device; .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \ - max, invert, 0) } + 0, max, invert, 0) } #define SOC_DOUBLE_SX_TLV(xname, xreg, shift_left, shift_right, xmin, xmax, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ @@ -147,10 +137,8 @@ struct platform_device; .info = snd_soc_info_volsw_sx, \ .get = snd_soc_get_volsw_sx, \ .put = snd_soc_put_volsw_sx, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, \ - .shift = shift_left, .rshift = shift_right, \ - .max = xmax, .min = xmin} } + .private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \ + xmin, xmax, 0, 0) } #define SOC_DOUBLE_RANGE_TLV(xname, xreg, xshift_left, xshift_right, xmin, xmax, \ xinvert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ @@ -159,10 +147,8 @@ struct platform_device; .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw, \ .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, \ - .shift = xshift_left, .rshift = xshift_right, \ - .min = xmin, .max = xmax, .invert = xinvert} } + .private_value = SOC_DOUBLE_VALUE(xreg, xshift_left, xshift_right, \ + xmin, xmax, xinvert, 0) } #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ @@ -250,14 +236,14 @@ struct platform_device; { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ - .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) } + .private_value = SOC_SINGLE_VALUE(xreg, xshift, 0, xmax, xinvert, 0) } #define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\ xhandler_get, xhandler_put) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = \ - SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert, 0) } + SOC_DOUBLE_VALUE(reg, shift_left, shift_right, 0, max, invert, 0) } #define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\ xhandler_get, xhandler_put) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ @@ -273,7 +259,7 @@ struct platform_device; .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ - .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) } + .private_value = SOC_SINGLE_VALUE(xreg, xshift, 0, xmax, xinvert, 0) } #define SOC_SINGLE_RANGE_EXT_TLV(xname, xreg, xshift, xmin, xmax, xinvert, \ xhandler_get, xhandler_put, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ @@ -282,10 +268,7 @@ struct platform_device; .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw_range, \ .get = xhandler_get, .put = xhandler_put, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .rreg = xreg, .shift = xshift, \ - .rshift = xshift, .min = xmin, .max = xmax, \ - .invert = xinvert} } + .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\ xhandler_get, xhandler_put, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ @@ -295,7 +278,7 @@ struct platform_device; .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \ - xmax, xinvert, 0) } + 0, xmax, xinvert, 0) } #define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ xhandler_get, xhandler_put, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ From de22dc76e11d1291d4f50b73dbbaa158ba9d6acd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Mar 2025 00:24:06 +0000 Subject: [PATCH 417/651] ASoC: doc: use SND_SOC_DAILINK_xxx() macro We can use SND_SOC_DAILINK_xxx() macro to define CPU/Codec/Platform. Let's use it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tt88z5nd.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- Documentation/sound/soc/dpcm.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Documentation/sound/soc/dpcm.rst b/Documentation/sound/soc/dpcm.rst index a12636552f50..7b6aeab3c207 100644 --- a/Documentation/sound/soc/dpcm.rst +++ b/Documentation/sound/soc/dpcm.rst @@ -147,14 +147,16 @@ For the example above we have to define 4 FE DAI links and 6 BE DAI links. The FE DAI links are defined as follows :- :: + SND_SOC_DAILINK_DEFS(pcm0, + DAILINK_COMP_ARRAY(COMP_CPU("System Pin")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_PLATFORM("dsp-audio"))); + static struct snd_soc_dai_link machine_dais[] = { { .name = "PCM0 System", .stream_name = "System Playback", - .cpu_dai_name = "System Pin", - .platform_name = "dsp-audio", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", + SND_SOC_DAILINK_REG(pcm0), .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, }, @@ -174,15 +176,16 @@ dynamic and will change depending on runtime config. The BE DAIs are configured as follows :- :: + SND_SOC_DAILINK_DEFS(headset, + DAILINK_COMP_ARRAY(COMP_CPU("ssp-dai.0")), + DAILINK_COMP_ARRAY(COMP_CODEC("rt5640.0-001c", "rt5640-aif1"))); + static struct snd_soc_dai_link machine_dais[] = { .....< FE DAI links here > { .name = "Codec Headset", - .cpu_dai_name = "ssp-dai.0", - .platform_name = "snd-soc-dummy", + SND_SOC_DAILINK_REG(headset), .no_pcm = 1, - .codec_name = "rt5640.0-001c", - .codec_dai_name = "rt5640-aif1", .ignore_suspend = 1, .ignore_pmdown_time = 1, .be_hw_params_fixup = hswult_ssp0_fixup, From b92bc4d6e21f1802a39975e3c7cc4f76f591d46f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 5 Mar 2025 00:12:52 +0000 Subject: [PATCH 418/651] ASoC: soc-pcm: merge soc_pcm_hw_update_format/subformat() format() and subformat() should be handled in the same time, no need to have each functions. Let's merge these soc_pcm_hw_update_format() soc_pcm_hw_update_subformat() Signed-off-by: Kuninori Morimoto Cc: Cezary Rojewski Cc: Jaroslav Kysela Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/87v7soz664.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 2a53a2eb4acd..c2d4becf0c3d 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -603,13 +603,8 @@ static void soc_pcm_hw_update_chan(struct snd_pcm_hardware *hw, static void soc_pcm_hw_update_format(struct snd_pcm_hardware *hw, const struct snd_soc_pcm_stream *p) { - hw->formats &= p->formats; -} - -static void soc_pcm_hw_update_subformat(struct snd_pcm_hardware *hw, - const struct snd_soc_pcm_stream *p) -{ - hw->subformats &= p->subformats; + hw->formats &= p->formats; + hw->subformats &= p->subformats; } /** @@ -650,7 +645,6 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, soc_pcm_hw_update_chan(hw, cpu_stream); soc_pcm_hw_update_rate(hw, cpu_stream); soc_pcm_hw_update_format(hw, cpu_stream); - soc_pcm_hw_update_subformat(hw, cpu_stream); } cpu_chan_min = hw->channels_min; cpu_chan_max = hw->channels_max; @@ -672,7 +666,6 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd, soc_pcm_hw_update_chan(hw, codec_stream); soc_pcm_hw_update_rate(hw, codec_stream); soc_pcm_hw_update_format(hw, codec_stream); - soc_pcm_hw_update_subformat(hw, codec_stream); } /* Verify both a valid CPU DAI and a valid CODEC DAI were found */ @@ -1765,7 +1758,6 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream) soc_pcm_hw_update_rate(hw, cpu_stream); soc_pcm_hw_update_chan(hw, cpu_stream); soc_pcm_hw_update_format(hw, cpu_stream); - soc_pcm_hw_update_subformat(hw, cpu_stream); } } @@ -1803,7 +1795,6 @@ static void dpcm_runtime_setup_be_format(struct snd_pcm_substream *substream) codec_stream = snd_soc_dai_get_pcm_stream(dai, stream); soc_pcm_hw_update_format(hw, codec_stream); - soc_pcm_hw_update_subformat(hw, codec_stream); } } } From 8b36447c9ae102539d82d6278971b23b20d87629 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 5 Mar 2025 21:54:35 +0800 Subject: [PATCH 419/651] ASoC: Intel: adl: add 2xrt1316 audio configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That is a speaker only configuration and 2 rt1316 are on link 0 and 2. Signed-off-by: Bard Liao Reviewed-by: Liam Girdwood Reviewed-by: Péter Ujfalusi Link: https://patch.msgid.link/20250305135443.201884-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-adl-match.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index bb1324fb588e..a68efbe98948 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -214,6 +214,15 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = { + { + .adr = 0x000232025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = { { .adr = 0x000130025D131601ull, @@ -547,6 +556,20 @@ static const struct snd_soc_acpi_link_adr adl_chromebook_base[] = { {} }; +static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link02[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt1316_0_group2_adr), + .adr_d = rt1316_0_group2_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group2_adr), + .adr_d = rt1316_2_group2_adr, + }, + {} +}; + static const struct snd_soc_acpi_codecs adl_max98357a_amp = { .num_codecs = 1, .codecs = {"MX98357A"} @@ -749,6 +772,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-adl-sdw-max98373-rt5682.tplg", }, + { + .link_mask = BIT(0) | BIT(2), + .links = adl_sdw_rt1316_link02, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-adl-rt1316-l02.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_sdw_machines); From 02467341e3577836648753a9e9a5c196f08187da Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 5 Mar 2025 21:54:36 +0800 Subject: [PATCH 420/651] ASoC: Intel: soc-acpi-intel-ptl-match: add rt712_vb_l3_rt1320_l2 support Add rt712_vb on SDW link 3 and 1 rt1320 on SDW link 2 configuration support. Signed-off-by: Peter Ujfalusi Reviewed-by: Liam Girdwood Reviewed-by: Ranjani Sridharan Signed-off-by: Bard Liao Link: https://patch.msgid.link/20250305135443.201884-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-ptl-match.c | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index dd7993b76dee..8807acb92ecf 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -134,6 +134,15 @@ static const struct snd_soc_acpi_adr_device rt712_vb_2_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt712_vb_3_group1_adr[] = { + { + .adr = 0x000330025D071201ull, + .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints_endpoints), + .endpoints = jack_amp_g1_dmic_endpoints_endpoints, + .name_prefix = "rt712" + } +}; + static const struct snd_soc_acpi_adr_device rt713_vb_2_adr[] = { { .adr = 0x000230025d071301ull, @@ -206,6 +215,15 @@ static const struct snd_soc_acpi_adr_device rt1320_1_group2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1320_2_group1_adr[] = { + { + .adr = 0x000230025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-1" + } +}; + static const struct snd_soc_acpi_adr_device rt1320_3_group2_adr[] = { { .adr = 0x000330025D132001ull, @@ -284,6 +302,20 @@ static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l2_rt1320_l1[] = { {} }; +static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l3_rt1320_l2[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt712_vb_3_group1_adr), + .adr_d = rt712_vb_3_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1320_2_group1_adr), + .adr_d = rt1320_2_group1_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { /* mockup tests need to be first */ @@ -342,6 +374,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, .sof_tplg_filename = "sof-ptl-rt712-l2-rt1320-l1.tplg" }, + { + .link_mask = BIT(2) | BIT(3), + .links = ptl_sdw_rt712_vb_l3_rt1320_l2, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-ptl-rt712-l3-rt1320-l2.tplg" + }, { .link_mask = BIT(1) | BIT(2) | BIT(3), .links = ptl_sdw_rt713_vb_l2_rt1320_l13, From ffe450cb6bce16eb15f6bf90b85b7e5f9bfbc1e3 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 5 Mar 2025 21:54:37 +0800 Subject: [PATCH 421/651] ASoC: Intel: soc-acpi-intel-ptl-match: add rt713_vb_l3_rt1320_l12 support Add rt713_vb on SDW link 3 and 2 rt1320 on SDW link 1 and 2 configuration support. Signed-off-by: Peter Ujfalusi Reviewed-by: Liam Girdwood Reviewed-by: Ranjani Sridharan Signed-off-by: Bard Liao Link: https://patch.msgid.link/20250305135443.201884-4-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-ptl-match.c | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index 8807acb92ecf..5c1ece913a18 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -152,6 +152,15 @@ static const struct snd_soc_acpi_adr_device rt713_vb_2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt713_vb_3_adr[] = { + { + .adr = 0x000330025D071301ull, + .num_endpoints = ARRAY_SIZE(jack_dmic_endpoints), + .endpoints = jack_dmic_endpoints, + .name_prefix = "rt713" + } +}; + static const struct snd_soc_acpi_adr_device rt721_3_single_adr[] = { { .adr = 0x000330025d072101ull, @@ -224,6 +233,15 @@ static const struct snd_soc_acpi_adr_device rt1320_2_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1320_2_group2_adr[] = { + { + .adr = 0x000230025D132001ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1320-1" + } +}; + static const struct snd_soc_acpi_adr_device rt1320_3_group2_adr[] = { { .adr = 0x000330025D132001ull, @@ -288,6 +306,25 @@ static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l2_rt1320_l13[] = { {} }; +static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l3_rt1320_l12[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt713_vb_3_adr), + .adr_d = rt713_vb_3_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1320_1_group2_adr), + .adr_d = rt1320_1_group2_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1320_2_group2_adr), + .adr_d = rt1320_2_group2_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l2_rt1320_l1[] = { { .mask = BIT(2), @@ -388,6 +425,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, .sof_tplg_filename = "sof-ptl-rt713-l2-rt1320-l13.tplg" }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = ptl_sdw_rt713_vb_l3_rt1320_l12, + .drv_name = "sof_sdw", + .machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb, + .sof_tplg_filename = "sof-ptl-rt713-l3-rt1320-l12.tplg" + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_sdw_machines); From 65e246d33dede0008f281d3d09b7695bef2d18eb Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 5 Mar 2025 21:54:38 +0800 Subject: [PATCH 422/651] ASoC: sdw_utils: add mic and amp dais to 0xaaaa codec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit part id 0xaaaa codec is a mockup codec. Make it be a multi function codec. So that we can test multi function with a mockup codec. Signed-off-by: Bard Liao Reviewed-by: Liam Girdwood Reviewed-by: Péter Ujfalusi Link: https://patch.msgid.link/20250305135443.201884-5-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sdw_utils/soc_sdw_utils.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c index 6ee7d30b8ece..5175818ff2c1 100644 --- a/sound/soc/sdw_utils/soc_sdw_utils.c +++ b/sound/soc/sdw_utils/soc_sdw_utils.c @@ -586,8 +586,20 @@ struct asoc_sdw_codec_info codec_info_list[] = { .dai_type = SOC_SDW_DAI_TYPE_JACK, .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID}, }, + { + .direction = {true, false}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOC_SDW_DAI_TYPE_AMP, + .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID}, + }, + { + .direction = {false, true}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOC_SDW_DAI_TYPE_MIC, + .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID}, + }, }, - .dai_num = 1, + .dai_num = 3, }, { .part_id = 0xaa55, /* headset codec mockup */ From e1a0657c6d943528ef58671594ca7e5b17db5394 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 5 Mar 2025 21:54:39 +0800 Subject: [PATCH 423/651] ASoC: Intel: add multi-function SDW mockup codec match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SoundWire multi function codecs are common used in recent platforms. Add a multi function mockup codec to test without real codec. Signed-off-by: Bard Liao Reviewed-by: Liam Girdwood Reviewed-by: Péter Ujfalusi Link: https://patch.msgid.link/20250305135443.201884-6-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../common/soc-acpi-intel-sdw-mockup-match.c | 42 +++++++++++++++++++ .../common/soc-acpi-intel-sdw-mockup-match.h | 1 + 2 files changed, 43 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c index a3d33997736a..d122ce69fa4f 100644 --- a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.c @@ -31,6 +31,30 @@ static const struct snd_soc_acpi_endpoint sdw_mockup_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints[] = { + /* Jack Endpoint */ + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + /* Amp Endpoint, work as spk_l_endpoint */ + { + .num = 1, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, + /* DMIC Endpoint */ + { + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device sdw_mockup_headset_0_adr[] = { { .adr = 0x0000000105AA5500ull, @@ -103,6 +127,15 @@ static const struct snd_soc_acpi_adr_device sdw_mockup_amp_2_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device sdw_mockup_multi_function_adr[] = { + { + .adr = 0x0000000105AAAA01ull, + .num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints), + .endpoints = jack_amp_g1_dmic_endpoints, + .name_prefix = "sdw_mockup_mmulti-function" + } +}; + const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[] = { { .mask = BIT(0), @@ -164,3 +197,12 @@ const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[] = { }, {} }; + +const struct snd_soc_acpi_link_adr sdw_mockup_multi_func[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(sdw_mockup_multi_function_adr), + .adr_d = sdw_mockup_multi_function_adr, + }, + {} +}; diff --git a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h index c99eecd19e03..f7ed5beaca96 100644 --- a/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h +++ b/sound/soc/intel/common/soc-acpi-intel-sdw-mockup-match.h @@ -13,5 +13,6 @@ extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_1amp_mic[]; extern const struct snd_soc_acpi_link_adr sdw_mockup_headset_2amps_mic[]; extern const struct snd_soc_acpi_link_adr sdw_mockup_mic_headset_1amp[]; +extern const struct snd_soc_acpi_link_adr sdw_mockup_multi_func[]; #endif From 438405704eec45c06be9adc94eb5f94855412790 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 5 Mar 2025 21:54:40 +0800 Subject: [PATCH 424/651] ASoC: Intel: soc-acpi-intel-lnl-match: add sdw multi function mockup codec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a SoundWire multi function mockup codec support. Signed-off-by: Bard Liao Reviewed-by: Liam Girdwood Reviewed-by: Péter Ujfalusi Link: https://patch.msgid.link/20250305135443.201884-7-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-lnl-match.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c index 0b4a9c27c47e..1e24e969ad15 100644 --- a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c @@ -552,6 +552,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-lnl-rt715-rt711-rt1308-mono.tplg", }, + { + .link_mask = BIT(0), + .links = sdw_mockup_multi_func, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt722-l0.tplg", /* Reuse the existing tplg file */ + }, { .link_mask = GENMASK(3, 0), .links = lnl_3_in_1_sdca, From c7a6a74f847923bb726029b85a3fd0e05e9fbb04 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 5 Mar 2025 21:54:41 +0800 Subject: [PATCH 425/651] ASoC: Intel: soc-acpi-intel-ptl-match: add sdw multi function mockup codec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a SoundWire multi function mockup codec support. Signed-off-by: Bard Liao Reviewed-by: Liam Girdwood Reviewed-by: Péter Ujfalusi Link: https://patch.msgid.link/20250305135443.201884-8-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-ptl-match.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index 5c1ece913a18..28ee768efd57 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -374,6 +374,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-ptl-rt715-rt711-rt1308-mono.tplg", }, + { + .link_mask = BIT(0), + .links = sdw_mockup_multi_func, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-rt722.tplg", /* Reuse the existing tplg file */ + }, { .link_mask = BIT(0), .links = ptl_rvp, From 1ff07522690d2c2b67343099d2d046e88f71cddb Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 5 Mar 2025 21:54:42 +0800 Subject: [PATCH 426/651] ASoC: Intel: soc-acpi-intel-lnl-match: add cs42l43 6x cs35l56 support This add a match for cs42l43 on sdw link 2, 3 cs35l56 on sdw link 1 and 3. All speakers are aggregated. Signed-off-by: Bard Liao Reviewed-by: Liam Girdwood Link: https://patch.msgid.link/20250305135443.201884-9-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-lnl-match.c | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c index 1e24e969ad15..e04f6de746eb 100644 --- a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c @@ -37,6 +37,13 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint spk_1_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, +}; + static const struct snd_soc_acpi_endpoint spk_2_endpoint = { .num = 0, .aggregated = 1, @@ -51,6 +58,27 @@ static const struct snd_soc_acpi_endpoint spk_3_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint spk_4_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 4, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_5_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 5, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_6_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 6, + .group_id = 1, +}; + static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { { .num = 0, @@ -159,6 +187,33 @@ static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { }, }; +static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, +}; + static const struct snd_soc_acpi_adr_device cs35l56_2_l_adr[] = { { .adr = 0x00023001FA355601ull, @@ -204,6 +259,48 @@ static const struct snd_soc_acpi_adr_device cs35l56_3_lr_adr[] = { } }; +static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = { + { + .adr = 0x00013001fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_1_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + }, + { + .adr = 0x00013201fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP3" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = { + { + .adr = 0x00033301fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_4_endpoint, + .name_prefix = "AMP4" + }, + { + .adr = 0x00033401fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_5_endpoint, + .name_prefix = "AMP5" + }, + { + .adr = 0x00033501fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_6_endpoint, + .name_prefix = "AMP6" + } +}; + static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { { .adr = 0x00003001FA424301ull, @@ -213,6 +310,15 @@ static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { } }; +static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = { + { + .adr = 0x00023001fa424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints), + .endpoints = cs42l43_amp_spkagg_endpoints, + .name_prefix = "cs42l43" + } +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -408,6 +514,25 @@ static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0_cs35l56_l23[] = { {} }; +static const struct snd_soc_acpi_link_adr lnl_cs42l43_l2_cs35l56x6_l13[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs42l43_2_adr), + .adr_d = cs42l43_2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr), + .adr_d = cs35l56_1_3amp_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr), + .adr_d = cs35l56_3_3amp_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr lnl_rvp[] = { { .mask = BIT(0), @@ -570,6 +695,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-lnl-cs42l43-l0-cs35l56-l23.tplg", }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = lnl_cs42l43_l2_cs35l56x6_l13, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-cs42l43-l2-cs35l56x6-l13.tplg", + }, { .link_mask = BIT(0) | BIT(3), .links = lnl_cs42l43_l0_cs35l56_l3, From 7172d9ae29afd00c8ee9a8e3a4eba4cea5d5e403 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 5 Mar 2025 21:54:43 +0800 Subject: [PATCH 427/651] ASoC: Intel: soc-acpi-intel-ptl-match: add cs42l43 6x cs35l56 support This add a match for cs42l43 on sdw link 2, 3 cs35l56 on sdw link 1 and 3. All speakers are aggregated. Signed-off-by: Bard Liao Reviewed-by: Liam Girdwood Link: https://patch.msgid.link/20250305135443.201884-10-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-ptl-match.c | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index 28ee768efd57..a07526eb802b 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -50,6 +50,48 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint spk_1_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_2_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_3_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_4_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 4, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_5_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 5, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_6_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 6, + .group_id = 1, +}; + /* * Multi-function codecs with three endpoints created for * headset, amp and dmic functions. @@ -116,6 +158,84 @@ static const struct snd_soc_acpi_endpoint jack_amp_g1_dmic_endpoints_endpoints[] }, }; +static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 1, + .group_position = 0, + .group_id = 1, + }, +}; + +static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = { + { + .adr = 0x00023001fa424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints), + .endpoints = cs42l43_amp_spkagg_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = { + { + .adr = 0x00013001fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_1_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013101fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + }, + { + .adr = 0x00013201fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP3" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = { + { + .adr = 0x00033301fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_4_endpoint, + .name_prefix = "AMP4" + }, + { + .adr = 0x00033401fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_5_endpoint, + .name_prefix = "AMP5" + }, + { + .adr = 0x00033501fa355601ull, + .num_endpoints = 1, + .endpoints = &spk_6_endpoint, + .name_prefix = "AMP6" + } +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -251,6 +371,25 @@ static const struct snd_soc_acpi_adr_device rt1320_3_group2_adr[] = { } }; +static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs42l43_2_adr), + .adr_d = cs42l43_2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr), + .adr_d = cs35l56_1_3amp_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr), + .adr_d = cs35l56_3_3amp_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr ptl_rt722_only[] = { { .mask = BIT(0), @@ -374,6 +513,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-ptl-rt715-rt711-rt1308-mono.tplg", }, + { + .link_mask = BIT(1) | BIT(2) | BIT(3), + .links = ptl_cs42l43_l2_cs35l56x6_l13, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-cs42l43-l2-cs35l56x6-l13.tplg", + }, { .link_mask = BIT(0), .links = sdw_mockup_multi_func, From 269b844239149a9bbaba66518db99ebb06554a15 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 6 Mar 2025 10:42:33 +0000 Subject: [PATCH 428/651] ASoC: dapm: Fix changes to DECLARE_ADAU17X1_DSP_MUX_CTRL The changes to DECLARE_ADAU17X1_DSP_MUX_CTRL did avoid the issue with a compiler not liking all the macro indirection. However it introduced a new issue with respect to the mux not being declared static: sound/soc/codecs/adau17x1.c:275:8: sparse: sparse: symbol 'adau17x1_dac_mux' was not declared. Should it be static? sound/soc/codecs/adau17x1.c:278:8: sparse: sparse: symbol 'adau17x1_capture_mux' was not declared. Should it be static? Fix this up by going back to the inline declaration of the soc_enum, but just call SOC_ENUM_EXT directly rather than indirecting through SOC_DAPM_ENUM_EXT. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503061119.4QGlnOi6-lkp@intel.com/ Fixes: c951b20766f0 ("ASoC: dapm: Use ASoC control macros where possible") Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250306104233.1638625-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/adau17x1.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 2ebb5c90bdd9..0b6b0d2115eb 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -254,13 +254,11 @@ static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol, } #define DECLARE_ADAU17X1_DSP_MUX_CTRL(_name, _label, _stream, _text) \ - const struct soc_enum _name##_enum = \ - SOC_ENUM_SINGLE(SND_SOC_NOPM, _stream, \ - ARRAY_SIZE(_text), _text); \ const struct snd_kcontrol_new _name = \ - SOC_DAPM_ENUM_EXT(_label, _name##_enum, \ - adau17x1_dsp_mux_enum_get, \ - adau17x1_dsp_mux_enum_put) + SOC_ENUM_EXT(_label, (const struct soc_enum)\ + SOC_ENUM_SINGLE(SND_SOC_NOPM, _stream, \ + ARRAY_SIZE(_text), _text), \ + adau17x1_dsp_mux_enum_get, adau17x1_dsp_mux_enum_put) static const char * const adau17x1_dac_mux_text[] = { "DSP", From 2c2eadd07e747059ccd65e68cd1d1b23ca96b072 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 5 Mar 2025 18:27:32 +0100 Subject: [PATCH 429/651] ASoC: cs42l43: convert to SYSTEM_SLEEP_PM_OPS The custom suspend function causes a build warning when CONFIG_PM_SLEEP is disabled: sound/soc/codecs/cs42l43.c:2405:12: error: unused function 'cs42l43_codec_runtime_force_suspend' [-Werror,-Wunused-function] Change SET_SYSTEM_SLEEP_PM_OPS() to the newer SYSTEM_SLEEP_PM_OPS(), to avoid this. Fixes: 164b7dd4546b ("ASoC: cs42l43: Add jack delay debounce after suspend") Signed-off-by: Arnd Bergmann Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250305172738.3437513-1-arnd@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l43.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c index 4257dbefe9dd..e0d630c262f6 100644 --- a/sound/soc/codecs/cs42l43.c +++ b/sound/soc/codecs/cs42l43.c @@ -2417,7 +2417,7 @@ static int cs42l43_codec_runtime_force_suspend(struct device *dev) static const struct dev_pm_ops cs42l43_codec_pm_ops = { RUNTIME_PM_OPS(NULL, cs42l43_codec_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(cs42l43_codec_runtime_force_suspend, pm_runtime_force_resume) + SYSTEM_SLEEP_PM_OPS(cs42l43_codec_runtime_force_suspend, pm_runtime_force_resume) }; static const struct platform_device_id cs42l43_codec_id_table[] = { From 7a2ff0510c51462c0a979f5006d375a2b23d46e9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 6 Mar 2025 02:06:27 +0000 Subject: [PATCH 430/651] ASoC: soc-pcm: reuse dpcm_state_string() We already have dpcm_state_string(). Let's reuse it. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87y0xi52vx.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index c2d4becf0c3d..1b9ae03e83d0 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -144,7 +144,6 @@ static inline const char *soc_codec_dai_name(struct snd_soc_pcm_runtime *rtd) return (rtd)->dai_link->num_codecs == 1 ? snd_soc_rtd_to_codec(rtd, 0)->name : "multicodec"; } -#ifdef CONFIG_DEBUG_FS static const char *dpcm_state_string(enum snd_soc_dpcm_state state) { switch (state) { @@ -173,6 +172,7 @@ static const char *dpcm_state_string(enum snd_soc_dpcm_state state) return "unknown"; } +#ifdef CONFIG_DEBUG_FS static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, int stream, char *buf, size_t size) { @@ -1636,9 +1636,9 @@ void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, continue; if (be->dpcm[stream].users == 0) { - dev_err(be->dev, "ASoC: no users %s at close - state %d\n", + dev_err(be->dev, "ASoC: no users %s at close - state %s\n", snd_pcm_direction_name(stream), - be->dpcm[stream].state); + dpcm_state_string(be->dpcm[stream].state)); continue; } @@ -1687,9 +1687,9 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) /* first time the dpcm is open ? */ if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) { - dev_err(be->dev, "ASoC: too many users %s at open %d\n", + dev_err(be->dev, "ASoC: too many users %s at open %s\n", snd_pcm_direction_name(stream), - be->dpcm[stream].state); + dpcm_state_string(be->dpcm[stream].state)); continue; } @@ -1708,9 +1708,9 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) if (err < 0) { be->dpcm[stream].users--; if (be->dpcm[stream].users < 0) - dev_err(be->dev, "ASoC: no users %s at unwind %d\n", + dev_err(be->dev, "ASoC: no users %s at unwind %s\n", snd_pcm_direction_name(stream), - be->dpcm[stream].state); + dpcm_state_string(be->dpcm[stream].state)); be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; goto unwind; @@ -2572,8 +2572,8 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream) /* Only start the BE if the FE is ready */ if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_FREE || fe->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE) { - dev_err(fe->dev, "ASoC: FE %s is not ready %d\n", - fe->dai_link->name, fe->dpcm[stream].state); + dev_err(fe->dev, "ASoC: FE %s is not ready %s\n", + fe->dai_link->name, dpcm_state_string(fe->dpcm[stream].state)); ret = -EINVAL; goto disconnect; } From 5d5eceb9bb1050774dadc6919a258729f276fd00 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 6 Mar 2025 01:59:25 +0000 Subject: [PATCH 431/651] ASoC: soc-dai: add snd_soc_dai_mute_is_ctrled_at_trigger() Adds snd_soc_dai_mute_is_ctrled_at_trigger() to judge dai->driver->ops->mute_unmute_on_trigger flags Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/871pva6hs2.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 2 +- sound/soc/soc-dai.c | 12 ++++++++++-- sound/soc/soc-pcm.c | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index c3a3ba4b0bb7..d19ab5572d2b 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -193,7 +193,7 @@ int snd_soc_dai_prepare(struct snd_soc_dai *dai, /* Digital Audio Interface mute */ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute, int direction); - +int snd_soc_dai_mute_is_ctrled_at_trigger(struct snd_soc_dai *dai); int snd_soc_dai_get_channel_map(const struct snd_soc_dai *dai, unsigned int *tx_num, unsigned int *tx_slot, diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index 8f2b5b840bb0..a210089747d0 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -364,6 +364,14 @@ int snd_soc_dai_prepare(struct snd_soc_dai *dai, } EXPORT_SYMBOL_GPL(snd_soc_dai_prepare); +int snd_soc_dai_mute_is_ctrled_at_trigger(struct snd_soc_dai *dai) +{ + if (dai->driver->ops) + return dai->driver->ops->mute_unmute_on_trigger; + + return 0; +} + /** * snd_soc_dai_digital_mute - configure DAI system or master clock. * @dai: DAI @@ -620,7 +628,7 @@ int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, if (ret < 0) break; - if (dai->driver->ops && dai->driver->ops->mute_unmute_on_trigger) + if (snd_soc_dai_mute_is_ctrled_at_trigger(dai)) snd_soc_dai_digital_mute(dai, 0, substream->stream); soc_dai_mark_push(dai, substream, trigger); @@ -633,7 +641,7 @@ int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, if (rollback && !soc_dai_mark_match(dai, substream, trigger)) continue; - if (dai->driver->ops && dai->driver->ops->mute_unmute_on_trigger) + if (snd_soc_dai_mute_is_ctrled_at_trigger(dai)) snd_soc_dai_digital_mute(dai, 1, substream->stream); r = soc_dai_trigger(dai, substream, cmd); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 1b9ae03e83d0..403edd2fd8cf 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -949,7 +949,7 @@ static int __soc_pcm_prepare(struct snd_soc_pcm_runtime *rtd, SND_SOC_DAPM_STREAM_START); for_each_rtd_dais(rtd, i, dai) { - if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger) + if (!snd_soc_dai_mute_is_ctrled_at_trigger(dai)) snd_soc_dai_digital_mute(dai, 0, substream->stream); } @@ -1007,7 +1007,7 @@ static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd, soc_pcm_set_dai_params(dai, NULL); if (snd_soc_dai_stream_active(dai, substream->stream) == 1) { - if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger) + if (!snd_soc_dai_mute_is_ctrled_at_trigger(dai)) snd_soc_dai_digital_mute(dai, 1, substream->stream); } } From e3cd33ab17c33bd8f1a9df66ec83a15dd8f7afbb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 7 Mar 2025 09:42:42 +0100 Subject: [PATCH 432/651] ALSA: seq: Improve data consistency at polling snd_seq_poll() calls snd_seq_write_pool_allocated() that reads out a field in client->pool object, while it can be updated concurrently via ioctls, as reported by syzbot. The data race itself is harmless, as it's merely a poll() call, and the state is volatile. OTOH, the read out of poll object info from the caller side is fragile, and we can leave it better in snd_seq_pool_poll_wait() alone. A similar pattern is seen in snd_seq_kernel_client_write_poll(), too, which is called from the OSS sequencer. This patch drops the pool checks from the caller side and add the pool->lock in snd_seq_pool_poll_wait() for better data consistency. Reported-by: syzbot+2d373c9936c00d7e120c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/67c88903.050a0220.15b4b9.0028.GAE@google.com Link: https://patch.msgid.link/20250307084246.29271-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/seq/seq_clientmgr.c | 5 +---- sound/core/seq/seq_memory.c | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 073b56dc2225..659494e00c51 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1130,8 +1130,7 @@ static __poll_t snd_seq_poll(struct file *file, poll_table * wait) if (snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT) { /* check if data is available in the pool */ - if (!snd_seq_write_pool_allocated(client) || - snd_seq_pool_poll_wait(client->pool, file, wait)) + if (snd_seq_pool_poll_wait(client->pool, file, wait)) mask |= EPOLLOUT | EPOLLWRNORM; } @@ -2566,8 +2565,6 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table if (client == NULL) return -ENXIO; - if (! snd_seq_write_pool_allocated(client)) - return 1; if (snd_seq_pool_poll_wait(client->pool, file, wait)) return 1; return 0; diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index 20155e3e87c6..ccde0ca3d208 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -427,6 +427,7 @@ int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, poll_table *wait) { poll_wait(file, &pool->output_sleep, wait); + guard(spinlock_irq)(&pool->lock); return snd_seq_output_ok(pool); } From ef749c8d9573d256da139b6ebccceb678ec00eaa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 7 Mar 2025 09:42:43 +0100 Subject: [PATCH 433/651] ALSA: seq: Avoid client data changes during proc reads The proc read of each client should protect against the concurrent data changes to keep the data consistent; although they are supposed to be safe and won't crash things, it doesn't guarantee the consistency between the read values. Take client->ioctl_mutex for protecting against the concurrent changes. Link: https://patch.msgid.link/20250307084246.29271-2-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/seq/seq_clientmgr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 659494e00c51..fe7cd0649c98 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -2706,6 +2706,7 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry, continue; } + mutex_lock(&client->ioctl_mutex); snd_iprintf(buffer, "Client %3d : \"%s\" [%s %s]\n", c, client->name, client->type == USER_CLIENT ? "User" : "Kernel", @@ -2723,6 +2724,7 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry, snd_iprintf(buffer, " Input pool :\n"); snd_seq_info_pool(buffer, client->data.user.fifo->pool, " "); } + mutex_unlock(&client->ioctl_mutex); snd_seq_client_unlock(client); } } From 69823334200029767de785d30acf74e4872a11d3 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:09 +0200 Subject: [PATCH 434/651] ASoC: SOF: Intel: mtl: Split up dsp_ops setup code Move the sof_mtl_ops and sof_mtl_ops_init() to pci-mtl.c as local static and add a 'generic' sof_mtl_set_ops() function as replacement exported function to fill the dsp_ops structure. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.h | 2 -- sound/soc/sof/intel/mtl.c | 44 +++++++++++++++++------------------ sound/soc/sof/intel/mtl.h | 2 ++ sound/soc/sof/intel/pci-mtl.c | 8 +++++++ 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index ee4ccc1a5490..92b7402e752e 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -913,8 +913,6 @@ extern struct snd_sof_dsp_ops sof_tgl_ops; int sof_tgl_ops_init(struct snd_sof_dev *sdev); extern struct snd_sof_dsp_ops sof_icl_ops; int sof_icl_ops_init(struct snd_sof_dev *sdev); -extern struct snd_sof_dsp_ops sof_mtl_ops; -int sof_mtl_ops_init(struct snd_sof_dev *sdev); extern struct snd_sof_dsp_ops sof_lnl_ops; int sof_lnl_ops_init(struct snd_sof_dev *sdev); diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 4a6b1d56171e..ec563214dd1a 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -712,43 +712,40 @@ int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core) } EXPORT_SYMBOL_NS(mtl_dsp_core_put, "SND_SOC_SOF_INTEL_MTL"); -/* Meteorlake ops */ -struct snd_sof_dsp_ops sof_mtl_ops; - -int sof_mtl_ops_init(struct snd_sof_dev *sdev) +int sof_mtl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops) { struct sof_ipc4_fw_data *ipc4_data; /* common defaults */ - memcpy(&sof_mtl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops)); + memcpy(dsp_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops)); /* shutdown */ - sof_mtl_ops.shutdown = hda_dsp_shutdown; + dsp_ops->shutdown = hda_dsp_shutdown; /* doorbell */ - sof_mtl_ops.irq_thread = mtl_ipc_irq_thread; + dsp_ops->irq_thread = mtl_ipc_irq_thread; /* ipc */ - sof_mtl_ops.send_msg = mtl_ipc_send_msg; - sof_mtl_ops.get_mailbox_offset = mtl_dsp_ipc_get_mailbox_offset; - sof_mtl_ops.get_window_offset = mtl_dsp_ipc_get_window_offset; + dsp_ops->send_msg = mtl_ipc_send_msg; + dsp_ops->get_mailbox_offset = mtl_dsp_ipc_get_mailbox_offset; + dsp_ops->get_window_offset = mtl_dsp_ipc_get_window_offset; /* debug */ - sof_mtl_ops.debug_map = mtl_dsp_debugfs; - sof_mtl_ops.debug_map_count = ARRAY_SIZE(mtl_dsp_debugfs); - sof_mtl_ops.dbg_dump = mtl_dsp_dump; - sof_mtl_ops.ipc_dump = mtl_ipc_dump; + dsp_ops->debug_map = mtl_dsp_debugfs; + dsp_ops->debug_map_count = ARRAY_SIZE(mtl_dsp_debugfs); + dsp_ops->dbg_dump = mtl_dsp_dump; + dsp_ops->ipc_dump = mtl_ipc_dump; /* pre/post fw run */ - sof_mtl_ops.pre_fw_run = mtl_dsp_pre_fw_run; - sof_mtl_ops.post_fw_run = mtl_dsp_post_fw_run; + dsp_ops->pre_fw_run = mtl_dsp_pre_fw_run; + dsp_ops->post_fw_run = mtl_dsp_post_fw_run; /* parse platform specific extended manifest */ - sof_mtl_ops.parse_platform_ext_manifest = NULL; + dsp_ops->parse_platform_ext_manifest = NULL; /* dsp core get/put */ - sof_mtl_ops.core_get = mtl_dsp_core_get; - sof_mtl_ops.core_put = mtl_dsp_core_put; + dsp_ops->core_get = mtl_dsp_core_get; + dsp_ops->core_put = mtl_dsp_core_put; sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); if (!sdev->private) @@ -764,13 +761,14 @@ int sof_mtl_ops_init(struct snd_sof_dev *sdev) /* External library loading support */ ipc4_data->load_library = hda_dsp_ipc4_load_library; - /* set DAI ops */ - hda_set_dai_drv_ops(sdev, &sof_mtl_ops); + dsp_ops->set_power_state = hda_dsp_set_power_state_ipc4; - sof_mtl_ops.set_power_state = hda_dsp_set_power_state_ipc4; + /* set DAI ops */ + hda_set_dai_drv_ops(sdev, dsp_ops); return 0; -}; +} +EXPORT_SYMBOL_NS(sof_mtl_set_ops, "SND_SOC_SOF_INTEL_MTL"); const struct sof_intel_dsp_desc mtl_chip_info = { .cores_num = 3, diff --git a/sound/soc/sof/intel/mtl.h b/sound/soc/sof/intel/mtl.h index 9ab4b21c960e..4d098dae2973 100644 --- a/sound/soc/sof/intel/mtl.h +++ b/sound/soc/sof/intel/mtl.h @@ -145,3 +145,5 @@ void mtl_ipc_dump(struct snd_sof_dev *sdev); int mtl_dsp_core_get(struct snd_sof_dev *sdev, int core); int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core); + +int sof_mtl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops); diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c index 71f711cf8599..c5048a4a56be 100644 --- a/sound/soc/sof/intel/pci-mtl.c +++ b/sound/soc/sof/intel/pci-mtl.c @@ -20,6 +20,14 @@ #include "hda.h" #include "mtl.h" +/* Meteorlake ops */ +static struct snd_sof_dsp_ops sof_mtl_ops; + +static int sof_mtl_ops_init(struct snd_sof_dev *sdev) +{ + return sof_mtl_set_ops(sdev, &sof_mtl_ops); +} + static const struct sof_dev_desc mtl_desc = { .use_acpi_target_states = true, .machines = snd_soc_acpi_intel_mtl_machines, From 0d2d276f53ea3ba1686619cde503d9748f58a834 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:10 +0200 Subject: [PATCH 435/651] ASoC: SOF: Intel: lnl/ptl: Only set dsp_ops which differs from MTL LunarLake is a next generation in ACE architecture and most of the dsp_ops are the same as it is in previous generation. Use the sof_mtl_set_ops() to get the ops used for mtl and update the ones that needs different functions for LNL. Update pci-ptl at the same time to use the LNL dsp_ops as before. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.h | 2 - sound/soc/sof/intel/lnl.c | 86 +++++++---------------------------- sound/soc/sof/intel/lnl.h | 2 + sound/soc/sof/intel/pci-lnl.c | 12 +++-- sound/soc/sof/intel/pci-ptl.c | 15 ++++-- 5 files changed, 38 insertions(+), 79 deletions(-) diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 92b7402e752e..76154627fc17 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -913,8 +913,6 @@ extern struct snd_sof_dsp_ops sof_tgl_ops; int sof_tgl_ops_init(struct snd_sof_dev *sdev); extern struct snd_sof_dsp_ops sof_icl_ops; int sof_icl_ops_init(struct snd_sof_dev *sdev); -extern struct snd_sof_dsp_ops sof_lnl_ops; -int sof_lnl_ops_init(struct snd_sof_dev *sdev); extern const struct sof_intel_dsp_desc skl_chip_info; extern const struct sof_intel_dsp_desc apl_chip_info; diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c index 793d8539821d..ffda39ca3606 100644 --- a/sound/soc/sof/intel/lnl.c +++ b/sound/soc/sof/intel/lnl.c @@ -20,17 +20,6 @@ #include "lnl.h" #include -/* LunarLake ops */ -struct snd_sof_dsp_ops sof_lnl_ops; -EXPORT_SYMBOL_NS(sof_lnl_ops, "SND_SOC_SOF_INTEL_LNL"); - -static const struct snd_sof_debugfs_map lnl_dsp_debugfs[] = { - {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS}, - {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS}, - {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS}, - {"fw_regs", HDA_DSP_BAR, MTL_SRAM_WINDOW_OFFSET(0), 0x1000, SOF_DEBUGFS_ACCESS_D0_ONLY}, -}; - /* this helps allows the DSP to setup DMIC/SSP */ static int hdac_bus_offload_dmic_ssp(struct hdac_bus *bus, bool enable) { @@ -111,78 +100,32 @@ static int lnl_dsp_post_fw_run(struct snd_sof_dev *sdev) return 0; } -int sof_lnl_ops_init(struct snd_sof_dev *sdev) +int sof_lnl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops) { - struct sof_ipc4_fw_data *ipc4_data; + int ret; - /* common defaults */ - memcpy(&sof_lnl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops)); + ret = sof_mtl_set_ops(sdev, dsp_ops); + if (ret) + return ret; /* probe/remove */ if (!sdev->dspless_mode_selected) { - sof_lnl_ops.probe = lnl_hda_dsp_probe; - sof_lnl_ops.remove = lnl_hda_dsp_remove; + dsp_ops->probe = lnl_hda_dsp_probe; + dsp_ops->remove = lnl_hda_dsp_remove; } - /* shutdown */ - sof_lnl_ops.shutdown = hda_dsp_shutdown; - - /* doorbell */ - sof_lnl_ops.irq_thread = mtl_ipc_irq_thread; - - /* ipc */ - sof_lnl_ops.send_msg = mtl_ipc_send_msg; - sof_lnl_ops.get_mailbox_offset = mtl_dsp_ipc_get_mailbox_offset; - sof_lnl_ops.get_window_offset = mtl_dsp_ipc_get_window_offset; - - /* debug */ - sof_lnl_ops.debug_map = lnl_dsp_debugfs; - sof_lnl_ops.debug_map_count = ARRAY_SIZE(lnl_dsp_debugfs); - sof_lnl_ops.dbg_dump = mtl_dsp_dump; - sof_lnl_ops.ipc_dump = mtl_ipc_dump; - - /* pre/post fw run */ - sof_lnl_ops.pre_fw_run = mtl_dsp_pre_fw_run; - sof_lnl_ops.post_fw_run = lnl_dsp_post_fw_run; - - /* parse platform specific extended manifest */ - sof_lnl_ops.parse_platform_ext_manifest = NULL; - - /* dsp core get/put */ - /* TODO: add core_get and core_put */ + /* post fw run */ + dsp_ops->post_fw_run = lnl_dsp_post_fw_run; /* PM */ if (!sdev->dspless_mode_selected) { - sof_lnl_ops.resume = lnl_hda_dsp_resume; - sof_lnl_ops.runtime_resume = lnl_hda_dsp_runtime_resume; + dsp_ops->resume = lnl_hda_dsp_resume; + dsp_ops->runtime_resume = lnl_hda_dsp_runtime_resume; } - /* dsp core get/put */ - sof_lnl_ops.core_get = mtl_dsp_core_get; - sof_lnl_ops.core_put = mtl_dsp_core_put; - - sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); - if (!sdev->private) - return -ENOMEM; - - ipc4_data = sdev->private; - ipc4_data->manifest_fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET; - - ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_2; - - ipc4_data->fw_context_save = true; - - /* External library loading support */ - ipc4_data->load_library = hda_dsp_ipc4_load_library; - - /* set DAI ops */ - hda_set_dai_drv_ops(sdev, &sof_lnl_ops); - - sof_lnl_ops.set_power_state = hda_dsp_set_power_state_ipc4; - return 0; -}; -EXPORT_SYMBOL_NS(sof_lnl_ops_init, "SND_SOC_SOF_INTEL_LNL"); +} +EXPORT_SYMBOL_NS(sof_lnl_set_ops, "SND_SOC_SOF_INTEL_LNL"); /* Check if an SDW IRQ occurred */ static bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) @@ -262,3 +205,6 @@ const struct sof_intel_dsp_desc ptl_chip_info = { .hw_ip_version = SOF_INTEL_ACE_3_0, }; EXPORT_SYMBOL_NS(ptl_chip_info, "SND_SOC_SOF_INTEL_LNL"); + +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); diff --git a/sound/soc/sof/intel/lnl.h b/sound/soc/sof/intel/lnl.h index 79101af84b2e..e585b93d2b63 100644 --- a/sound/soc/sof/intel/lnl.h +++ b/sound/soc/sof/intel/lnl.h @@ -12,4 +12,6 @@ #define LNL_DSP_REG_HFDSC 0x160200 /* DSP core0 status */ #define LNL_DSP_REG_HFDEC 0x160204 /* DSP core0 error */ +int sof_lnl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops); + #endif /* __SOF_INTEL_LNL_H */ diff --git a/sound/soc/sof/intel/pci-lnl.c b/sound/soc/sof/intel/pci-lnl.c index 8d4d74ac4398..91b9cff8c4ca 100644 --- a/sound/soc/sof/intel/pci-lnl.c +++ b/sound/soc/sof/intel/pci-lnl.c @@ -18,7 +18,15 @@ /* platform specific devices */ #include "hda.h" -#include "mtl.h" +#include "lnl.h" + +/* LunarLake ops */ +static struct snd_sof_dsp_ops sof_lnl_ops; + +static int sof_lnl_ops_init(struct snd_sof_dev *sdev) +{ + return sof_lnl_set_ops(sdev, &sof_lnl_ops); +} static const struct sof_dev_desc lnl_desc = { .use_acpi_target_states = true, @@ -73,6 +81,4 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for LunarLake platforms"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); -MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL"); -MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/pci-ptl.c b/sound/soc/sof/intel/pci-ptl.c index c4fb6a2441b7..32f93723ee66 100644 --- a/sound/soc/sof/intel/pci-ptl.c +++ b/sound/soc/sof/intel/pci-ptl.c @@ -16,7 +16,15 @@ /* platform specific devices */ #include "hda.h" -#include "mtl.h" +#include "lnl.h" + +/* PantherLake ops */ +static struct snd_sof_dsp_ops sof_ptl_ops; + +static int sof_ptl_ops_init(struct snd_sof_dev *sdev) +{ + return sof_lnl_set_ops(sdev, &sof_ptl_ops); +} static const struct sof_dev_desc ptl_desc = { .use_acpi_target_states = true, @@ -43,8 +51,8 @@ static const struct sof_dev_desc ptl_desc = { [SOF_IPC_TYPE_4] = "sof-ptl.ri", }, .nocodec_tplg_filename = "sof-ptl-nocodec.tplg", - .ops = &sof_lnl_ops, - .ops_init = sof_lnl_ops_init, + .ops = &sof_ptl_ops, + .ops_init = sof_ptl_ops_init, }; /* PCI IDs */ @@ -73,6 +81,5 @@ MODULE_DESCRIPTION("SOF support for PantherLake platforms"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_LNL"); -MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL"); MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); From 80416226920c21e806f93bd0930d67557f41600f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:11 +0200 Subject: [PATCH 436/651] ASoC: SOF: Intel: mtl: Stop exporting dsp_ops callback functions There is no need to export individual dsp_ops functions anymore as the callbacks are filled now by sof_mtl_set_ops() Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/mtl.c | 30 ++++++++++-------------------- sound/soc/sof/intel/mtl.h | 15 --------------- 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index ec563214dd1a..2242c96bfa51 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -96,7 +96,7 @@ static bool mtl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) return false; } -int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) +static int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) { struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; struct sof_ipc4_msg *msg_data = msg->msg_data; @@ -122,7 +122,6 @@ int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) return 0; } -EXPORT_SYMBOL_NS(mtl_ipc_send_msg, "SND_SOC_SOF_INTEL_MTL"); void mtl_enable_ipc_interrupts(struct snd_sof_dev *sdev) { @@ -238,7 +237,7 @@ int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable) EXPORT_SYMBOL_NS(mtl_enable_interrupts, "SND_SOC_SOF_INTEL_MTL"); /* pre fw run operations */ -int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) +static int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) { struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; u32 dsphfpwrsts; @@ -298,9 +297,8 @@ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) return ret; } -EXPORT_SYMBOL_NS(mtl_dsp_pre_fw_run, "SND_SOC_SOF_INTEL_MTL"); -int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) +static int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) { int ret; @@ -325,9 +323,8 @@ int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) hda_sdw_int_enable(sdev, true); return 0; } -EXPORT_SYMBOL_NS(mtl_dsp_post_fw_run, "SND_SOC_SOF_INTEL_MTL"); -void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags) +static void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags) { char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR; u32 fwsts; @@ -343,7 +340,6 @@ void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags) sof_ipc4_intel_dump_telemetry_state(sdev, flags); } -EXPORT_SYMBOL_NS(mtl_dsp_dump, "SND_SOC_SOF_INTEL_MTL"); static bool mtl_dsp_primary_core_is_enabled(struct snd_sof_dev *sdev) { @@ -559,7 +555,7 @@ err: } EXPORT_SYMBOL_NS(mtl_dsp_cl_init, "SND_SOC_SOF_INTEL_MTL"); -irqreturn_t mtl_ipc_irq_thread(int irq, void *context) +static irqreturn_t mtl_ipc_irq_thread(int irq, void *context) { struct sof_ipc4_msg notification_data = {{ 0 }}; struct snd_sof_dev *sdev = context; @@ -641,21 +637,18 @@ irqreturn_t mtl_ipc_irq_thread(int irq, void *context) return IRQ_HANDLED; } -EXPORT_SYMBOL_NS(mtl_ipc_irq_thread, "SND_SOC_SOF_INTEL_MTL"); -int mtl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) +static int mtl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) { return MTL_DSP_MBOX_UPLINK_OFFSET; } -EXPORT_SYMBOL_NS(mtl_dsp_ipc_get_mailbox_offset, "SND_SOC_SOF_INTEL_MTL"); -int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id) +static int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id) { return MTL_SRAM_WINDOW_OFFSET(id); } -EXPORT_SYMBOL_NS(mtl_dsp_ipc_get_window_offset, "SND_SOC_SOF_INTEL_MTL"); -void mtl_ipc_dump(struct snd_sof_dev *sdev) +static void mtl_ipc_dump(struct snd_sof_dev *sdev) { u32 hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl; @@ -671,7 +664,6 @@ void mtl_ipc_dump(struct snd_sof_dev *sdev) "Host IPC initiator: %#x|%#x|%#x, target: %#x|%#x|%#x, ctl: %#x\n", hipcidr, hipcidd, hipcida, hipctdr, hipctdd, hipctda, hipcctl); } -EXPORT_SYMBOL_NS(mtl_ipc_dump, "SND_SOC_SOF_INTEL_MTL"); static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev) { @@ -680,7 +672,7 @@ static int mtl_dsp_disable_interrupts(struct snd_sof_dev *sdev) return mtl_enable_interrupts(sdev, false); } -int mtl_dsp_core_get(struct snd_sof_dev *sdev, int core) +static int mtl_dsp_core_get(struct snd_sof_dev *sdev, int core) { const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; @@ -692,9 +684,8 @@ int mtl_dsp_core_get(struct snd_sof_dev *sdev, int core) return 0; } -EXPORT_SYMBOL_NS(mtl_dsp_core_get, "SND_SOC_SOF_INTEL_MTL"); -int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core) +static int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core) { const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; int ret; @@ -710,7 +701,6 @@ int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core) return 0; } -EXPORT_SYMBOL_NS(mtl_dsp_core_put, "SND_SOC_SOF_INTEL_MTL"); int sof_mtl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops) { diff --git a/sound/soc/sof/intel/mtl.h b/sound/soc/sof/intel/mtl.h index 4d098dae2973..e01a1536709e 100644 --- a/sound/soc/sof/intel/mtl.h +++ b/sound/soc/sof/intel/mtl.h @@ -122,28 +122,13 @@ #define MTL_DSP_REG_HfIMRIS1_IU_MASK BIT(0) bool mtl_dsp_check_ipc_irq(struct snd_sof_dev *sdev); -int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); void mtl_enable_ipc_interrupts(struct snd_sof_dev *sdev); void mtl_disable_ipc_interrupts(struct snd_sof_dev *sdev); int mtl_enable_interrupts(struct snd_sof_dev *sdev, bool enable); -int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev); -int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev); -void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags); - int mtl_power_down_dsp(struct snd_sof_dev *sdev); int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot); -irqreturn_t mtl_ipc_irq_thread(int irq, void *context); - -int mtl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev); -int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id); - -void mtl_ipc_dump(struct snd_sof_dev *sdev); - -int mtl_dsp_core_get(struct snd_sof_dev *sdev, int core); -int mtl_dsp_core_put(struct snd_sof_dev *sdev, int core); - int sof_mtl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops); From 8aeb7d2c3fc315e629d252cd601598a5af74bbb0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:12 +0200 Subject: [PATCH 437/651] ASoC: SOF: Intel: Create ptl.c as placeholder for Panther Lake features Create a minimal placeholder to make it possible to add code to handle the new features of Panther Lake compared to MTL/LNL. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/Makefile | 2 +- sound/soc/sof/intel/lnl.c | 33 ++++------------------ sound/soc/sof/intel/lnl.h | 4 +++ sound/soc/sof/intel/pci-ptl.c | 6 ++-- sound/soc/sof/intel/ptl.c | 52 +++++++++++++++++++++++++++++++++++ sound/soc/sof/intel/ptl.h | 14 ++++++++++ 6 files changed, 79 insertions(+), 32 deletions(-) create mode 100644 sound/soc/sof/intel/ptl.c create mode 100644 sound/soc/sof/intel/ptl.h diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index f40daa616803..675f9fc92dde 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -34,7 +34,7 @@ snd-sof-pci-intel-icl-y := pci-icl.o icl.o snd-sof-pci-intel-tgl-y := pci-tgl.o tgl.o snd-sof-pci-intel-mtl-y := pci-mtl.o mtl.o snd-sof-pci-intel-lnl-y := pci-lnl.o lnl.o -snd-sof-pci-intel-ptl-y := pci-ptl.o +snd-sof-pci-intel-ptl-y := pci-ptl.o ptl.o obj-$(CONFIG_SND_SOC_SOF_MERRIFIELD) += snd-sof-pci-intel-tng.o obj-$(CONFIG_SND_SOC_SOF_INTEL_SKL) += snd-sof-pci-intel-skl.o diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c index ffda39ca3606..2f3222040f98 100644 --- a/sound/soc/sof/intel/lnl.c +++ b/sound/soc/sof/intel/lnl.c @@ -128,20 +128,22 @@ int sof_lnl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops) EXPORT_SYMBOL_NS(sof_lnl_set_ops, "SND_SOC_SOF_INTEL_LNL"); /* Check if an SDW IRQ occurred */ -static bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) +bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); return hdac_bus_eml_check_interrupt(bus, true, AZX_REG_ML_LEPTR_ID_SDW); } +EXPORT_SYMBOL_NS(lnl_dsp_check_sdw_irq, "SND_SOC_SOF_INTEL_LNL"); -static int lnl_dsp_disable_interrupts(struct snd_sof_dev *sdev) +int lnl_dsp_disable_interrupts(struct snd_sof_dev *sdev) { mtl_disable_ipc_interrupts(sdev); return mtl_enable_interrupts(sdev, false); } +EXPORT_SYMBOL_NS(lnl_dsp_disable_interrupts, "SND_SOC_SOF_INTEL_LNL"); -static bool lnl_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) +bool lnl_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); u16 wake_sts; @@ -157,6 +159,7 @@ static bool lnl_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) /* filter out the range of SDIs that can be set for SoundWire */ return wake_sts & GENMASK(SDW_MAX_DEVICES, SDW_INTEL_DEV_NUM_IDA_MIN); } +EXPORT_SYMBOL_NS(lnl_sdw_check_wakeen_irq, "SND_SOC_SOF_INTEL_LNL"); const struct sof_intel_dsp_desc lnl_chip_info = { .cores_num = 5, @@ -182,29 +185,5 @@ const struct sof_intel_dsp_desc lnl_chip_info = { .hw_ip_version = SOF_INTEL_ACE_2_0, }; -const struct sof_intel_dsp_desc ptl_chip_info = { - .cores_num = 5, - .init_core_mask = BIT(0), - .host_managed_cores_mask = BIT(0), - .ipc_req = MTL_DSP_REG_HFIPCXIDR, - .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY, - .ipc_ack = MTL_DSP_REG_HFIPCXIDA, - .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE, - .ipc_ctl = MTL_DSP_REG_HFIPCXCTL, - .rom_status_reg = LNL_DSP_REG_HFDSC, - .rom_init_timeout = 300, - .ssp_count = MTL_SSP_COUNT, - .d0i3_offset = MTL_HDA_VS_D0I3C, - .read_sdw_lcount = hda_sdw_check_lcount_ext, - .check_sdw_irq = lnl_dsp_check_sdw_irq, - .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq, - .check_ipc_irq = mtl_dsp_check_ipc_irq, - .cl_init = mtl_dsp_cl_init, - .power_down_dsp = mtl_power_down_dsp, - .disable_interrupts = lnl_dsp_disable_interrupts, - .hw_ip_version = SOF_INTEL_ACE_3_0, -}; -EXPORT_SYMBOL_NS(ptl_chip_info, "SND_SOC_SOF_INTEL_LNL"); - MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL"); MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); diff --git a/sound/soc/sof/intel/lnl.h b/sound/soc/sof/intel/lnl.h index e585b93d2b63..2837f818ac51 100644 --- a/sound/soc/sof/intel/lnl.h +++ b/sound/soc/sof/intel/lnl.h @@ -14,4 +14,8 @@ int sof_lnl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops); +bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev); +int lnl_dsp_disable_interrupts(struct snd_sof_dev *sdev); +bool lnl_sdw_check_wakeen_irq(struct snd_sof_dev *sdev); + #endif /* __SOF_INTEL_LNL_H */ diff --git a/sound/soc/sof/intel/pci-ptl.c b/sound/soc/sof/intel/pci-ptl.c index 32f93723ee66..3812ab6d99c0 100644 --- a/sound/soc/sof/intel/pci-ptl.c +++ b/sound/soc/sof/intel/pci-ptl.c @@ -16,14 +16,14 @@ /* platform specific devices */ #include "hda.h" -#include "lnl.h" +#include "ptl.h" /* PantherLake ops */ static struct snd_sof_dsp_ops sof_ptl_ops; static int sof_ptl_ops_init(struct snd_sof_dev *sdev) { - return sof_lnl_set_ops(sdev, &sof_ptl_ops); + return sof_ptl_set_ops(sdev, &sof_ptl_ops); } static const struct sof_dev_desc ptl_desc = { @@ -80,6 +80,4 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF support for PantherLake platforms"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_GENERIC"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); -MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_LNL"); -MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); MODULE_IMPORT_NS("SND_SOC_SOF_PCI_DEV"); diff --git a/sound/soc/sof/intel/ptl.c b/sound/soc/sof/intel/ptl.c new file mode 100644 index 000000000000..ae8e9e08ad2a --- /dev/null +++ b/sound/soc/sof/intel/ptl.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2025 Intel Corporation + +/* + * Hardware interface for audio DSP on PantherLake. + */ + +#include +#include +#include +#include "../ipc4-priv.h" +#include "../ops.h" +#include "hda.h" +#include "hda-ipc.h" +#include "../sof-audio.h" +#include "mtl.h" +#include "lnl.h" +#include "ptl.h" + +int sof_ptl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops) +{ + return sof_lnl_set_ops(sdev, dsp_ops); +} +EXPORT_SYMBOL_NS(sof_ptl_set_ops, "SND_SOC_SOF_INTEL_PTL"); + +const struct sof_intel_dsp_desc ptl_chip_info = { + .cores_num = 5, + .init_core_mask = BIT(0), + .host_managed_cores_mask = BIT(0), + .ipc_req = MTL_DSP_REG_HFIPCXIDR, + .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY, + .ipc_ack = MTL_DSP_REG_HFIPCXIDA, + .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE, + .ipc_ctl = MTL_DSP_REG_HFIPCXCTL, + .rom_status_reg = LNL_DSP_REG_HFDSC, + .rom_init_timeout = 300, + .ssp_count = MTL_SSP_COUNT, + .d0i3_offset = MTL_HDA_VS_D0I3C, + .read_sdw_lcount = hda_sdw_check_lcount_ext, + .check_sdw_irq = lnl_dsp_check_sdw_irq, + .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq, + .check_ipc_irq = mtl_dsp_check_ipc_irq, + .cl_init = mtl_dsp_cl_init, + .power_down_dsp = mtl_power_down_dsp, + .disable_interrupts = lnl_dsp_disable_interrupts, + .hw_ip_version = SOF_INTEL_ACE_3_0, +}; + +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL"); +MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_LNL"); +MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); diff --git a/sound/soc/sof/intel/ptl.h b/sound/soc/sof/intel/ptl.h new file mode 100644 index 000000000000..186f7c835acb --- /dev/null +++ b/sound/soc/sof/intel/ptl.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2025 Intel Corporation + */ + +#ifndef __SOF_INTEL_PTL_H +#define __SOF_INTEL_PTL_H + +int sof_ptl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops); + +#endif /* __SOF_INTEL_PTL_H */ From eea84a7f0cdb693c261a7cf84bd4b3d81479c9a6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:13 +0200 Subject: [PATCH 438/651] ASoC: SOF: ipc4: Add support for Intel HW managed mic privacy messaging ACE3 (Panther Lake) introduced support for microphone privacy feature which can - in hardware - mute incoming audio data based on a state of a physical switch. The change in the privacy state is delivered through interface IP blocks and can only be handled by the link owner. In Intel platforms Soundwire is for example host owned, so the interrupt can only be handled by the host. Since the input stream is going to be muted by hardware, the host needs to send a message to firmware about the change in privacy so it can execute a fade out/in to enhance user experience. The support for microphone privacy can be queried from the HW_CONFIG data under the INTEL_MIC_PRIVACY_CAP tuple. This is Intel specific data, the core will pass it to platform code if the intel_configure_mic_privacy() callback is provided. Platform code can call sof_ipc4_mic_privacy_state_change() to send the IPC message to the firmware on state change. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-6-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- include/sound/sof/ipc4/header.h | 13 +++++++++++++ sound/soc/sof/ipc4-loader.c | 33 +++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-priv.h | 5 +++++ sound/soc/sof/ipc4.c | 18 ++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h index 0c0cf47946b1..f71d04736d17 100644 --- a/include/sound/sof/ipc4/header.h +++ b/include/sound/sof/ipc4/header.h @@ -396,6 +396,7 @@ enum sof_ipc4_base_fw_params { SOF_IPC4_FW_PARAM_MODULES_INFO_GET, SOF_IPC4_FW_PARAM_LIBRARIES_INFO_GET = 16, SOF_IPC4_FW_PARAM_SYSTEM_TIME = 20, + SOF_IPC4_FW_PARAM_MIC_PRIVACY_STATE_CHANGE = 35, }; enum sof_ipc4_fw_config_params { @@ -446,6 +447,18 @@ struct sof_ipc4_dx_state_info { uint32_t dx_mask; } __packed __aligned(4); +enum sof_ipc4_hw_config_params { + SOF_IPC4_HW_CFG_INTEL_MIC_PRIVACY_CAPS = 11, +}; + +#define SOF_IPC_INTEL_MIC_PRIVACY_VERSION_PTL 1 + +struct sof_ipc4_intel_mic_privacy_cap { + uint32_t version; + uint32_t capabilities_length; + uint32_t capabilities[]; +} __packed; + /* Reply messages */ /* diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c index 6ad1ef0e53e8..d2f534d65edf 100644 --- a/sound/soc/sof/ipc4-loader.c +++ b/sound/soc/sof/ipc4-loader.c @@ -502,6 +502,39 @@ int sof_ipc4_query_fw_configuration(struct snd_sof_dev *sdev) offset += sizeof(*tuple) + tuple->size; } + /* Get the hardware configuration */ + msg.primary = SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + msg.primary |= SOF_IPC4_MOD_ID(SOF_IPC4_MOD_INIT_BASEFW_MOD_ID); + msg.primary |= SOF_IPC4_MOD_INSTANCE(SOF_IPC4_MOD_INIT_BASEFW_INSTANCE_ID); + msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_FW_PARAM_HW_CONFIG_GET); + + msg.data_size = sdev->ipc->max_payload_size; + + ret = iops->set_get_data(sdev, &msg, msg.data_size, false); + if (ret) + goto out; + + offset = 0; + while (offset < msg.data_size) { + tuple = (struct sof_ipc4_tuple *)((u8 *)msg.data_ptr + offset); + + switch (tuple->type) { + case SOF_IPC4_HW_CFG_INTEL_MIC_PRIVACY_CAPS: + if (ipc4_data->intel_configure_mic_privacy) { + struct sof_ipc4_intel_mic_privacy_cap *caps; + + caps = (struct sof_ipc4_intel_mic_privacy_cap *)tuple->value; + ipc4_data->intel_configure_mic_privacy(sdev, caps); + } + break; + default: + break; + } + + offset += sizeof(*tuple) + tuple->size; + } + out: kfree(msg.data_ptr); diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index b798810eff91..58b032820683 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -11,6 +11,7 @@ #include #include +#include #include "sof-priv.h" /* The DSP window indices are fixed */ @@ -89,6 +90,8 @@ struct sof_ipc4_fw_data { int (*load_library)(struct snd_sof_dev *sdev, struct sof_ipc4_fw_library *fw_lib, bool reload); + void (*intel_configure_mic_privacy)(struct snd_sof_dev *sdev, + struct sof_ipc4_intel_mic_privacy_cap *caps); struct mutex pipeline_state_mutex; /* protect pipeline triggers, ref counts and states */ }; @@ -118,4 +121,6 @@ void sof_ipc4_update_cpc_from_manifest(struct snd_sof_dev *sdev, size_t sof_ipc4_find_debug_slot_offset_by_type(struct snd_sof_dev *sdev, u32 slot_type); +void sof_ipc4_mic_privacy_state_change(struct snd_sof_dev *sdev, bool state); + #endif diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index 2ed0c52fb2f1..37e837b22ac8 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -851,3 +851,21 @@ const struct sof_ipc_ops ipc4_ops = { .pcm = &ipc4_pcm_ops, .fw_tracing = &ipc4_mtrace_ops, }; + +void sof_ipc4_mic_privacy_state_change(struct snd_sof_dev *sdev, bool state) +{ + struct sof_ipc4_msg msg; + u32 data = state; + + msg.primary = SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + msg.primary |= SOF_IPC4_MOD_ID(SOF_IPC4_MOD_INIT_BASEFW_MOD_ID); + msg.primary |= SOF_IPC4_MOD_INSTANCE(SOF_IPC4_MOD_INIT_BASEFW_INSTANCE_ID); + msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_FW_PARAM_MIC_PRIVACY_STATE_CHANGE); + + msg.data_size = sizeof(data); + msg.data_ptr = &data; + + sof_ipc4_set_get_data(sdev, &msg, msg.data_size, true); +} +EXPORT_SYMBOL(sof_ipc4_mic_privacy_state_change); From 0978e8207b61ac6d51280e5d28ccfff75d653363 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:14 +0200 Subject: [PATCH 439/651] ASoC: SOF: Intel: hda-mlink: Add support for mic privacy in VS SHIM registers New register has been introduced with PTL in the vendor specific SHIM registers, outside of the IPs itself for microphone privacy status handling. Via the PVCCS register the current microphone privacy status can be checked and the interrupt generation on status change can be enabled/disabled. The status change interrupt is routed to the owner of the interface (DSP/host). The PVCCS is provided for each sublink under the IP to make it possible to control the interrupt generation per sublink. On status change the MDSTSCHG bit needs to be cleared for all sublink of the interface to be able to detect future changes in privacy. The status bit (MDSTS) is volatile in all PVCCS register, it reflects the current state of the GPIO signal. Microphone privacy is a hardware feature (if enabled and configured that way), the host has only passive, monitoring role. The added functions are generic to be future proof if the mic privacy support is extended beyond Soundwire and DMIC links. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-7-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- include/sound/hda-mlink.h | 25 +++++++ sound/soc/sof/intel/hda-mlink.c | 127 ++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h index 6774f4b9e5fc..4327317be6af 100644 --- a/include/sound/hda-mlink.h +++ b/include/sound/hda-mlink.h @@ -62,6 +62,12 @@ struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid); int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable); +/* microphone privacy specific function supported by ACE3+ architecture */ +void hdac_bus_eml_set_mic_privacy_mask(struct hdac_bus *bus, bool alt, int elid, + unsigned long mask); +bool hdac_bus_eml_is_mic_privacy_changed(struct hdac_bus *bus, bool alt, int elid); +bool hdac_bus_eml_get_mic_privacy_state(struct hdac_bus *bus, bool alt, int elid); + #else static inline int @@ -185,4 +191,23 @@ hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enabl { return 0; } + +static inline void +hdac_bus_eml_set_mic_privacy_mask(struct hdac_bus *bus, bool alt, int elid, + unsigned long mask) +{ +} + +static inline bool +hdac_bus_eml_is_mic_privacy_changed(struct hdac_bus *bus, bool alt, int elid) +{ + return false; +} + +static inline bool +hdac_bus_eml_get_mic_privacy_state(struct hdac_bus *bus, bool alt, int elid) +{ + return false; +} + #endif /* CONFIG_SND_SOC_SOF_HDA_MLINK */ diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c index fe627bcb0531..ce561fe52bd5 100644 --- a/sound/soc/sof/intel/hda-mlink.c +++ b/sound/soc/sof/intel/hda-mlink.c @@ -16,6 +16,7 @@ #include #include +#include #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK) @@ -42,6 +43,7 @@ * @shim_offset: offset to SHIM register base * @ip_offset: offset to IP register base * @shim_vs_offset: offset to vendor-specific (VS) SHIM base + * @mic_privacy_mask: bitmask of sublinks where mic privacy is applied */ struct hdac_ext2_link { struct hdac_ext_link hext_link; @@ -65,6 +67,8 @@ struct hdac_ext2_link { u32 shim_offset; u32 ip_offset; u32 shim_vs_offset; + + unsigned long mic_privacy_mask; }; #define hdac_ext_link_to_ext2(h) container_of(h, struct hdac_ext2_link, hext_link) @@ -90,6 +94,13 @@ struct hdac_ext2_link { #define AZX_REG_INTEL_UAOL_IP_OFFSET 0x100 #define AZX_REG_INTEL_UAOL_VS_SHIM_OFFSET 0xC00 +/* Microphone privacy */ +#define AZX_REG_INTEL_VS_SHIM_PVCCS 0x10 +#define AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTSCHGIE BIT(0) +#define AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTSCHG BIT(8) +#define AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTS BIT(9) +#define AZX_REG_INTEL_VS_SHIM_PVCCS_FMDIS BIT(10) + /* HDAML section - this part follows sequences in the hardware specification, * including naming conventions and the use of the hdaml_ prefix. * The code is intentionally minimal with limited dependencies on frameworks or @@ -696,6 +707,20 @@ static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, } ret = hdaml_link_init(hlink->ml_addr + AZX_REG_ML_LCTL, sublink); + if ((h2link->mic_privacy_mask & BIT(sublink)) && !ret) { + u16 __iomem *pvccs = h2link->base_ptr + + h2link->shim_vs_offset + + sublink * h2link->instance_offset + + AZX_REG_INTEL_VS_SHIM_PVCCS; + u16 val = readw(pvccs); + + writew(val | AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTSCHGIE, pvccs); + + if (val & AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTS) + dev_dbg(bus->dev, + "sublink %d (%d:%d): Mic privacy is enabled\n", + sublink, alt, elid); + } skip_init: if (eml_lock) @@ -742,6 +767,16 @@ static int hdac_bus_eml_power_down_base(struct hdac_bus *bus, bool alt, int elid if (--h2link->sublink_ref_count[sublink] > 0) goto skip_shutdown; } + + if (h2link->mic_privacy_mask & BIT(sublink)) { + u16 __iomem *pvccs = h2link->base_ptr + + h2link->shim_vs_offset + + sublink * h2link->instance_offset + + AZX_REG_INTEL_VS_SHIM_PVCCS; + + writew(readw(pvccs) & ~AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTSCHGIE, pvccs); + } + ret = hdaml_link_shutdown(hlink->ml_addr + AZX_REG_ML_LCTL, sublink); skip_shutdown: @@ -987,6 +1022,98 @@ int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool e } EXPORT_SYMBOL_NS(hdac_bus_eml_enable_offload, "SND_SOC_SOF_HDA_MLINK"); +void hdac_bus_eml_set_mic_privacy_mask(struct hdac_bus *bus, bool alt, int elid, + unsigned long mask) +{ + struct hdac_ext2_link *h2link; + + if (!mask) + return; + + h2link = find_ext2_link(bus, alt, elid); + if (!h2link) + return; + + if (__fls(mask) > h2link->slcount) { + dev_warn(bus->dev, + "%s: invalid sublink mask for %d:%d, slcount %d: %#lx\n", + __func__, alt, elid, h2link->slcount, mask); + return; + } + + dev_dbg(bus->dev, "sublink mask for %d:%d, slcount %d: %#lx\n", alt, + elid, h2link->slcount, mask); + + h2link->mic_privacy_mask = mask; +} +EXPORT_SYMBOL_NS(hdac_bus_eml_set_mic_privacy_mask, "SND_SOC_SOF_HDA_MLINK"); + +bool hdac_bus_eml_is_mic_privacy_changed(struct hdac_bus *bus, bool alt, int elid) +{ + struct hdac_ext2_link *h2link; + bool changed = false; + u16 __iomem *pvccs; + int i; + + h2link = find_ext2_link(bus, alt, elid); + if (!h2link) + return false; + + /* The change in privacy state needs to be acked for each link */ + for_each_set_bit(i, &h2link->mic_privacy_mask, h2link->slcount) { + u16 val; + + if (h2link->sublink_ref_count[i] == 0) + continue; + + pvccs = h2link->base_ptr + + h2link->shim_vs_offset + + i * h2link->instance_offset + + AZX_REG_INTEL_VS_SHIM_PVCCS; + + val = readw(pvccs); + if (val & AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTSCHG) { + writew(val, pvccs); + changed = true; + } + } + + return changed; +} +EXPORT_SYMBOL_NS(hdac_bus_eml_is_mic_privacy_changed, "SND_SOC_SOF_HDA_MLINK"); + +bool hdac_bus_eml_get_mic_privacy_state(struct hdac_bus *bus, bool alt, int elid) +{ + struct hdac_ext2_link *h2link; + u16 __iomem *pvccs; + bool state; + int i; + + h2link = find_ext2_link(bus, alt, elid); + if (!h2link) + return false; + + for_each_set_bit(i, &h2link->mic_privacy_mask, h2link->slcount) { + if (h2link->sublink_ref_count[i] == 0) + continue; + + /* Return the privacy state from the first active link */ + pvccs = h2link->base_ptr + + h2link->shim_vs_offset + + i * h2link->instance_offset + + AZX_REG_INTEL_VS_SHIM_PVCCS; + + state = readw(pvccs) & AZX_REG_INTEL_VS_SHIM_PVCCS_MDSTS; + dev_dbg(bus->dev, "alt: %d, elid: %d: Mic privacy is %s\n", alt, + elid, str_enabled_disabled(state)); + + return state; + } + + return false; +} +EXPORT_SYMBOL_NS(hdac_bus_eml_get_mic_privacy_state, "SND_SOC_SOF_HDA_MLINK"); + #endif MODULE_LICENSE("Dual BSD/GPL"); From a0db661e7d8e084e9cf3b9cdca7c6e4e66f2e849 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:15 +0200 Subject: [PATCH 440/651] ASoC: SOF: hda/shim: Add callbacks to handle mic privacy change for sdw Add generic callback definitions for checking the mic privacy interrupt and status. Implement wrappers for mic privacy reported via the Soundwire interrupt and its vendor specific SHIM registers. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-8-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 34 ++++++++++++++++++++++++++++++++++ sound/soc/sof/intel/shim.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index a1ccd95da8bb..6b1ada566476 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -352,6 +352,27 @@ void hda_sdw_process_wakeen_common(struct snd_sof_dev *sdev) } EXPORT_SYMBOL_NS(hda_sdw_process_wakeen_common, "SND_SOC_SOF_INTEL_HDA_GENERIC"); +static bool hda_dsp_sdw_check_mic_privacy_irq(struct snd_sof_dev *sdev) +{ + const struct sof_intel_dsp_desc *chip; + + chip = get_chip_info(sdev->pdata); + if (chip && chip->check_mic_privacy_irq) + return chip->check_mic_privacy_irq(sdev, true, + AZX_REG_ML_LEPTR_ID_SDW); + + return false; +} + +static void hda_dsp_sdw_process_mic_privacy(struct snd_sof_dev *sdev) +{ + const struct sof_intel_dsp_desc *chip; + + chip = get_chip_info(sdev->pdata); + if (chip && chip->process_mic_privacy) + chip->process_mic_privacy(sdev, true, AZX_REG_ML_LEPTR_ID_SDW); +} + #else /* IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) */ static inline int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) { @@ -383,6 +404,13 @@ static inline bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) return false; } +static inline bool hda_dsp_sdw_check_mic_privacy_irq(struct snd_sof_dev *sdev) +{ + return false; +} + +static inline void hda_dsp_sdw_process_mic_privacy(struct snd_sof_dev *sdev) { } + #endif /* IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) */ /* pre fw run operations */ @@ -678,7 +706,13 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) if (hda_dsp_check_sdw_irq(sdev)) { trace_sof_intel_hda_irq(sdev, "sdw"); + hda_dsp_sdw_thread(irq, hdev->sdw); + + if (hda_dsp_sdw_check_mic_privacy_irq(sdev)) { + trace_sof_intel_hda_irq(sdev, "mic privacy"); + hda_dsp_sdw_process_mic_privacy(sdev); + } } if (hda_sdw_check_wakeen_irq(sdev)) { diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h index 8709b750a11e..d4372f0bff7e 100644 --- a/sound/soc/sof/intel/shim.h +++ b/sound/soc/sof/intel/shim.h @@ -193,6 +193,8 @@ struct sof_intel_dsp_desc { bool (*check_sdw_wakeen_irq)(struct snd_sof_dev *sdev); void (*sdw_process_wakeen)(struct snd_sof_dev *sdev); bool (*check_ipc_irq)(struct snd_sof_dev *sdev); + bool (*check_mic_privacy_irq)(struct snd_sof_dev *sdev, bool alt, int elid); + void (*process_mic_privacy)(struct snd_sof_dev *sdev, bool alt, int elid); int (*power_down_dsp)(struct snd_sof_dev *sdev); int (*disable_interrupts)(struct snd_sof_dev *sdev); int (*cl_init)(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot); From 4a43c3241ec3465a501825ecaf051e5a1d85a60b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 7 Mar 2025 13:28:16 +0200 Subject: [PATCH 441/651] ASoC: SOF: Intel: ptl: Add support for mic privacy Implement the three callbacks that is needed to enable support for reporting the mic privacy change via soundwire. In PTL the mic privacy reporting is supported via soundwire and DMIC and the soundwire is owned by the host, it's interrupt is routed there. To enable the interrupt, the sublink mask needs to be passed to the multilink layer, the check_mic_privacy_irq/process_mic_privacy callbacks needs to be implemented to check and report the mic privacy change. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Liam Girdwood Reviewed-by: Kai Vehmanen Link: https://patch.msgid.link/20250307112816.1495-9-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/ptl.c | 58 +++++++++++++++++++++++++++++++++++++-- sound/soc/sof/intel/ptl.h | 5 ++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/ptl.c b/sound/soc/sof/intel/ptl.c index ae8e9e08ad2a..8fa4bdceedd9 100644 --- a/sound/soc/sof/intel/ptl.c +++ b/sound/soc/sof/intel/ptl.c @@ -18,10 +18,62 @@ #include "lnl.h" #include "ptl.h" +static bool sof_ptl_check_mic_privacy_irq(struct snd_sof_dev *sdev, bool alt, + int elid) +{ + if (!alt || elid != AZX_REG_ML_LEPTR_ID_SDW) + return false; + + return hdac_bus_eml_is_mic_privacy_changed(sof_to_bus(sdev), alt, elid); +} + +static void sof_ptl_process_mic_privacy(struct snd_sof_dev *sdev, bool alt, + int elid) +{ + bool state; + + if (!alt || elid != AZX_REG_ML_LEPTR_ID_SDW) + return; + + state = hdac_bus_eml_get_mic_privacy_state(sof_to_bus(sdev), alt, elid); + + sof_ipc4_mic_privacy_state_change(sdev, state); +} + +static void sof_ptl_set_mic_privacy(struct snd_sof_dev *sdev, + struct sof_ipc4_intel_mic_privacy_cap *caps) +{ + u32 micpvcp; + + if (!caps || !caps->capabilities_length) + return; + + micpvcp = caps->capabilities[0]; + + /* No need to set the mic privacy if it is not enabled or forced */ + if (!(micpvcp & PTL_MICPVCP_DDZE_ENABLED) || + micpvcp & PTL_MICPVCP_DDZE_FORCED) + return; + + hdac_bus_eml_set_mic_privacy_mask(sof_to_bus(sdev), true, + AZX_REG_ML_LEPTR_ID_SDW, + PTL_MICPVCP_GET_SDW_MASK(micpvcp)); +} + int sof_ptl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops) { - return sof_lnl_set_ops(sdev, dsp_ops); -} + struct sof_ipc4_fw_data *ipc4_data; + int ret; + + ret = sof_lnl_set_ops(sdev, dsp_ops); + if (ret) + return ret; + + ipc4_data = sdev->private; + ipc4_data->intel_configure_mic_privacy = sof_ptl_set_mic_privacy; + + return 0; +}; EXPORT_SYMBOL_NS(sof_ptl_set_ops, "SND_SOC_SOF_INTEL_PTL"); const struct sof_intel_dsp_desc ptl_chip_info = { @@ -41,6 +93,8 @@ const struct sof_intel_dsp_desc ptl_chip_info = { .check_sdw_irq = lnl_dsp_check_sdw_irq, .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq, .check_ipc_irq = mtl_dsp_check_ipc_irq, + .check_mic_privacy_irq = sof_ptl_check_mic_privacy_irq, + .process_mic_privacy = sof_ptl_process_mic_privacy, .cl_init = mtl_dsp_cl_init, .power_down_dsp = mtl_power_down_dsp, .disable_interrupts = lnl_dsp_disable_interrupts, diff --git a/sound/soc/sof/intel/ptl.h b/sound/soc/sof/intel/ptl.h index 186f7c835acb..6a7ef11f411e 100644 --- a/sound/soc/sof/intel/ptl.h +++ b/sound/soc/sof/intel/ptl.h @@ -9,6 +9,11 @@ #ifndef __SOF_INTEL_PTL_H #define __SOF_INTEL_PTL_H +#define PTL_MICPVCP_DDZE_FORCED BIT(16) +#define PTL_MICPVCP_DDZE_ENABLED BIT(17) +#define PTL_MICPVCP_DDZLS_SDW GENMASK(26, 20) +#define PTL_MICPVCP_GET_SDW_MASK(x) (((x) & PTL_MICPVCP_DDZLS_SDW) >> 20) + int sof_ptl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops); #endif /* __SOF_INTEL_PTL_H */ From a8fed0bddf8fa239fc71dc5c035d2e078c597369 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Thu, 6 Mar 2025 18:18:39 +0100 Subject: [PATCH 442/651] ASoC: dt-bindings: add regulator support to dmic codec Add optional vref-supply property to describe the regulator supplying the digital microphones. Signed-off-by: Olivier Moysan Acked-by: "Rob Herring (Arm)" Link: https://patch.msgid.link/20250306171840.593443-2-olivier.moysan@foss.st.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/dmic-codec.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/dmic-codec.yaml b/Documentation/devicetree/bindings/sound/dmic-codec.yaml index 59ef0cf6b6e5..cc3c84dd4c26 100644 --- a/Documentation/devicetree/bindings/sound/dmic-codec.yaml +++ b/Documentation/devicetree/bindings/sound/dmic-codec.yaml @@ -19,6 +19,9 @@ properties: '#sound-dai-cells': const: 0 + vref-supply: + description: Phandle to the digital microphone reference supply + dmicen-gpios: description: GPIO specifier for DMIC to control start and stop maxItems: 1 From d3321a20b5111a66f3e68798959a347acfccbd44 Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Thu, 6 Mar 2025 18:18:40 +0100 Subject: [PATCH 443/651] ASoC: dmic: add regulator support Allow management of the regulator that may be used to supply the digital microphone. Signed-off-by: Olivier Moysan Link: https://patch.msgid.link/20250306171840.593443-3-olivier.moysan@foss.st.com Signed-off-by: Mark Brown --- sound/soc/codecs/dmic.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 0388f115470c..5d3c3f17c6d8 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ module_param(wakeup_delay, uint, 0644); struct dmic { struct gpio_desc *gpio_en; + struct regulator *vref; int wakeup_delay; /* Delay after DMIC mode switch */ int modeswitch_delay; @@ -55,22 +57,33 @@ static int dmic_aif_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct dmic *dmic = snd_soc_component_get_drvdata(component); + int ret = 0; switch (event) { case SND_SOC_DAPM_POST_PMU: if (dmic->gpio_en) gpiod_set_value_cansleep(dmic->gpio_en, 1); + if (dmic->vref) { + ret = regulator_enable(dmic->vref); + if (ret) + return ret; + } + if (dmic->wakeup_delay) msleep(dmic->wakeup_delay); break; case SND_SOC_DAPM_POST_PMD: if (dmic->gpio_en) gpiod_set_value_cansleep(dmic->gpio_en, 0); + + if (dmic->vref) + ret = regulator_disable(dmic->vref); + break; } - return 0; + return ret; } static struct snd_soc_dai_driver dmic_dai = { @@ -100,6 +113,10 @@ static int dmic_component_probe(struct snd_soc_component *component) if (!dmic) return -ENOMEM; + dmic->vref = devm_regulator_get_optional(component->dev, "vref"); + if (IS_ERR(dmic->vref) && PTR_ERR(dmic->vref) != -ENODEV) + return dev_err_probe(component->dev, PTR_ERR(dmic->vref), "Failed to get vref\n"); + dmic->gpio_en = devm_gpiod_get_optional(component->dev, "dmicen", GPIOD_OUT_LOW); if (IS_ERR(dmic->gpio_en)) From db91ad81a2545eb82aa47d0306bc3e1adb05e336 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 6 Mar 2025 13:31:38 +0800 Subject: [PATCH 444/651] ASoC: dt-bindings: fsl,imx-asrc: Document audio graph port This device can be used in conjunction with audio-graph-card to provide an endpoint for binding with the other side of the audio link. Signed-off-by: Shengjiu Wang Reviewed-by: Frank Li Reviewed-by: "Rob Herring (Arm)" Link: https://patch.msgid.link/20250306053138.1914956-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl,imx-asrc.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml index abac5084d63b..85799f83e65f 100644 --- a/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,imx-asrc.yaml @@ -77,6 +77,10 @@ properties: power-domains: maxItems: 1 + port: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + fsl,asrc-rate: $ref: /schemas/types.yaml#/definitions/uint32 description: The mutual sample rate used by DPCM Back Ends @@ -174,4 +178,12 @@ examples: "txa", "txb", "txc"; fsl,asrc-rate = <48000>; fsl,asrc-width = <16>; + + port { + playback-only; + + asrc_endpoint: endpoint { + remote-endpoint = <&fe00_ep>; + }; + }; }; From ad5a0970f86d82e39ebd06d45a1f7aa48a1316f8 Mon Sep 17 00:00:00 2001 From: Vitaliy Shevtsov Date: Tue, 4 Mar 2025 16:56:37 +0500 Subject: [PATCH 445/651] ASoC: cs35l41: check the return value from spi_setup() Currently the return value from spi_setup() is not checked for a failure. It is unlikely it will ever fail in this particular case but it is still better to add this check for the sake of completeness and correctness. This is cheap since it is performed once when the device is being probed. Handle spi_setup() return value. Found by Linux Verification Center (linuxtesting.org) with Svace. Fixes: 872fc0b6bde8 ("ASoC: cs35l41: Set the max SPI speed for the whole device") Signed-off-by: Vitaliy Shevtsov Link: https://patch.msgid.link/20250304115643.2748-1-v.shevtsov@mt-integration.ru Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41-spi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c index a6db44520c06..f9b6bf7bea9c 100644 --- a/sound/soc/codecs/cs35l41-spi.c +++ b/sound/soc/codecs/cs35l41-spi.c @@ -32,13 +32,16 @@ static int cs35l41_spi_probe(struct spi_device *spi) const struct regmap_config *regmap_config = &cs35l41_regmap_spi; struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(&spi->dev); struct cs35l41_private *cs35l41; + int ret; cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), GFP_KERNEL); if (!cs35l41) return -ENOMEM; spi->max_speed_hz = CS35L41_SPI_MAX_FREQ; - spi_setup(spi); + ret = spi_setup(spi); + if (ret < 0) + return ret; spi_set_drvdata(spi, cs35l41); cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); From 89be3c15a58b2ccf31e969223c8ac93ca8932d81 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Fri, 28 Feb 2025 16:14:30 +0000 Subject: [PATCH 446/651] ASoC: qcom: sm8250: explicitly set format in sm8250_be_hw_params_fixup() Setting format to s16le is required for compressed playback on compatible soundcards. Cc: Srinivas Kandagatla Signed-off-by: Alexey Klimov Link: https://patch.msgid.link/20250228161430.373961-1-alexey.klimov@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/sm8250.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index 45e0c33fc3f3..9039107972e2 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -39,9 +40,11 @@ static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); rate->min = rate->max = 48000; channels->min = channels->max = 2; + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); return 0; } From ac5b4a24f16f2f56b5cc5092969930b867274edc Mon Sep 17 00:00:00 2001 From: Naveen Manohar Date: Tue, 11 Mar 2025 08:31:01 +0800 Subject: [PATCH 447/651] ASoC: Intel: soc-acpi-intel-ptl-match: Add cs42l43 support Patch adds driver data & match table for cs42l43 multi-function codec on PTL-RVP at sdw link3. Signed-off-by: Naveen Manohar Reviewed-by: Liam Girdwood Signed-off-by: Bard Liao Link: https://patch.msgid.link/20250311003101.80967-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- .../intel/common/soc-acpi-intel-ptl-match.c | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c index a07526eb802b..6603d8de501c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c @@ -185,6 +185,33 @@ static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = { }, }; +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = { { .adr = 0x00023001fa424301ull, @@ -236,6 +263,15 @@ static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = { } }; +static const struct snd_soc_acpi_adr_device cs42l43_3_adr[] = { + { + .adr = 0x00033001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -390,6 +426,14 @@ static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = { {} }; +static const struct snd_soc_acpi_link_adr ptl_cs42l43_l3[] = { + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(cs42l43_3_adr), + .adr_d = cs42l43_3_adr, + } +}; + static const struct snd_soc_acpi_link_adr ptl_rt722_only[] = { { .mask = BIT(0), @@ -531,6 +575,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-ptl-rt711.tplg", }, + { + .link_mask = BIT(3), + .links = ptl_cs42l43_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-ptl-cs42l43-l3.tplg", + }, { .link_mask = BIT(3), .links = ptl_rt721_l3, From c3d5d331c96f35c6425f7dcfa5c60cf9a5055d0e Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:48 +0530 Subject: [PATCH 448/651] ASoC: amd: acp: Remove redundant acp70 chip->name As acp71 platform driver uses acp70 platform driver, remove the redundant chip->name. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-2-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index e0fc42d939d3..dcd92d716e78 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -89,8 +89,6 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->name = "acp_asoc_acp63"; break; case 0x70: - chip->name = "acp_asoc_acp70"; - break; case 0x71: chip->name = "acp_asoc_acp70"; break; From 8ae746fe51041484e52eba99bed15a444c7d4372 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:49 +0530 Subject: [PATCH 449/651] ASoC: amd: acp: Implement acp_common_hw_ops support for acp platforms Implement acp common hardware ops for acp_init and acp_deinit funcions to support commons ops for all platforms. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-3-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 50 +++++++++++++++++++++++++++ sound/soc/amd/acp/acp-pci.c | 13 ++++--- sound/soc/amd/acp/amd.h | 36 +++++++++++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 89f5cda18a23..f87a2da8c641 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -21,6 +21,12 @@ #define ACP63_PDM_ADDR 0x02 #define ACP70_PDM_ADDR 0x02 +const struct snd_acp_hw_ops acp_common_hw_ops = { + /* ACP hardware initilizations */ + .acp_init = acp_init, + .acp_deinit = acp_deinit, +}; +EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); void acp_enable_interrupts(struct acp_dev_data *adata) { struct acp_resource *rsrc = adata->rsrc; @@ -463,5 +469,49 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip) } EXPORT_SYMBOL_NS_GPL(check_acp_config, "SND_SOC_ACP_COMMON"); +struct snd_acp_hw_ops acp31_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp31_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp31_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp31_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp31_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp31_hw_ops_init, "SND_SOC_ACP_COMMON"); + +struct snd_acp_hw_ops acp6x_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp6x_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp6x_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp6x_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp6x_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp6x_hw_ops_init, "SND_SOC_ACP_COMMON"); + +struct snd_acp_hw_ops acp63_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp63_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp63_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp63_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp63_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp63_hw_ops_init, "SND_SOC_ACP_COMMON"); + +struct snd_acp_hw_ops acp70_common_hw_ops; +EXPORT_SYMBOL_NS_GPL(acp70_common_hw_ops, "SND_SOC_ACP_COMMON"); +int acp70_hw_ops_init(struct acp_chip_info *chip) +{ + memcpy(&acp70_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); + chip->acp_hw_ops = &acp70_common_hw_ops; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp70_hw_ops_init, "SND_SOC_ACP_COMMON"); + MODULE_DESCRIPTION("AMD ACP legacy common features"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index dcd92d716e78..b5eabd0280bc 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -81,16 +81,20 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id switch (pci->revision) { case 0x01: chip->name = "acp_asoc_renoir"; + chip->acp_hw_ops_init = acp31_hw_ops_init; break; case 0x6f: chip->name = "acp_asoc_rembrandt"; + chip->acp_hw_ops_init = acp6x_hw_ops_init; break; case 0x63: chip->name = "acp_asoc_acp63"; + chip->acp_hw_ops_init = acp63_hw_ops_init; break; case 0x70: case 0x71: chip->name = "acp_asoc_acp70"; + chip->acp_hw_ops_init = acp70_hw_ops_init; break; default: dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision); @@ -112,7 +116,8 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id goto unregister_dmic_dev; } - ret = acp_init(chip); + chip->acp_hw_ops_init(chip); + ret = acp_hw_init(chip); if (ret) goto unregister_dmic_dev; @@ -179,7 +184,7 @@ static int __maybe_unused snd_acp_suspend(struct device *dev) int ret; chip = dev_get_drvdata(dev); - ret = acp_deinit(chip); + ret = acp_hw_deinit(chip); if (ret) dev_err(dev, "ACP de-init failed\n"); return ret; @@ -193,7 +198,7 @@ static int __maybe_unused snd_acp_resume(struct device *dev) int ret; chip = dev_get_drvdata(dev); - ret = acp_init(chip); + ret = acp_hw_init(chip); if (ret) dev_err(dev, "ACP init failed\n"); if (chip->chip_pdev) { @@ -222,7 +227,7 @@ static void acp_pci_remove(struct pci_dev *pci) platform_device_unregister(dmic_dev); if (pdev) platform_device_unregister(pdev); - ret = acp_deinit(chip); + ret = acp_hw_deinit(chip); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); } diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index c921bcabbcec..3c06567e112c 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -142,6 +142,8 @@ struct acp_chip_info { char *name; /* Platform name */ unsigned int acp_rev; /* ACP Revision id */ void __iomem *base; /* ACP memory PCI base */ + struct snd_acp_hw_ops *acp_hw_ops; + int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ @@ -203,6 +205,17 @@ struct acp_dev_data { unsigned int flag; }; +/** + * struct snd_acp_hw_ops - ACP PCI driver platform specific ops + * @acp_init: ACP initialization + * @acp_deinit: ACP de-initialization + */ +struct snd_acp_hw_ops { + /* ACP hardware initilizations */ + int (*acp_init)(struct acp_chip_info *chip); + int (*acp_deinit)(struct acp_chip_info *chip); +}; + enum acp_config { ACP_CONFIG_0 = 0, ACP_CONFIG_1, @@ -239,6 +252,15 @@ int acp_init(struct acp_chip_info *chip); int acp_deinit(struct acp_chip_info *chip); void acp_enable_interrupts(struct acp_dev_data *adata); void acp_disable_interrupts(struct acp_dev_data *adata); + +extern struct snd_acp_hw_ops acp31_common_hw_ops; +extern struct snd_acp_hw_ops acp6x_common_hw_ops; +extern struct snd_acp_hw_ops acp63_common_hw_ops; +extern struct snd_acp_hw_ops acp70_common_hw_ops; +extern int acp31_hw_ops_init(struct acp_chip_info *chip); +extern int acp6x_hw_ops_init(struct acp_chip_info *chip); +extern int acp63_hw_ops_init(struct acp_chip_info *chip); +extern int acp70_hw_ops_init(struct acp_chip_info *chip); /* Machine configuration */ int snd_amd_acp_find_config(struct pci_dev *pci); @@ -252,6 +274,20 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip); +static inline int acp_hw_init(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->acp_init) + return chip->acp_hw_ops->acp_init(chip); + return -EOPNOTSUPP; +} + +static inline int acp_hw_deinit(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->acp_deinit) + return chip->acp_hw_ops->acp_deinit(chip); + return -EOPNOTSUPP; +} + static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) { u64 byte_count = 0, low = 0, high = 0; From e2cda461765692757cd5c3b1fc80bd260ffe1394 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:50 +0530 Subject: [PATCH 450/651] ASoC: amd: acp: Refactor dmic-codec platform device creation Refactor dmic-codec platform driver creation using helper function. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-4-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 49 +++++++++++++++++++++++++------------ sound/soc/amd/acp/amd.h | 1 + 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index b5eabd0280bc..549e95415ab2 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -26,7 +26,6 @@ #define ACP3x_REG_START 0x1240000 #define ACP3x_REG_END 0x125C000 -static struct platform_device *dmic_dev; static struct platform_device *pdev; static const struct resource acp_res[] = { @@ -44,6 +43,26 @@ static const struct resource acp_res[] = { }, }; +static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *chip) +{ + int ret; + + if (chip->is_pdm_dev && chip->is_pdm_config) { + chip->dmic_codec_dev = platform_device_register_data(&pci->dev, + "dmic-codec", + PLATFORM_DEVID_NONE, + NULL, 0); + if (IS_ERR(chip->dmic_codec_dev)) { + dev_err(&pci->dev, "failed to create DMIC device\n"); + ret = PTR_ERR(chip->dmic_codec_dev); + goto err; + } + } + return 0; +err: + return ret; +} + static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct platform_device_info pdevinfo; @@ -102,33 +121,33 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id goto release_regions; } chip->flag = flag; - dmic_dev = platform_device_register_data(dev, "dmic-codec", PLATFORM_DEVID_NONE, NULL, 0); - if (IS_ERR(dmic_dev)) { - dev_err(dev, "failed to create DMIC device\n"); - ret = PTR_ERR(dmic_dev); - goto release_regions; - } addr = pci_resource_start(pci, 0); chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0)); if (!chip->base) { ret = -ENOMEM; - goto unregister_dmic_dev; + goto release_regions; } chip->acp_hw_ops_init(chip); ret = acp_hw_init(chip); if (ret) - goto unregister_dmic_dev; + goto release_regions; check_acp_config(pci, chip); if (!chip->is_pdm_dev && !chip->is_i2s_config) goto skip_pdev_creation; + ret = create_acp_platform_devs(pci, chip); + if (ret < 0) { + dev_err(&pci->dev, "ACP platform devices creation failed\n"); + goto de_init; + } + res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL); if (!res) { ret = -ENOMEM; - goto unregister_dmic_dev; + goto de_init; } for (i = 0; i < num_res; i++, res_acp++) { @@ -156,7 +175,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id if (IS_ERR(pdev)) { dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name); ret = PTR_ERR(pdev); - goto unregister_dmic_dev; + goto de_init; } skip_pdev_creation: @@ -168,8 +187,8 @@ skip_pdev_creation: pm_runtime_allow(&pci->dev); return ret; -unregister_dmic_dev: - platform_device_unregister(dmic_dev); +de_init: + acp_hw_deinit(chip); release_regions: pci_release_regions(pci); disable_pci: @@ -223,8 +242,8 @@ static void acp_pci_remove(struct pci_dev *pci) chip = pci_get_drvdata(pci); pm_runtime_forbid(&pci->dev); pm_runtime_get_noresume(&pci->dev); - if (dmic_dev) - platform_device_unregister(dmic_dev); + if (chip->dmic_codec_dev) + platform_device_unregister(chip->dmic_codec_dev); if (pdev) platform_device_unregister(pdev); ret = acp_hw_deinit(chip); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 3c06567e112c..9511995da591 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -145,6 +145,7 @@ struct acp_chip_info { struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; + struct platform_device *dmic_codec_dev; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ bool is_pdm_config; /* flag set to true when PDM configuration is selected from BIOS */ From a8b9d2d7376d2caf74c0ffbf9bc71b98ed9d1a01 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:51 +0530 Subject: [PATCH 451/651] ASoC: amd: acp: Refactor acp platform device creation Refactor acp platform device creation logic and remove unused acp resource (acp_res) structure. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-5-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 121 ++++++++++++++++++------------------ sound/soc/amd/acp/amd.h | 4 ++ 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 549e95415ab2..0ffef70ab979 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -26,27 +26,56 @@ #define ACP3x_REG_START 0x1240000 #define ACP3x_REG_END 0x125C000 -static struct platform_device *pdev; - -static const struct resource acp_res[] = { - { - .start = 0, - .end = ACP3x_REG_END - ACP3x_REG_START, - .name = "acp_mem", - .flags = IORESOURCE_MEM, - }, - { - .start = 0, - .end = 0, - .name = "acp_dai_irq", - .flags = IORESOURCE_IRQ, - }, -}; - -static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *chip) +static void acp_fill_platform_dev_info(struct platform_device_info *pdevinfo, + struct device *parent, + struct fwnode_handle *fw_node, + char *name, unsigned int id, + const struct resource *res, + unsigned int num_res, + const void *data, + size_t size_data) { + pdevinfo->name = name; + pdevinfo->id = id; + pdevinfo->parent = parent; + pdevinfo->num_res = num_res; + pdevinfo->res = res; + pdevinfo->data = data; + pdevinfo->size_data = size_data; + pdevinfo->fwnode = fw_node; +} + +static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *chip, u32 addr) +{ + struct platform_device_info pdevinfo; + struct device *parent; int ret; + parent = &pci->dev; + + if (chip->is_i2s_config || chip->is_pdm_dev) { + chip->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL); + if (!chip->res) { + ret = -ENOMEM; + goto err; + } + chip->res->flags = IORESOURCE_MEM; + chip->res->start = addr; + chip->res->end = addr + (ACP3x_REG_END - ACP3x_REG_START); + memset(&pdevinfo, 0, sizeof(pdevinfo)); + } + + memset(&pdevinfo, 0, sizeof(pdevinfo)); + acp_fill_platform_dev_info(&pdevinfo, parent, NULL, chip->name, + 0, chip->res, 1, chip, sizeof(*chip)); + + chip->acp_plat_dev = platform_device_register_full(&pdevinfo); + if (IS_ERR(chip->acp_plat_dev)) { + dev_err(&pci->dev, + "cannot register %s device\n", pdevinfo.name); + ret = PTR_ERR(chip->acp_plat_dev); + goto err; + } if (chip->is_pdm_dev && chip->is_pdm_config) { chip->dmic_codec_dev = platform_device_register_data(&pci->dev, "dmic-codec", @@ -55,22 +84,21 @@ static int create_acp_platform_devs(struct pci_dev *pci, struct acp_chip_info *c if (IS_ERR(chip->dmic_codec_dev)) { dev_err(&pci->dev, "failed to create DMIC device\n"); ret = PTR_ERR(chip->dmic_codec_dev); - goto err; + goto unregister_acp_plat_dev; } } return 0; +unregister_acp_plat_dev: + platform_device_unregister(chip->acp_plat_dev); err: return ret; } static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { - struct platform_device_info pdevinfo; struct device *dev = &pci->dev; - const struct resource *res_acp; struct acp_chip_info *chip; - struct resource *res; - unsigned int flag, addr, num_res, i; + unsigned int flag, addr; int ret; flag = snd_amd_acp_find_config(pci); @@ -94,8 +122,6 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id pci_set_master(pci); - res_acp = acp_res; - num_res = ARRAY_SIZE(acp_res); chip->acp_rev = pci->revision; switch (pci->revision) { case 0x01: @@ -129,6 +155,8 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id goto release_regions; } + chip->addr = addr; + chip->acp_hw_ops_init(chip); ret = acp_hw_init(chip); if (ret) @@ -138,48 +166,16 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id if (!chip->is_pdm_dev && !chip->is_i2s_config) goto skip_pdev_creation; - ret = create_acp_platform_devs(pci, chip); + ret = create_acp_platform_devs(pci, chip, addr); if (ret < 0) { dev_err(&pci->dev, "ACP platform devices creation failed\n"); goto de_init; } - res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL); - if (!res) { - ret = -ENOMEM; - goto de_init; - } - - for (i = 0; i < num_res; i++, res_acp++) { - res[i].name = res_acp->name; - res[i].flags = res_acp->flags; - res[i].start = addr + res_acp->start; - res[i].end = addr + res_acp->end; - if (res_acp->flags == IORESOURCE_IRQ) { - res[i].start = pci->irq; - res[i].end = res[i].start; - } - } - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - - pdevinfo.name = chip->name; - pdevinfo.id = 0; - pdevinfo.parent = &pci->dev; - pdevinfo.num_res = num_res; - pdevinfo.res = &res[0]; - pdevinfo.data = chip; - pdevinfo.size_data = sizeof(*chip); - - pdev = platform_device_register_full(&pdevinfo); - if (IS_ERR(pdev)) { - dev_err(&pci->dev, "cannot register %s device\n", pdevinfo.name); - ret = PTR_ERR(pdev); - goto de_init; - } + chip->chip_pdev = chip->acp_plat_dev; + chip->dev = &chip->acp_plat_dev->dev; skip_pdev_creation: - chip->chip_pdev = pdev; dev_set_drvdata(&pci->dev, chip); pm_runtime_set_autosuspend_delay(&pci->dev, 2000); pm_runtime_use_autosuspend(&pci->dev); @@ -244,8 +240,9 @@ static void acp_pci_remove(struct pci_dev *pci) pm_runtime_get_noresume(&pci->dev); if (chip->dmic_codec_dev) platform_device_unregister(chip->dmic_codec_dev); - if (pdev) - platform_device_unregister(pdev); + if (chip->acp_plat_dev) + platform_device_unregister(chip->acp_plat_dev); + ret = acp_hw_deinit(chip); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 9511995da591..be1aa405a14a 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -140,12 +140,16 @@ struct acp_chip_info { char *name; /* Platform name */ + struct resource *res; + struct device *dev; unsigned int acp_rev; /* ACP Revision id */ void __iomem *base; /* ACP memory PCI base */ struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; struct platform_device *dmic_codec_dev; + struct platform_device *acp_plat_dev; + u32 addr; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ bool is_pdm_config; /* flag set to true when PDM configuration is selected from BIOS */ From 6e60db74b69c29b528c8d10d86108f78f2995dcb Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:52 +0530 Subject: [PATCH 452/651] ASoC: amd: acp: Refactor acp machine select Refactor and move acp machine select function from acp platform driver to acp pci driver and assign platform specific acpi machines to chip->machines. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-6-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 28 +++++++++ sound/soc/amd/acp/acp-pci.c | 7 +++ sound/soc/amd/acp/acp-platform.c | 28 --------- sound/soc/amd/acp/acp-rembrandt.c | 32 ----------- sound/soc/amd/acp/acp-renoir.c | 42 -------------- sound/soc/amd/acp/acp63.c | 10 ---- sound/soc/amd/acp/acp70.c | 10 ---- sound/soc/amd/acp/amd.h | 81 ++++++++++++++++++++++++++- 8 files changed, 114 insertions(+), 124 deletions(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index f87a2da8c641..886615798b93 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -16,6 +16,8 @@ #include #include +#include "../mach-config.h" + #define ACP_RENOIR_PDM_ADDR 0x02 #define ACP_REMBRANDT_PDM_ADDR 0x03 #define ACP63_PDM_ADDR 0x02 @@ -350,6 +352,32 @@ int acp_deinit(struct acp_chip_info *chip) return 0; } EXPORT_SYMBOL_NS_GPL(acp_deinit, "SND_SOC_ACP_COMMON"); +int acp_machine_select(struct acp_chip_info *chip) +{ + struct snd_soc_acpi_mach *mach; + int size, platform; + + if (chip->flag == FLAG_AMD_LEGACY_ONLY_DMIC) { + platform = chip->acp_rev; + chip->mach_dev = platform_device_register_data(chip->dev, "acp-pdm-mach", + PLATFORM_DEVID_NONE, &platform, + sizeof(platform)); + } else { + size = sizeof(*chip->machines); + mach = snd_soc_acpi_find_machine(chip->machines); + if (!mach) { + dev_err(chip->dev, "warning: No matching ASoC machine driver found\n"); + return -EINVAL; + } + mach->mach_params.subsystem_rev = chip->acp_rev; + chip->mach_dev = platform_device_register_data(chip->dev, mach->drv_name, + PLATFORM_DEVID_NONE, mach, size); + } + if (IS_ERR(chip->mach_dev)) + dev_warn(chip->dev, "Unable to register Machine device\n"); + return 0; +} +EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); static void check_acp3x_config(struct acp_chip_info *chip) { diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 0ffef70ab979..99297a388ed7 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -127,19 +127,23 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id case 0x01: chip->name = "acp_asoc_renoir"; chip->acp_hw_ops_init = acp31_hw_ops_init; + chip->machines = snd_soc_acpi_amd_acp_machines; break; case 0x6f: chip->name = "acp_asoc_rembrandt"; chip->acp_hw_ops_init = acp6x_hw_ops_init; + chip->machines = snd_soc_acpi_amd_rmb_acp_machines; break; case 0x63: chip->name = "acp_asoc_acp63"; chip->acp_hw_ops_init = acp63_hw_ops_init; + chip->machines = snd_soc_acpi_amd_acp63_acp_machines; break; case 0x70: case 0x71: chip->name = "acp_asoc_acp70"; chip->acp_hw_ops_init = acp70_hw_ops_init; + chip->machines = snd_soc_acpi_amd_acp70_acp_machines; break; default: dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision); @@ -175,6 +179,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->chip_pdev = chip->acp_plat_dev; chip->dev = &chip->acp_plat_dev->dev; + acp_machine_select(chip); skip_pdev_creation: dev_set_drvdata(&pci->dev, chip); pm_runtime_set_autosuspend_delay(&pci->dev, 2000); @@ -242,6 +247,8 @@ static void acp_pci_remove(struct pci_dev *pci) platform_device_unregister(chip->dmic_codec_dev); if (chip->acp_plat_dev) platform_device_unregister(chip->acp_plat_dev); + if (chip->mach_dev) + platform_device_unregister(chip->mach_dev); ret = acp_hw_deinit(chip); if (ret) diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index aa330aeeb301..7d6abff28b23 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -21,7 +21,6 @@ #include #include "amd.h" -#include "../mach-config.h" #include "acp-mach.h" #define DRV_NAME "acp_i2s_dma" @@ -108,33 +107,6 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = { .periods_max = CAPTURE_MAX_NUM_PERIODS, }; -int acp_machine_select(struct acp_dev_data *adata) -{ - struct snd_soc_acpi_mach *mach; - int size, platform; - - if (adata->flag == FLAG_AMD_LEGACY_ONLY_DMIC) { - platform = adata->acp_rev; - adata->mach_dev = platform_device_register_data(adata->dev, "acp-pdm-mach", - PLATFORM_DEVID_NONE, &platform, - sizeof(platform)); - } else { - size = sizeof(*adata->machines); - mach = snd_soc_acpi_find_machine(adata->machines); - if (!mach) { - dev_err(adata->dev, "warning: No matching ASoC machine driver found\n"); - return -EINVAL; - } - mach->mach_params.subsystem_rev = adata->acp_rev; - adata->mach_dev = platform_device_register_data(adata->dev, mach->drv_name, - PLATFORM_DEVID_NONE, mach, size); - } - if (IS_ERR(adata->mach_dev)) - dev_warn(adata->dev, "Unable to register Machine device\n"); - return 0; -} -EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); - static irqreturn_t i2s_irq_handler(int irq, void *data) { struct acp_dev_data *adata = data; diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index e727754a8231..eb09878c0d5c 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -44,36 +44,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x03802800, }; -static struct snd_soc_acpi_codecs amp_rt1019 = { - .num_codecs = 1, - .codecs = {"10EC1019"} -}; - -static struct snd_soc_acpi_codecs amp_max = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - -static struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = { - { - .id = "10508825", - .drv_name = "rmb-nau8825-max", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_max, - }, - { - .id = "AMDI0007", - .drv_name = "rembrandt-acp", - }, - { - .id = "RTL5682", - .drv_name = "rmb-rt5682s-rt1019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - {}, -}; - static struct snd_soc_dai_driver acp_rmb_dai[] = { { .name = "acp-i2s-sp", @@ -230,8 +200,6 @@ static int rembrandt_audio_probe(struct platform_device *pdev) adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; adata->is_i2s_config = chip->is_i2s_config; - adata->machines = snd_soc_acpi_amd_rmb_acp_machines; - acp_machine_select(adata); dev_set_drvdata(dev, adata); diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index ca2b74283d8f..2b47c6bfc9e7 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -36,45 +36,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x02052800, }; -static struct snd_soc_acpi_codecs amp_rt1019 = { - .num_codecs = 1, - .codecs = {"10EC1019"} -}; - -static struct snd_soc_acpi_codecs amp_max = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - -static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { - { - .id = "10EC5682", - .drv_name = "acp3xalc56821019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - { - .id = "RTL5682", - .drv_name = "acp3xalc5682sm98360", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_max, - }, - { - .id = "RTL5682", - .drv_name = "acp3xalc5682s1019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - { - .id = "AMDI1019", - .drv_name = "renoir-acp", - }, - { - .id = "ESSX8336", - .drv_name = "acp3x-es83xx", - }, - {}, -}; static struct snd_soc_dai_driver acp_renoir_dai[] = { { @@ -188,9 +149,6 @@ static int renoir_audio_probe(struct platform_device *pdev) adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; - adata->machines = snd_soc_acpi_amd_acp_machines; - acp_machine_select(adata); - dev_set_drvdata(dev, adata); acp_enable_interrupts(adata); acp_platform_register(dev); diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 4187a8968de7..76a26b82e3ad 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -62,14 +62,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x03802800, }; -static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines[] = { - { - .id = "AMDI0052", - .drv_name = "acp63-acp", - }, - {}, -}; - static struct snd_soc_dai_driver acp63_dai[] = { { .name = "acp-i2s-sp", @@ -259,8 +251,6 @@ static int acp63_audio_probe(struct platform_device *pdev) adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; adata->is_i2s_config = chip->is_i2s_config; - adata->machines = snd_soc_acpi_amd_acp63_acp_machines; - acp_machine_select(adata); dev_set_drvdata(dev, adata); if (chip->is_i2s_config && rsrc.soc_mclk) { diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index 7f4ec3bfaeab..3e603c5f736a 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -40,14 +40,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x03800000, }; -static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { - { - .id = "AMDI0029", - .drv_name = "acp70-acp", - }, - {}, -}; - static struct snd_soc_dai_driver acp70_dai[] = { { .name = "acp-i2s-sp", @@ -187,10 +179,8 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) adata->dai_driver = acp70_dai; adata->num_dai = ARRAY_SIZE(acp70_dai); adata->rsrc = &rsrc; - adata->machines = snd_soc_acpi_amd_acp70_acp_machines; adata->acp_rev = chip->acp_rev; adata->flag = chip->flag; - acp_machine_select(adata); dev_set_drvdata(dev, adata); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index be1aa405a14a..b7a1b4aa8fef 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -149,6 +149,8 @@ struct acp_chip_info { struct platform_device *chip_pdev; struct platform_device *dmic_codec_dev; struct platform_device *acp_plat_dev; + struct platform_device *mach_dev; + struct snd_soc_acpi_mach *machines; u32 addr; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ @@ -195,7 +197,6 @@ struct acp_dev_data { struct list_head stream_list; spinlock_t acp_lock; - struct snd_soc_acpi_mach *machines; struct platform_device *mach_dev; u32 bclk_div; @@ -245,13 +246,89 @@ enum acp_config { ACP_CONFIG_20, }; +struct snd_soc_acpi_codecs amp_rt1019 = { + .num_codecs = 1, + .codecs = {"10EC1019"} +}; + +struct snd_soc_acpi_codecs amp_max = { + .num_codecs = 1, + .codecs = {"MX98360A"} +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { + { + .id = "10EC5682", + .drv_name = "acp3xalc56821019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + { + .id = "RTL5682", + .drv_name = "acp3xalc5682sm98360", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + }, + { + .id = "RTL5682", + .drv_name = "acp3xalc5682s1019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + { + .id = "AMDI1019", + .drv_name = "renoir-acp", + }, + { + .id = "ESSX8336", + .drv_name = "acp3x-es83xx", + }, + {}, +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = { + { + .id = "10508825", + .drv_name = "rmb-nau8825-max", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + }, + { + .id = "AMDI0007", + .drv_name = "rembrandt-acp", + }, + { + .id = "RTL5682", + .drv_name = "rmb-rt5682s-rt1019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + {}, +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines[] = { + { + .id = "AMDI0052", + .drv_name = "acp63-acp", + }, + {}, +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { + { + .id = "AMDI0029", + .drv_name = "acp70-acp", + }, + {}, +}; + extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; extern const struct snd_soc_dai_ops acp_dmic_dai_ops; int acp_platform_register(struct device *dev); int acp_platform_unregister(struct device *dev); -int acp_machine_select(struct acp_dev_data *adata); +int acp_machine_select(struct acp_chip_info *chip); int acp_init(struct acp_chip_info *chip); int acp_deinit(struct acp_chip_info *chip); From aaf7a668bb3814f084f9f6f673567f6aa316632f Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:53 +0530 Subject: [PATCH 453/651] ASoC: amd: acp: Add new interrupt handle callbacks in acp_common_hw_ops Add new interrupt handle callbacks in acp_common_hw_ops. Refactor and move interrupt handler registration form platform driver to pci driver. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-7-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-i2s.c | 4 +- sound/soc/amd/acp/acp-legacy-common.c | 79 +++++++++++++++++++++++---- sound/soc/amd/acp/acp-pci.c | 29 +++++++--- sound/soc/amd/acp/acp-pdm.c | 12 ++-- sound/soc/amd/acp/acp-platform.c | 50 +++-------------- sound/soc/amd/acp/acp-rembrandt.c | 15 ++++- sound/soc/amd/acp/acp-renoir.c | 15 ++++- sound/soc/amd/acp/acp63.c | 15 ++++- sound/soc/amd/acp/acp70.c | 15 ++++- sound/soc/amd/acp/amd.h | 29 +++++++++- sound/soc/amd/acp/chip_offset_byte.h | 12 ++-- 11 files changed, 184 insertions(+), 91 deletions(-) diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c index 89e99ed4275a..2f458c76f9fc 100644 --- a/sound/soc/amd/acp/acp-i2s.c +++ b/sound/soc/amd/acp/acp-i2s.c @@ -617,7 +617,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | BIT(BT_RX_THRESHOLD(rsrc->offset)) | BIT(I2S_TX_THRESHOLD(rsrc->offset)) | @@ -625,7 +625,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d BIT(HS_RX_THRESHOLD(rsrc->offset)) | BIT(HS_TX_THRESHOLD(rsrc->offset)); - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); return 0; } diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 886615798b93..13fddce8df56 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -27,26 +27,76 @@ const struct snd_acp_hw_ops acp_common_hw_ops = { /* ACP hardware initilizations */ .acp_init = acp_init, .acp_deinit = acp_deinit, + + /* ACP Interrupts*/ + .irq = acp_irq_handler, + .en_interrupts = acp_enable_interrupts, + .dis_interrupts = acp_disable_interrupts, }; EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); -void acp_enable_interrupts(struct acp_dev_data *adata) + +irqreturn_t acp_irq_handler(int irq, void *data) { + struct acp_chip_info *chip = data; + struct acp_dev_data *adata = chip->adata; struct acp_resource *rsrc = adata->rsrc; + struct acp_stream *stream; + u16 i2s_flag = 0; + u32 ext_intr_stat, ext_intr_stat1; + + if (adata->rsrc->no_of_ctrls == 2) + ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1))); + + ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); + + spin_lock(&adata->acp_lock); + list_for_each_entry(stream, &adata->stream_list, list) { + if (ext_intr_stat & stream->irq_bit) { + writel(stream->irq_bit, + ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); + snd_pcm_period_elapsed(stream->substream); + i2s_flag = 1; + } + if (adata->rsrc->no_of_ctrls == 2) { + if (ext_intr_stat1 & stream->irq_bit) { + writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip, + (rsrc->irqp_used - 1))); + snd_pcm_period_elapsed(stream->substream); + i2s_flag = 1; + } + } + } + spin_unlock(&adata->acp_lock); + if (i2s_flag) + return IRQ_HANDLED; + + return IRQ_NONE; +} + +int acp_enable_interrupts(struct acp_chip_info *chip) +{ + struct acp_resource *rsrc; u32 ext_intr_ctrl; - writel(0x01, ACP_EXTERNAL_INTR_ENB(adata)); - ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + rsrc = chip->rsrc; + writel(0x01, ACP_EXTERNAL_INTR_ENB(chip)); + ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_intr_ctrl |= ACP_ERROR_MASK; - writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); + + return 0; } EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, "SND_SOC_ACP_COMMON"); -void acp_disable_interrupts(struct acp_dev_data *adata) +int acp_disable_interrupts(struct acp_chip_info *chip) { - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc; - writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - writel(0x00, ACP_EXTERNAL_INTR_ENB(adata)); + rsrc = chip->rsrc; + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); + writel(0x00, ACP_EXTERNAL_INTR_ENB(chip)); + + return 0; } EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, "SND_SOC_ACP_COMMON"); @@ -90,19 +140,23 @@ void restore_acp_pdm_params(struct snd_pcm_substream *substream, struct acp_dev_data *adata) { struct snd_soc_dai *dai; + struct device *dev; + struct acp_chip_info *chip; struct snd_soc_pcm_runtime *soc_runtime; u32 ext_int_ctrl; soc_runtime = snd_soc_substream_to_rtd(substream); dai = snd_soc_rtd_to_cpu(soc_runtime, 0); + dev = dai->component->dev; + chip = dev_get_platdata(dev); /* Programming channel mask and sampling rate */ writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR); /* Enabling ACP Pdm interuppts */ - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); ext_int_ctrl |= PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0)); set_acp_pdm_clk(substream, dai); } EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, "SND_SOC_ACP_COMMON"); @@ -113,6 +167,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, struct device *dev = dai->component->dev; struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream = substream->runtime->private_data; u32 reg_dma_size, reg_fifo_size, reg_fifo_addr; u32 phy_addr, acp_fifo_addr, ext_int_ctrl; @@ -185,7 +240,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | BIT(BT_RX_THRESHOLD(rsrc->offset)) | BIT(I2S_TX_THRESHOLD(rsrc->offset)) | @@ -193,7 +248,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, BIT(HS_RX_THRESHOLD(rsrc->offset)) | BIT(HS_TX_THRESHOLD(rsrc->offset)); - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); return 0; } diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 99297a388ed7..1ef9faba1d8a 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -26,6 +26,15 @@ #define ACP3x_REG_START 0x1240000 #define ACP3x_REG_END 0x125C000 +static irqreturn_t irq_handler(int irq, void *data) +{ + struct acp_chip_info *chip = data; + + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->irq) + return chip->acp_hw_ops->irq(irq, chip); + + return IRQ_NONE; +} static void acp_fill_platform_dev_info(struct platform_device_info *pdevinfo, struct device *parent, struct fwnode_handle *fw_node, @@ -166,6 +175,13 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id if (ret) goto release_regions; + ret = devm_request_irq(dev, pci->irq, irq_handler, + IRQF_SHARED, "ACP_I2S_IRQ", chip); + if (ret) { + dev_err(&pci->dev, "ACP I2S IRQ request failed %d\n", ret); + return ret; + } + check_acp_config(pci, chip); if (!chip->is_pdm_dev && !chip->is_i2s_config) goto skip_pdev_creation; @@ -213,20 +229,17 @@ static int __maybe_unused snd_acp_suspend(struct device *dev) static int __maybe_unused snd_acp_resume(struct device *dev) { struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct device child; int ret; chip = dev_get_drvdata(dev); ret = acp_hw_init(chip); if (ret) dev_err(dev, "ACP init failed\n"); - if (chip->chip_pdev) { - child = chip->chip_pdev->dev; - adata = dev_get_drvdata(&child); - if (adata) - acp_enable_interrupts(adata); - } + + ret = acp_hw_en_interrupts(chip); + if (ret) + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; } diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index d4855da05b6a..9a820ef3bf46 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -145,7 +145,7 @@ static int acp_dmic_dai_startup(struct snd_pcm_substream *substream, { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); u32 ext_int_ctrl; stream->dai_id = DMIC_INSTANCE; @@ -154,9 +154,9 @@ static int acp_dmic_dai_startup(struct snd_pcm_substream *substream, stream->reg_offset = ACP_REGION2_OFFSET; /* Enable DMIC Interrupts */ - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); ext_int_ctrl |= PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0)); return 0; } @@ -165,13 +165,13 @@ static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); u32 ext_int_ctrl; /* Disable DMIC interrupts */ - ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); ext_int_ctrl &= ~PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0)); } const struct snd_soc_dai_ops acp_dmic_dai_ops = { diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 7d6abff28b23..9b181fb5861c 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -107,43 +107,6 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = { .periods_max = CAPTURE_MAX_NUM_PERIODS, }; -static irqreturn_t i2s_irq_handler(int irq, void *data) -{ - struct acp_dev_data *adata = data; - struct acp_resource *rsrc = adata->rsrc; - struct acp_stream *stream; - u16 i2s_flag = 0; - u32 ext_intr_stat, ext_intr_stat1; - - if (adata->rsrc->no_of_ctrls == 2) - ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(adata, (rsrc->irqp_used - 1))); - - ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { - if (ext_intr_stat & stream->irq_bit) { - writel(stream->irq_bit, - ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - snd_pcm_period_elapsed(stream->substream); - i2s_flag = 1; - } - if (adata->rsrc->no_of_ctrls == 2) { - if (ext_intr_stat1 & stream->irq_bit) { - writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(adata, - (rsrc->irqp_used - 1))); - snd_pcm_period_elapsed(stream->substream); - i2s_flag = 1; - } - } - } - spin_unlock(&adata->acp_lock); - if (i2s_flag) - return IRQ_HANDLED; - - return IRQ_NONE; -} - void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream) { struct acp_resource *rsrc = adata->rsrc; @@ -278,7 +241,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs } runtime->private_data = stream; - writel(1, ACP_EXTERNAL_INTR_ENB(adata)); + writel(1, ACP_EXTERNAL_INTR_ENB(chip)); spin_lock_irq(&adata->acp_lock); list_add_tail(&stream->list, &adata->stream_list); @@ -363,16 +326,17 @@ static const struct snd_soc_component_driver acp_pcm_component = { int acp_platform_register(struct device *dev) { struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip; struct snd_soc_dai_driver; unsigned int status; - status = devm_request_irq(dev, adata->i2s_irq, i2s_irq_handler, - IRQF_SHARED, "ACP_I2S_IRQ", adata); - if (status) { - dev_err(dev, "ACP I2S IRQ request failed\n"); - return status; + chip = dev_get_platdata(dev); + if (!chip || !chip->base) { + dev_err(dev, "ACP chip data is NULL\n"); + return -ENODEV; } + chip->adata = adata; status = devm_snd_soc_register_component(dev, &acp_pcm_component, adata->dai_driver, adata->num_dai); diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index eb09878c0d5c..13633b3f3730 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -192,6 +192,7 @@ static int rembrandt_audio_probe(struct platform_device *pdev) return -ENODEV; } + chip->rsrc = &rsrc; adata->i2s_irq = res->start; adata->dev = dev; adata->dai_driver = acp_rmb_dai; @@ -208,7 +209,11 @@ static int rembrandt_audio_probe(struct platform_device *pdev) if (ret) return ret; } - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); @@ -221,9 +226,13 @@ static int rembrandt_audio_probe(struct platform_device *pdev) static void rembrandt_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); pm_runtime_disable(&pdev->dev); } diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 2b47c6bfc9e7..94ecb17684b7 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -142,6 +142,7 @@ static int renoir_audio_probe(struct platform_device *pdev) return ret; adata->i2s_irq = ret; + chip->rsrc = &rsrc; adata->dev = dev; adata->dai_driver = acp_renoir_dai; adata->num_dai = ARRAY_SIZE(acp_renoir_dai); @@ -150,7 +151,11 @@ static int renoir_audio_probe(struct platform_device *pdev) adata->flag = chip->flag; dev_set_drvdata(dev, adata); - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); @@ -164,9 +169,13 @@ static int renoir_audio_probe(struct platform_device *pdev) static void renoir_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); } diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 76a26b82e3ad..e38ad9f7fb48 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -243,6 +243,7 @@ static int acp63_audio_probe(struct platform_device *pdev) return -ENODEV; } + chip->rsrc = &rsrc; adata->i2s_irq = res->start; adata->dev = dev; adata->dai_driver = acp63_dai; @@ -258,7 +259,11 @@ static int acp63_audio_probe(struct platform_device *pdev) if (ret) return ret; } - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); @@ -271,9 +276,13 @@ static int acp63_audio_probe(struct platform_device *pdev) static void acp63_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); pm_runtime_disable(&pdev->dev); } diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index 3e603c5f736a..be4302a5a584 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -174,6 +174,7 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) return -ENODEV; } + chip->rsrc = &rsrc; adata->i2s_irq = res->start; adata->dev = dev; adata->dai_driver = acp70_dai; @@ -190,7 +191,11 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to set I2S master clock as 196.608MHz\n"); return ret; } - acp_enable_interrupts(adata); + ret = acp_hw_en_interrupts(chip); + if (ret) { + dev_err(dev, "ACP en-interrupts failed\n"); + return ret; + } acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); pm_runtime_use_autosuspend(&pdev->dev); @@ -203,9 +208,13 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) static void acp_acp70_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); + int ret; + + ret = acp_hw_dis_interrupts(chip); + if (ret) + dev_err(dev, "ACP dis-interrupts failed\n"); - acp_disable_interrupts(adata); acp_platform_unregister(dev); pm_runtime_disable(&pdev->dev); } diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index b7a1b4aa8fef..4beaa9cae352 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -147,10 +147,12 @@ struct acp_chip_info { struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; + struct acp_resource *rsrc; /* Platform specific resources*/ struct platform_device *dmic_codec_dev; struct platform_device *acp_plat_dev; struct platform_device *mach_dev; struct snd_soc_acpi_mach *machines; + struct acp_dev_data *adata; u32 addr; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ @@ -215,11 +217,19 @@ struct acp_dev_data { * struct snd_acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization * @acp_deinit: ACP de-initialization + * @irq: ACP irq handler + * @en_interrupts: ACP enable interrupts + * @dis_interrupts: ACP disable interrupts */ struct snd_acp_hw_ops { /* ACP hardware initilizations */ int (*acp_init)(struct acp_chip_info *chip); int (*acp_deinit)(struct acp_chip_info *chip); + + /* ACP Interrupts*/ + irqreturn_t (*irq)(int irq, void *data); + int (*en_interrupts)(struct acp_chip_info *chip); + int (*dis_interrupts)(struct acp_chip_info *chip); }; enum acp_config { @@ -332,8 +342,9 @@ int acp_machine_select(struct acp_chip_info *chip); int acp_init(struct acp_chip_info *chip); int acp_deinit(struct acp_chip_info *chip); -void acp_enable_interrupts(struct acp_dev_data *adata); -void acp_disable_interrupts(struct acp_dev_data *adata); +int acp_enable_interrupts(struct acp_chip_info *chip); +int acp_disable_interrupts(struct acp_chip_info *chip); +irqreturn_t acp_irq_handler(int irq, void *data); extern struct snd_acp_hw_ops acp31_common_hw_ops; extern struct snd_acp_hw_ops acp6x_common_hw_ops; @@ -370,6 +381,20 @@ static inline int acp_hw_deinit(struct acp_chip_info *chip) return -EOPNOTSUPP; } +static inline int acp_hw_en_interrupts(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->en_interrupts) + return chip->acp_hw_ops->en_interrupts(chip); + return -EOPNOTSUPP; +} + +static inline int acp_hw_dis_interrupts(struct acp_chip_info *chip) +{ + if (chip && chip->acp_hw_ops && chip->acp_hw_ops->dis_interrupts) + chip->acp_hw_ops->dis_interrupts(chip); + return -EOPNOTSUPP; +} + static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) { u64 byte_count = 0, low = 0, high = 0; diff --git a/sound/soc/amd/acp/chip_offset_byte.h b/sound/soc/amd/acp/chip_offset_byte.h index 117ea63e85c6..82275c9de53a 100644 --- a/sound/soc/amd/acp/chip_offset_byte.h +++ b/sound/soc/amd/acp/chip_offset_byte.h @@ -29,13 +29,13 @@ #define ACP_PIN_CONFIG 0x1440 #define ACP3X_PIN_CONFIG 0x1400 -#define ACP_EXTERNAL_INTR_REG_ADDR(adata, offset, ctrl) \ - (adata->acp_base + adata->rsrc->irq_reg_offset + offset + (ctrl * 0x04)) +#define ACP_EXTERNAL_INTR_REG_ADDR(chip, offset, ctrl) \ + (chip->base + chip->rsrc->irq_reg_offset + offset + (ctrl * 0x04)) -#define ACP_EXTERNAL_INTR_ENB(adata) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x0, 0x0) -#define ACP_EXTERNAL_INTR_CNTL(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x4, ctrl) -#define ACP_EXTERNAL_INTR_STAT(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, \ - (0x4 + (adata->rsrc->no_of_ctrls * 0x04)), ctrl) +#define ACP_EXTERNAL_INTR_ENB(chip) ACP_EXTERNAL_INTR_REG_ADDR(chip, 0x0, 0x0) +#define ACP_EXTERNAL_INTR_CNTL(chip, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(chip, 0x4, ctrl) +#define ACP_EXTERNAL_INTR_STAT(chip, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(chip, \ + (0x4 + (chip->rsrc->no_of_ctrls * 0x04)), ctrl) /* Registers from ACP_AUDIO_BUFFERS block */ From e3933683b25e2cc94485da4909e3338e1a177b39 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:54 +0530 Subject: [PATCH 454/651] ASoC: amd: acp: Remove redundant acp_dev_data structure Move acp_dev_data structure members to acp_chip_info structure to avoid using common members in each structure and remove redundant acp_dev_data structure. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-8-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-i2s.c | 179 +++++++++++++------------- sound/soc/amd/acp/acp-legacy-common.c | 107 ++++++++------- sound/soc/amd/acp/acp-pdm.c | 41 +++--- sound/soc/amd/acp/acp-platform.c | 70 +++++----- sound/soc/amd/acp/acp-rembrandt.c | 53 ++------ sound/soc/amd/acp/acp-renoir.c | 48 ++----- sound/soc/amd/acp/acp63.c | 58 +++------ sound/soc/amd/acp/acp70.c | 50 ++----- sound/soc/amd/acp/amd.h | 86 +++++-------- 9 files changed, 274 insertions(+), 418 deletions(-) diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c index 2f458c76f9fc..a38409dd1d34 100644 --- a/sound/soc/amd/acp/acp-i2s.c +++ b/sound/soc/amd/acp/acp-i2s.c @@ -31,14 +31,10 @@ #define ACP63_LRCLK_DIV_FIELD GENMASK(12, 2) #define ACP63_BCLK_DIV_FIELD GENMASK(23, 13) -static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id) +static inline void acp_set_i2s_clk(struct acp_chip_info *chip, int dai_id) { u32 i2s_clk_reg, val; - struct acp_chip_info *chip; - struct device *dev; - dev = adata->dev; - chip = dev_get_platdata(dev); switch (dai_id) { case I2S_SP_INSTANCE: i2s_clk_reg = ACP_I2STDM0_MSTRCLKGEN; @@ -55,36 +51,37 @@ static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id) } val = I2S_MASTER_MODE_ENABLE; - if (adata->tdm_mode) + if (chip->tdm_mode) val |= BIT(1); switch (chip->acp_rev) { case ACP63_PCI_ID: case ACP70_PCI_ID: case ACP71_PCI_ID: - val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, adata->lrclk_div); - val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, adata->bclk_div); + val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, chip->lrclk_div); + val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, chip->bclk_div); break; default: - val |= FIELD_PREP(LRCLK_DIV_FIELD, adata->lrclk_div); - val |= FIELD_PREP(BCLK_DIV_FIELD, adata->bclk_div); + val |= FIELD_PREP(LRCLK_DIV_FIELD, chip->lrclk_div); + val |= FIELD_PREP(BCLK_DIV_FIELD, chip->bclk_div); } - writel(val, adata->acp_base + i2s_clk_reg); + writel(val, chip->base + i2s_clk_reg); } static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - struct acp_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); + struct device *dev = cpu_dai->component->dev; + struct acp_chip_info *chip = dev_get_platdata(dev); int mode; mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK; switch (mode) { case SND_SOC_DAIFMT_I2S: - adata->tdm_mode = TDM_DISABLE; + chip->tdm_mode = TDM_DISABLE; break; case SND_SOC_DAIFMT_DSP_A: - adata->tdm_mode = TDM_ENABLE; + chip->tdm_mode = TDM_ENABLE; break; default: return -EINVAL; @@ -96,7 +93,6 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas int slots, int slot_width) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = snd_soc_dai_get_drvdata(dai); struct acp_chip_info *chip; struct acp_stream *stream; int slot_len, no_of_slots; @@ -157,35 +153,35 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas slots = no_of_slots; - spin_lock_irq(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock_irq(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { switch (chip->acp_rev) { case ACP_RN_PCI_ID: case ACP_RMB_PCI_ID: if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) - adata->tdm_tx_fmt[stream->dai_id - 1] = + chip->tdm_tx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 15) | (slot_len << 18); else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) - adata->tdm_rx_fmt[stream->dai_id - 1] = + chip->tdm_rx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 15) | (slot_len << 18); break; case ACP63_PCI_ID: case ACP70_PCI_ID: case ACP71_PCI_ID: if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) - adata->tdm_tx_fmt[stream->dai_id - 1] = + chip->tdm_tx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 13) | (slot_len << 18); else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) - adata->tdm_rx_fmt[stream->dai_id - 1] = + chip->tdm_rx_fmt[stream->dai_id - 1] = FRM_LEN | (slots << 13) | (slot_len << 18); break; default: dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev); - spin_unlock_irq(&adata->acp_lock); + spin_unlock_irq(&chip->acp_lock); return -EINVAL; } } - spin_unlock_irq(&adata->acp_lock); + spin_unlock_irq(&chip->acp_lock); return 0; } @@ -193,15 +189,15 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata; + struct acp_chip_info *chip; struct acp_resource *rsrc; u32 val; u32 xfer_resolution; u32 reg_val, fmt_reg, tdm_fmt; u32 lrclk_div_val, bclk_div_val; - adata = snd_soc_dai_get_drvdata(dai); - rsrc = adata->rsrc; + chip = dev_get_platdata(dev); + rsrc = chip->rsrc; /* These values are as per Hardware Spec */ switch (params_format(params)) { @@ -240,7 +236,7 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; } - adata->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution; + chip->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution; } else { switch (dai->driver->id) { case I2S_BT_INSTANCE: @@ -259,22 +255,22 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; } - adata->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution; + chip->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution; } - val = readl(adata->acp_base + reg_val); + val = readl(chip->base + reg_val); val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK; val = val | (xfer_resolution << 3); - writel(val, adata->acp_base + reg_val); + writel(val, chip->base + reg_val); - if (adata->tdm_mode) { - val = readl(adata->acp_base + reg_val); - writel(val | BIT(1), adata->acp_base + reg_val); + if (chip->tdm_mode) { + val = readl(chip->base + reg_val); + writel(val | BIT(1), chip->base + reg_val); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - tdm_fmt = adata->tdm_tx_fmt[dai->driver->id - 1]; + tdm_fmt = chip->tdm_tx_fmt[dai->driver->id - 1]; else - tdm_fmt = adata->tdm_rx_fmt[dai->driver->id - 1]; - writel(tdm_fmt, adata->acp_base + fmt_reg); + tdm_fmt = chip->tdm_rx_fmt[dai->driver->id - 1]; + writel(tdm_fmt, chip->base + fmt_reg); } if (rsrc->soc_mclk) { @@ -377,8 +373,8 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ default: break; } - adata->lrclk_div = lrclk_div_val; - adata->bclk_div = bclk_div_val; + chip->lrclk_div = lrclk_div_val; + chip->bclk_div = bclk_div_val; } return 0; } @@ -387,8 +383,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg; period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); @@ -398,20 +394,20 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - stream->bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream); + stream->bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { switch (dai->driver->id) { case I2S_BT_INSTANCE: - water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_BTTDM_ITER; ier_val = ACP_BTTDM_IER; - buf_reg = ACP_BT_TX_RINGBUFSIZE(adata); + buf_reg = ACP_BT_TX_RINGBUFSIZE(chip); break; case I2S_SP_INSTANCE: - water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_I2STDM_ITER; ier_val = ACP_I2STDM_IER; - buf_reg = ACP_I2S_TX_RINGBUFSIZE(adata); + buf_reg = ACP_I2S_TX_RINGBUFSIZE(chip); break; case I2S_HS_INSTANCE: water_val = ACP_HS_TX_INTR_WATERMARK_SIZE; @@ -426,16 +422,16 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct } else { switch (dai->driver->id) { case I2S_BT_INSTANCE: - water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_BTTDM_IRER; ier_val = ACP_BTTDM_IER; - buf_reg = ACP_BT_RX_RINGBUFSIZE(adata); + buf_reg = ACP_BT_RX_RINGBUFSIZE(chip); break; case I2S_SP_INSTANCE: - water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(adata); + water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(chip); reg_val = ACP_I2STDM_IRER; ier_val = ACP_I2STDM_IER; - buf_reg = ACP_I2S_RX_RINGBUFSIZE(adata); + buf_reg = ACP_I2S_RX_RINGBUFSIZE(chip); break; case I2S_HS_INSTANCE: water_val = ACP_HS_RX_INTR_WATERMARK_SIZE; @@ -449,14 +445,14 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct } } - writel(period_bytes, adata->acp_base + water_val); - writel(buf_size, adata->acp_base + buf_reg); + writel(period_bytes, chip->base + water_val); + writel(buf_size, chip->base + buf_reg); if (rsrc->soc_mclk) - acp_set_i2s_clk(adata, dai->driver->id); - val = readl(adata->acp_base + reg_val); + acp_set_i2s_clk(chip, dai->driver->id); + val = readl(chip->base + reg_val); val = val | BIT(0); - writel(val, adata->acp_base + reg_val); - writel(1, adata->acp_base + ier_val); + writel(val, chip->base + reg_val); + writel(1, chip->base + ier_val); return 0; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: @@ -493,19 +489,19 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct return -EINVAL; } } - val = readl(adata->acp_base + reg_val); + val = readl(chip->base + reg_val); val = val & ~BIT(0); - writel(val, adata->acp_base + reg_val); + writel(val, chip->base + reg_val); - if (!(readl(adata->acp_base + ACP_BTTDM_ITER) & BIT(0)) && - !(readl(adata->acp_base + ACP_BTTDM_IRER) & BIT(0))) - writel(0, adata->acp_base + ACP_BTTDM_IER); - if (!(readl(adata->acp_base + ACP_I2STDM_ITER) & BIT(0)) && - !(readl(adata->acp_base + ACP_I2STDM_IRER) & BIT(0))) - writel(0, adata->acp_base + ACP_I2STDM_IER); - if (!(readl(adata->acp_base + ACP_HSTDM_ITER) & BIT(0)) && - !(readl(adata->acp_base + ACP_HSTDM_IRER) & BIT(0))) - writel(0, adata->acp_base + ACP_HSTDM_IER); + if (!(readl(chip->base + ACP_BTTDM_ITER) & BIT(0)) && + !(readl(chip->base + ACP_BTTDM_IRER) & BIT(0))) + writel(0, chip->base + ACP_BTTDM_IER); + if (!(readl(chip->base + ACP_I2STDM_ITER) & BIT(0)) && + !(readl(chip->base + ACP_I2STDM_IRER) & BIT(0))) + writel(0, chip->base + ACP_I2STDM_IER); + if (!(readl(chip->base + ACP_HSTDM_ITER) & BIT(0)) && + !(readl(chip->base + ACP_HSTDM_IRER) & BIT(0))) + writel(0, chip->base + ACP_HSTDM_IER); return 0; default: return -EINVAL; @@ -517,9 +513,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_chip_info *chip; - struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; struct acp_stream *stream = substream->runtime->private_data; u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0; u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl; @@ -529,56 +524,56 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d switch (dai->driver->id) { case I2S_SP_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_SP_TX_MEM_WINDOW_START; else phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_SP_RX_MEM_WINDOW_START; else phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip)); } break; case I2S_BT_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_BT_TX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_BT_TX_MEM_WINDOW_START; else phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_BT_RX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip); if (chip->acp_rev >= ACP70_PCI_ID) phy_addr = ACP7x_I2S_BT_RX_MEM_WINDOW_START; else phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip)); } break; case I2S_HS_INSTANCE: @@ -593,7 +588,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d phy_addr = ACP7x_I2S_HS_TX_MEM_WINDOW_START; else phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR); } else { reg_dma_size = ACP_HS_RX_DMA_SIZE; acp_fifo_addr = rsrc->sram_pte_offset + @@ -605,7 +600,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d phy_addr = ACP7x_I2S_HS_RX_MEM_WINDOW_START; else phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR); } break; default: @@ -613,9 +608,9 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d return -EINVAL; } - writel(DMA_SIZE, adata->acp_base + reg_dma_size); - writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); - writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); + writel(DMA_SIZE, chip->base + reg_dma_size); + writel(acp_fifo_addr, chip->base + reg_fifo_addr); + writel(FIFO_SIZE, chip->base + reg_fifo_size); ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | @@ -634,8 +629,8 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_resource *rsrc = adata->rsrc; + struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; unsigned int dir = substream->stream; unsigned int irq_bit = 0; diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 13fddce8df56..988b7a17b2f4 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -38,26 +38,25 @@ EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); irqreturn_t acp_irq_handler(int irq, void *data) { struct acp_chip_info *chip = data; - struct acp_dev_data *adata = chip->adata; - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; struct acp_stream *stream; u16 i2s_flag = 0; u32 ext_intr_stat, ext_intr_stat1; - if (adata->rsrc->no_of_ctrls == 2) + if (rsrc->no_of_ctrls == 2) ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1))); ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { if (ext_intr_stat & stream->irq_bit) { writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); snd_pcm_period_elapsed(stream->substream); i2s_flag = 1; } - if (adata->rsrc->no_of_ctrls == 2) { + if (chip->rsrc->no_of_ctrls == 2) { if (ext_intr_stat1 & stream->irq_bit) { writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1))); @@ -66,7 +65,7 @@ irqreturn_t acp_irq_handler(int irq, void *data) } } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); if (i2s_flag) return IRQ_HANDLED; @@ -106,7 +105,7 @@ static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct acp_stream *stream = runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); u32 physical_addr, pdm_size, period_bytes; @@ -115,43 +114,40 @@ static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream, physical_addr = stream->reg_offset + MEM_WINDOW_START; /* Init ACP PDM Ring buffer */ - writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR); - writel(pdm_size, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE); - writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE); - writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); + writel(physical_addr, chip->base + ACP_WOV_RX_RINGBUFADDR); + writel(pdm_size, chip->base + ACP_WOV_RX_RINGBUFSIZE); + writel(period_bytes, chip->base + ACP_WOV_RX_INTR_WATERMARK_SIZE); + writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); } static void set_acp_pdm_clk(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); unsigned int pdm_ctrl; /* Enable default ACP PDM clk */ - writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL); - pdm_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL); + writel(PDM_CLK_FREQ_MASK, chip->base + ACP_WOV_CLK_CTRL); + pdm_ctrl = readl(chip->base + ACP_WOV_MISC_CTRL); pdm_ctrl |= PDM_MISC_CTRL_MASK; - writel(pdm_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL); + writel(pdm_ctrl, chip->base + ACP_WOV_MISC_CTRL); set_acp_pdm_ring_buffer(substream, dai); } void restore_acp_pdm_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata) + struct acp_chip_info *chip) { struct snd_soc_dai *dai; - struct device *dev; - struct acp_chip_info *chip; struct snd_soc_pcm_runtime *soc_runtime; u32 ext_int_ctrl; soc_runtime = snd_soc_substream_to_rtd(substream); dai = snd_soc_rtd_to_cpu(soc_runtime, 0); - dev = dai->component->dev; - chip = dev_get_platdata(dev); + /* Programming channel mask and sampling rate */ - writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); - writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR); + writel(chip->ch_mask, chip->base + ACP_WOV_PDM_NO_OF_CHANNELS); + writel(PDM_DEC_64, chip->base + ACP_WOV_PDM_DECIMATION_FACTOR); /* Enabling ACP Pdm interuppts */ ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); @@ -165,9 +161,8 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); - struct acp_resource *rsrc = adata->rsrc; struct acp_chip_info *chip = dev_get_platdata(dev); + struct acp_resource *rsrc = chip->rsrc; struct acp_stream *stream = substream->runtime->private_data; u32 reg_dma_size, reg_fifo_size, reg_fifo_addr; u32 phy_addr, acp_fifo_addr, ext_int_ctrl; @@ -176,40 +171,40 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, switch (dai->driver->id) { case I2S_SP_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip); phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata); + reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + SP_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata); - reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip); + reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip); phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip)); } break; case I2S_BT_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - reg_dma_size = ACP_BT_TX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_TX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_PB_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip); phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip)); } else { - reg_dma_size = ACP_BT_RX_DMA_SIZE(adata); + reg_dma_size = ACP_BT_RX_DMA_SIZE(chip); acp_fifo_addr = rsrc->sram_pte_offset + BT_CAPT_FIFO_ADDR_OFFSET; - reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata); - reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata); + reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip); + reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip); phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata)); + writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip)); } break; case I2S_HS_INSTANCE: @@ -220,7 +215,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, reg_fifo_addr = ACP_HS_TX_FIFOADDR; reg_fifo_size = ACP_HS_TX_FIFOSIZE; phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR); } else { reg_dma_size = ACP_HS_RX_DMA_SIZE; acp_fifo_addr = rsrc->sram_pte_offset + @@ -228,7 +223,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, reg_fifo_addr = ACP_HS_RX_FIFOADDR; reg_fifo_size = ACP_HS_RX_FIFOSIZE; phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; - writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR); + writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR); } break; default: @@ -236,9 +231,9 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, return -EINVAL; } - writel(DMA_SIZE, adata->acp_base + reg_dma_size); - writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); - writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); + writel(DMA_SIZE, chip->base + reg_dma_size); + writel(acp_fifo_addr, chip->base + reg_fifo_addr); + writel(FIFO_SIZE, chip->base + reg_fifo_size); ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | @@ -253,7 +248,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, } int restore_acp_i2s_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata, + struct acp_chip_info *chip, struct acp_stream *stream) { struct snd_soc_dai *dai; @@ -263,7 +258,7 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, soc_runtime = snd_soc_substream_to_rtd(substream); dai = snd_soc_rtd_to_cpu(soc_runtime, 0); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - tdm_fmt = adata->tdm_tx_fmt[stream->dai_id - 1]; + tdm_fmt = chip->tdm_tx_fmt[stream->dai_id - 1]; switch (stream->dai_id) { case I2S_BT_INSTANCE: reg_val = ACP_BTTDM_ITER; @@ -281,9 +276,9 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, pr_err("Invalid dai id %x\n", stream->dai_id); return -EINVAL; } - val = adata->xfer_tx_resolution[stream->dai_id - 1] << 3; + val = chip->xfer_tx_resolution[stream->dai_id - 1] << 3; } else { - tdm_fmt = adata->tdm_rx_fmt[stream->dai_id - 1]; + tdm_fmt = chip->tdm_rx_fmt[stream->dai_id - 1]; switch (stream->dai_id) { case I2S_BT_INSTANCE: reg_val = ACP_BTTDM_IRER; @@ -301,13 +296,13 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream, pr_err("Invalid dai id %x\n", stream->dai_id); return -EINVAL; } - val = adata->xfer_rx_resolution[stream->dai_id - 1] << 3; + val = chip->xfer_rx_resolution[stream->dai_id - 1] << 3; } - writel(val, adata->acp_base + reg_val); - if (adata->tdm_mode == TDM_ENABLE) { - writel(tdm_fmt, adata->acp_base + fmt_reg); - val = readl(adata->acp_base + reg_val); - writel(val | 0x2, adata->acp_base + reg_val); + writel(val, chip->base + reg_val); + if (chip->tdm_mode == TDM_ENABLE) { + writel(tdm_fmt, chip->base + fmt_reg); + val = readl(chip->base + reg_val); + writel(val | 0x2, chip->base + reg_val); } return set_acp_i2s_dma_fifo(substream, dai); } diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index 9a820ef3bf46..1bfc34c2aa53 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -30,17 +30,16 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream, { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; u32 physical_addr, size_dmic, period_bytes; unsigned int dmic_ctrl; chip = dev_get_platdata(dev); /* Enable default DMIC clk */ - writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL); - dmic_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL); + writel(PDM_CLK_FREQ_MASK, chip->base + ACP_WOV_CLK_CTRL); + dmic_ctrl = readl(chip->base + ACP_WOV_MISC_CTRL); dmic_ctrl |= PDM_MISC_CTRL_MASK; - writel(dmic_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL); + writel(dmic_ctrl, chip->base + ACP_WOV_MISC_CTRL); period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); @@ -53,10 +52,10 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream, physical_addr = stream->reg_offset + MEM_WINDOW_START; /* Init DMIC Ring buffer */ - writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR); - writel(size_dmic, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE); - writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE); - writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); + writel(physical_addr, chip->base + ACP_WOV_RX_RINGBUFADDR); + writel(size_dmic, chip->base + ACP_WOV_RX_RINGBUFSIZE); + writel(period_bytes, chip->base + ACP_WOV_RX_INTR_WATERMARK_SIZE); + writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); return 0; } @@ -65,7 +64,7 @@ static int acp_dmic_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); unsigned int dma_enable; int ret = 0; @@ -73,27 +72,27 @@ static int acp_dmic_dai_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + dma_enable = readl(chip->base + ACP_WOV_PDM_DMA_ENABLE); if (!(dma_enable & DMA_EN_MASK)) { - writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_ENABLE); - writel(PDM_ENABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + writel(PDM_ENABLE, chip->base + ACP_WOV_PDM_ENABLE); + writel(PDM_ENABLE, chip->base + ACP_WOV_PDM_DMA_ENABLE); } - ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE, + ret = readl_poll_timeout_atomic(chip->base + ACP_WOV_PDM_DMA_ENABLE, dma_enable, (dma_enable & DMA_EN_MASK), DELAY_US, PDM_TIMEOUT); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - dma_enable = readl(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + dma_enable = readl(chip->base + ACP_WOV_PDM_DMA_ENABLE); if ((dma_enable & DMA_EN_MASK)) { - writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_ENABLE); - writel(PDM_DISABLE, adata->acp_base + ACP_WOV_PDM_DMA_ENABLE); + writel(PDM_DISABLE, chip->base + ACP_WOV_PDM_ENABLE); + writel(PDM_DISABLE, chip->base + ACP_WOV_PDM_DMA_ENABLE); } - ret = readl_poll_timeout_atomic(adata->acp_base + ACP_WOV_PDM_DMA_ENABLE, + ret = readl_poll_timeout_atomic(chip->base + ACP_WOV_PDM_DMA_ENABLE, dma_enable, !(dma_enable & DMA_EN_MASK), DELAY_US, PDM_TIMEOUT); break; @@ -109,7 +108,7 @@ static int acp_dmic_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hwparams, struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); unsigned int channels, ch_mask; channels = params_channels(hwparams); @@ -128,14 +127,14 @@ static int acp_dmic_hwparams(struct snd_pcm_substream *substream, return -EINVAL; } - adata->ch_mask = ch_mask; + chip->ch_mask = ch_mask; if (params_format(hwparams) != SNDRV_PCM_FORMAT_S32_LE) { dev_err(dai->dev, "Invalid format:%d\n", params_format(hwparams)); return -EINVAL; } - writel(ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS); - writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR); + writel(ch_mask, chip->base + ACP_WOV_PDM_NO_OF_CHANNELS); + writel(PDM_DEC_64, chip->base + ACP_WOV_PDM_DECIMATION_FACTOR); return 0; } diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 9b181fb5861c..8d61e1991e4f 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -107,37 +107,37 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = { .periods_max = CAPTURE_MAX_NUM_PERIODS, }; -void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream) +void config_pte_for_stream(struct acp_chip_info *chip, struct acp_stream *stream) { - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; u32 reg_val; reg_val = rsrc->sram_pte_offset; stream->reg_offset = 0x02000000; - writel((reg_val + GRP1_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); + writel((reg_val + GRP1_OFFSET) | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); - writel((reg_val + GRP2_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2); + writel((reg_val + GRP2_OFFSET) | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2); - writel(reg_val | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5); + writel(reg_val | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5); - writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); + writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); } EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, "SND_SOC_ACP_COMMON"); -void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size) +void config_acp_dma(struct acp_chip_info *chip, struct acp_stream *stream, int size) { struct snd_pcm_substream *substream = stream->substream; - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; dma_addr_t addr = substream->dma_buffer.addr; int num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); u32 low, high, val; u16 page_idx; - switch (adata->acp_rev) { + switch (chip->acp_rev) { case ACP70_PCI_ID: case ACP71_PCI_ID: switch (stream->dai_id) { @@ -163,7 +163,7 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s val = 0x6000; break; default: - dev_err(adata->dev, "Invalid dai id %x\n", stream->dai_id); + dev_err(chip->dev, "Invalid dai id %x\n", stream->dai_id); return; } break; @@ -176,9 +176,9 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s /* Load the low address of page int ACP SRAM through SRBM */ low = lower_32_bits(addr); high = upper_32_bits(addr); - writel(low, adata->acp_base + rsrc->scratch_reg_offset + val); + writel(low, chip->base + rsrc->scratch_reg_offset + val); high |= BIT(31); - writel(high, adata->acp_base + rsrc->scratch_reg_offset + val + 4); + writel(high, chip->base + rsrc->scratch_reg_offset + val + 4); /* Move to next physically contiguous page */ val += 8; @@ -191,7 +191,6 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs { struct snd_pcm_runtime *runtime = substream->runtime; struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; struct acp_stream *stream; int ret; @@ -201,7 +200,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs return -ENOMEM; stream->substream = substream; - chip = dev_get_platdata(dev); + chip = dev_get_drvdata(dev->parent); switch (chip->acp_rev) { case ACP63_PCI_ID: case ACP70_PCI_ID: @@ -243,9 +242,9 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs writel(1, ACP_EXTERNAL_INTR_ENB(chip)); - spin_lock_irq(&adata->acp_lock); - list_add_tail(&stream->list, &adata->stream_list); - spin_unlock_irq(&adata->acp_lock); + spin_lock_irq(&chip->acp_lock); + list_add_tail(&stream->list, &chip->stream_list); + spin_unlock_irq(&chip->acp_lock); return ret; } @@ -254,13 +253,14 @@ static int acp_dma_hw_params(struct snd_soc_component *component, struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct acp_dev_data *adata = snd_soc_component_get_drvdata(component); + struct device *dev = component->dev; + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; u64 size = params_buffer_bytes(params); /* Configure ACP DMA block with params */ - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, size); return 0; } @@ -269,7 +269,7 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; u32 pos, buffersize; u64 bytescount; @@ -277,7 +277,7 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component, buffersize = frames_to_bytes(substream->runtime, substream->runtime->buffer_size); - bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream); + bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream); if (bytescount > stream->bytescount) bytescount -= stream->bytescount; @@ -301,13 +301,13 @@ static int acp_dma_close(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; /* Remove entry from list */ - spin_lock_irq(&adata->acp_lock); + spin_lock_irq(&chip->acp_lock); list_del(&stream->list); - spin_unlock_irq(&adata->acp_lock); + spin_unlock_irq(&chip->acp_lock); kfree(stream); return 0; @@ -325,7 +325,6 @@ static const struct snd_soc_component_driver acp_pcm_component = { int acp_platform_register(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; struct snd_soc_dai_driver; unsigned int status; @@ -336,17 +335,16 @@ int acp_platform_register(struct device *dev) return -ENODEV; } - chip->adata = adata; status = devm_snd_soc_register_component(dev, &acp_pcm_component, - adata->dai_driver, - adata->num_dai); + chip->dai_driver, + chip->num_dai); if (status) { dev_err(dev, "Fail to register acp i2s component\n"); return status; } - INIT_LIST_HEAD(&adata->stream_list); - spin_lock_init(&adata->acp_lock); + INIT_LIST_HEAD(&chip->stream_list); + spin_lock_init(&chip->acp_lock); return 0; } @@ -354,10 +352,6 @@ EXPORT_SYMBOL_NS_GPL(acp_platform_register, "SND_SOC_ACP_COMMON"); int acp_platform_unregister(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); - - if (adata->mach_dev) - platform_device_unregister(adata->mach_dev); return 0; } EXPORT_SYMBOL_NS_GPL(acp_platform_unregister, "SND_SOC_ACP_COMMON"); diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index 13633b3f3730..dfb18d5cdc7a 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -157,8 +157,6 @@ static int rembrandt_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; u32 ret; chip = dev_get_platdata(&pdev->dev); @@ -172,37 +170,10 @@ static int rembrandt_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); - return -ENODEV; - } - + chip->dev = dev; chip->rsrc = &rsrc; - adata->i2s_irq = res->start; - adata->dev = dev; - adata->dai_driver = acp_rmb_dai; - adata->num_dai = ARRAY_SIZE(acp_rmb_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; - adata->is_i2s_config = chip->is_i2s_config; - - dev_set_drvdata(dev, adata); + chip->dai_driver = acp_rmb_dai; + chip->num_dai = ARRAY_SIZE(acp_rmb_dai); if (chip->is_i2s_config && rsrc.soc_mclk) { ret = acp6x_master_clock_generate(dev); @@ -239,30 +210,30 @@ static void rembrandt_audio_remove(struct platform_device *pdev) static int __maybe_unused rmb_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - if (adata->is_i2s_config && adata->rsrc->soc_mclk) + if (chip->is_i2s_config && chip->rsrc->soc_mclk) acp6x_master_clock_generate(dev); - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 94ecb17684b7..2037af67509a 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -108,8 +108,6 @@ static int renoir_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; int ret; chip = dev_get_platdata(&pdev->dev); @@ -123,39 +121,17 @@ static int renoir_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - ret = platform_get_irq_byname(pdev, "acp_dai_irq"); - if (ret < 0) - return ret; - adata->i2s_irq = ret; - + chip->dev = dev; chip->rsrc = &rsrc; - adata->dev = dev; - adata->dai_driver = acp_renoir_dai; - adata->num_dai = ARRAY_SIZE(acp_renoir_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; + chip->dai_driver = acp_renoir_dai; + chip->num_dai = ARRAY_SIZE(acp_renoir_dai); - dev_set_drvdata(dev, adata); ret = acp_hw_en_interrupts(chip); if (ret) { dev_err(dev, "ACP en-interrupts failed\n"); return ret; } + acp_platform_register(dev); pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS); @@ -181,27 +157,27 @@ static void renoir_audio_remove(struct platform_device *pdev) static int __maybe_unused rn_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index e38ad9f7fb48..49786e1a214f 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -153,7 +153,7 @@ static struct snd_soc_dai_driver acp63_dai[] = { }, }; -static int acp63_i2s_master_clock_generate(struct acp_dev_data *adata) +static int acp63_i2s_master_clock_generate(struct acp_chip_info *chip) { int rc; u32 data; @@ -208,8 +208,6 @@ static int acp63_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; int ret; chip = dev_get_platdata(&pdev->dev); @@ -223,39 +221,13 @@ static int acp63_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); - return -ENODEV; - } - + chip->dev = dev; chip->rsrc = &rsrc; - adata->i2s_irq = res->start; - adata->dev = dev; - adata->dai_driver = acp63_dai; - adata->num_dai = ARRAY_SIZE(acp63_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; - adata->is_i2s_config = chip->is_i2s_config; - dev_set_drvdata(dev, adata); + chip->dai_driver = acp63_dai; + chip->num_dai = ARRAY_SIZE(acp63_dai); if (chip->is_i2s_config && rsrc.soc_mclk) { - ret = acp63_i2s_master_clock_generate(adata); + ret = acp63_i2s_master_clock_generate(chip); if (ret) return ret; } @@ -289,30 +261,30 @@ static void acp63_audio_remove(struct platform_device *pdev) static int __maybe_unused acp63_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - if (adata->is_i2s_config && adata->rsrc->soc_mclk) - acp63_i2s_master_clock_generate(adata); + if (chip->is_i2s_config && chip->rsrc->soc_mclk) + acp63_i2s_master_clock_generate(chip); - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index be4302a5a584..c1b546df5e67 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -135,8 +135,6 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acp_chip_info *chip; - struct acp_dev_data *adata; - struct resource *res; int ret; chip = dev_get_platdata(&pdev->dev); @@ -154,36 +152,10 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) return -ENODEV; } - adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); - if (!adata) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); - return -ENODEV; - } - - adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!adata->acp_base) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); - if (!res) { - dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); - return -ENODEV; - } - + chip->dev = dev; chip->rsrc = &rsrc; - adata->i2s_irq = res->start; - adata->dev = dev; - adata->dai_driver = acp70_dai; - adata->num_dai = ARRAY_SIZE(acp70_dai); - adata->rsrc = &rsrc; - adata->acp_rev = chip->acp_rev; - adata->flag = chip->flag; - - dev_set_drvdata(dev, adata); + chip->dai_driver = acp70_dai; + chip->num_dai = ARRAY_SIZE(acp70_dai); /* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/ ret = amd_smn_write(0, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER); @@ -221,27 +193,27 @@ static void acp_acp70_audio_remove(struct platform_device *pdev) static int __maybe_unused acp70_pcm_resume(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; struct snd_pcm_substream *substream; snd_pcm_uframes_t buf_in_frames; u64 buf_size; - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { + spin_lock(&chip->acp_lock); + list_for_each_entry(stream, &chip->stream_list, list) { substream = stream->substream; if (substream && substream->runtime) { buf_in_frames = (substream->runtime->buffer_size); buf_size = frames_to_bytes(substream->runtime, buf_in_frames); - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, buf_size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, buf_size); if (stream->dai_id) - restore_acp_i2s_params(substream, adata, stream); + restore_acp_i2s_params(substream, chip, stream); else - restore_acp_pdm_params(substream, adata); + restore_acp_pdm_params(substream, chip); } } - spin_unlock(&adata->acp_lock); + spin_unlock(&chip->acp_lock); return 0; } diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 4beaa9cae352..084d9db1b65c 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -142,22 +142,34 @@ struct acp_chip_info { char *name; /* Platform name */ struct resource *res; struct device *dev; + struct snd_soc_dai_driver *dai_driver; + unsigned int acp_rev; /* ACP Revision id */ void __iomem *base; /* ACP memory PCI base */ struct snd_acp_hw_ops *acp_hw_ops; int (*acp_hw_ops_init)(struct acp_chip_info *chip); struct platform_device *chip_pdev; struct acp_resource *rsrc; /* Platform specific resources*/ + struct list_head stream_list; + spinlock_t acp_lock; /* Used to protect stream_list */ struct platform_device *dmic_codec_dev; struct platform_device *acp_plat_dev; struct platform_device *mach_dev; struct snd_soc_acpi_mach *machines; - struct acp_dev_data *adata; + int num_dai; u32 addr; + u32 bclk_div; + u32 lrclk_div; + u32 ch_mask; + u32 tdm_tx_fmt[3]; + u32 tdm_rx_fmt[3]; + u32 xfer_tx_resolution[3]; + u32 xfer_rx_resolution[3]; unsigned int flag; /* Distinguish b/w Legacy or Only PDM */ bool is_pdm_dev; /* flag set to true when ACP PDM controller exists */ bool is_pdm_config; /* flag set to true when PDM configuration is selected from BIOS */ bool is_i2s_config; /* flag set to true when I2S configuration is selected from BIOS */ + bool tdm_mode; }; struct acp_stream { @@ -183,36 +195,6 @@ struct acp_resource { u64 sram_pte_offset; }; -struct acp_dev_data { - char *name; - struct device *dev; - void __iomem *acp_base; - unsigned int i2s_irq; - unsigned int acp_rev; /* ACP Revision id */ - - bool tdm_mode; - bool is_i2s_config; - /* SOC specific dais */ - struct snd_soc_dai_driver *dai_driver; - int num_dai; - - struct list_head stream_list; - spinlock_t acp_lock; - - struct platform_device *mach_dev; - - u32 bclk_div; - u32 lrclk_div; - - struct acp_resource *rsrc; - u32 ch_mask; - u32 tdm_tx_fmt[3]; - u32 tdm_rx_fmt[3]; - u32 xfer_tx_resolution[3]; - u32 xfer_rx_resolution[3]; - unsigned int flag; -}; - /** * struct snd_acp_hw_ops - ACP PCI driver platform specific ops * @acp_init: ACP initialization @@ -357,13 +339,13 @@ extern int acp70_hw_ops_init(struct acp_chip_info *chip); /* Machine configuration */ int snd_amd_acp_find_config(struct pci_dev *pci); -void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream); -void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size); +void config_pte_for_stream(struct acp_chip_info *chip, struct acp_stream *stream); +void config_acp_dma(struct acp_chip_info *chip, struct acp_stream *stream, int size); void restore_acp_pdm_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata); + struct acp_chip_info *chip); int restore_acp_i2s_params(struct snd_pcm_substream *substream, - struct acp_dev_data *adata, struct acp_stream *stream); + struct acp_chip_info *chip, struct acp_stream *stream); void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip); @@ -395,48 +377,48 @@ static inline int acp_hw_dis_interrupts(struct acp_chip_info *chip) return -EOPNOTSUPP; } -static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction) +static inline u64 acp_get_byte_count(struct acp_chip_info *chip, int dai_id, int direction) { u64 byte_count = 0, low = 0, high = 0; if (direction == SNDRV_PCM_STREAM_PLAYBACK) { switch (dai_id) { case I2S_BT_INSTANCE: - high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_SP_INSTANCE: - high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_HS_INSTANCE: - high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); - low = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW); + high = readl(chip->base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); + low = readl(chip->base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW); break; default: - dev_err(adata->dev, "Invalid dai id %x\n", dai_id); + dev_err(chip->dev, "Invalid dai id %x\n", dai_id); goto POINTER_RETURN_BYTES; } } else { switch (dai_id) { case I2S_BT_INSTANCE: - high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_SP_INSTANCE: - high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata)); - low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata)); + high = readl(chip->base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(chip)); + low = readl(chip->base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(chip)); break; case I2S_HS_INSTANCE: - high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); - low = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW); + high = readl(chip->base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); + low = readl(chip->base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW); break; case DMIC_INSTANCE: - high = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH); - low = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW); + high = readl(chip->base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH); + low = readl(chip->base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW); break; default: - dev_err(adata->dev, "Invalid dai id %x\n", dai_id); + dev_err(chip->dev, "Invalid dai id %x\n", dai_id); goto POINTER_RETURN_BYTES; } } From a95a1dbbd3d64adf392fed13c8eef4f72b4e5b90 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:55 +0530 Subject: [PATCH 455/651] ASoC: amd: acp: Move spin_lock and list initialization to acp-pci driver Move spin_lock and linked list initialization from platform driver to acp-pci driver. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-9-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 3 +++ sound/soc/amd/acp/acp-platform.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 1ef9faba1d8a..8bb93ca18053 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -196,6 +196,9 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->dev = &chip->acp_plat_dev->dev; acp_machine_select(chip); + + INIT_LIST_HEAD(&chip->stream_list); + spin_lock_init(&chip->acp_lock); skip_pdev_creation: dev_set_drvdata(&pci->dev, chip); pm_runtime_set_autosuspend_delay(&pci->dev, 2000); diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 8d61e1991e4f..b3eddf76aaa4 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -343,9 +343,6 @@ int acp_platform_register(struct device *dev) return status; } - INIT_LIST_HEAD(&chip->stream_list); - spin_lock_init(&chip->acp_lock); - return 0; } EXPORT_SYMBOL_NS_GPL(acp_platform_register, "SND_SOC_ACP_COMMON"); From c8b5f251f0e53edab220ac4edf444120815fed3c Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:56 +0530 Subject: [PATCH 456/651] ASoC: amd: acp: Remove white line Remove white line in renoir platform driver. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-10-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-renoir.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 2037af67509a..970ca613a439 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -36,7 +36,6 @@ static struct acp_resource rsrc = { .sram_pte_offset = 0x02052800, }; - static struct snd_soc_dai_driver acp_renoir_dai[] = { { .name = "acp-i2s-sp", From f8b4f3f525e82d78079a6ebbde68e4a0d79fd1c0 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:57 +0530 Subject: [PATCH 457/651] ASoC: amd: acp: Refactor acp70 platform resource structure Refactor acp70 platform resource private structure to amd.h header file. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-11-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 1 + sound/soc/amd/acp/acp70.c | 11 ----------- sound/soc/amd/acp/amd.h | 10 ++++++++++ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 8bb93ca18053..6728eee29993 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -151,6 +151,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id case 0x70: case 0x71: chip->name = "acp_asoc_acp70"; + chip->rsrc = &acp70_rsrc; chip->acp_hw_ops_init = acp70_hw_ops_init; chip->machines = snd_soc_acpi_amd_acp70_acp_machines; break; diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index c1b546df5e67..1a89f8a3724f 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -30,16 +30,6 @@ #define CLK7_CLK0_DFS_CNTL_N1 0X0006C1A4 #define CLK0_DIVIDER 0X19 -static struct acp_resource rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x10000, - .sram_pte_offset = 0x03800000, -}; - static struct snd_soc_dai_driver acp70_dai[] = { { .name = "acp-i2s-sp", @@ -153,7 +143,6 @@ static int acp_acp70_audio_probe(struct platform_device *pdev) } chip->dev = dev; - chip->rsrc = &rsrc; chip->dai_driver = acp70_dai; chip->num_dai = ARRAY_SIZE(acp70_dai); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 084d9db1b65c..979d8b8801a3 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,6 +238,16 @@ enum acp_config { ACP_CONFIG_20, }; +struct acp_resource acp70_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x10000, + .sram_pte_offset = 0x03800000, +}; + struct snd_soc_acpi_codecs amp_rt1019 = { .num_codecs = 1, .codecs = {"10EC1019"} From d08220b6e32e88655f54b497fd45a3982b59093c Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:58 +0530 Subject: [PATCH 458/651] ASoC: amd: acp: Refactor acp63 platform resource structure Refactor acp63 platform resource private structure to amd.h header file. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-12-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 1 + sound/soc/amd/acp/acp63.c | 13 +------------ sound/soc/amd/acp/amd.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 6728eee29993..3df665ca1b0b 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -145,6 +145,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id break; case 0x63: chip->name = "acp_asoc_acp63"; + chip->rsrc = &acp63_rsrc; chip->acp_hw_ops_init = acp63_hw_ops_init; chip->machines = snd_soc_acpi_amd_acp63_acp_machines; break; diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 49786e1a214f..53c013a64854 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -52,16 +52,6 @@ union clk_pll_req_no { u32 clk_pll_req_no_reg; }; -static struct acp_resource rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x03802800, -}; - static struct snd_soc_dai_driver acp63_dai[] = { { .name = "acp-i2s-sp", @@ -222,11 +212,10 @@ static int acp63_audio_probe(struct platform_device *pdev) } chip->dev = dev; - chip->rsrc = &rsrc; chip->dai_driver = acp63_dai; chip->num_dai = ARRAY_SIZE(acp63_dai); - if (chip->is_i2s_config && rsrc.soc_mclk) { + if (chip->is_i2s_config && chip->rsrc->soc_mclk) { ret = acp63_i2s_master_clock_generate(chip); if (ret) return ret; diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 979d8b8801a3..075659fb3314 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,6 +238,16 @@ enum acp_config { ACP_CONFIG_20, }; +struct acp_resource acp63_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x03802800, +}; + struct acp_resource acp70_rsrc = { .offset = 0, .no_of_ctrls = 2, From ee7ab0fd540877fceb3d51f87016e6531d86406f Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:01:59 +0530 Subject: [PATCH 459/651] ASoC: amd: acp: Refactor rembrant platform resource structure Refactor rembrandt platform resource private structure to amd.h header fle. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-13-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 1 + sound/soc/amd/acp/acp-rembrandt.c | 13 +------------ sound/soc/amd/acp/amd.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 3df665ca1b0b..6dd905e75f1d 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -140,6 +140,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id break; case 0x6f: chip->name = "acp_asoc_rembrandt"; + chip->rsrc = &rmb_rsrc; chip->acp_hw_ops_init = acp6x_hw_ops_init; chip->machines = snd_soc_acpi_amd_rmb_acp_machines; break; diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index dfb18d5cdc7a..21614e2e1b6c 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -34,16 +34,6 @@ #define MP1_C2PMSG_85 0x3B10A54 #define MP1_C2PMSG_93 0x3B10A74 -static struct acp_resource rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x03802800, -}; - static struct snd_soc_dai_driver acp_rmb_dai[] = { { .name = "acp-i2s-sp", @@ -171,11 +161,10 @@ static int rembrandt_audio_probe(struct platform_device *pdev) } chip->dev = dev; - chip->rsrc = &rsrc; chip->dai_driver = acp_rmb_dai; chip->num_dai = ARRAY_SIZE(acp_rmb_dai); - if (chip->is_i2s_config && rsrc.soc_mclk) { + if (chip->is_i2s_config && chip->rsrc->soc_mclk) { ret = acp6x_master_clock_generate(dev); if (ret) return ret; diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 075659fb3314..0cb6d2abf832 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,6 +238,16 @@ enum acp_config { ACP_CONFIG_20, }; +struct acp_resource rmb_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x03802800, +}; + struct acp_resource acp63_rsrc = { .offset = 0, .no_of_ctrls = 2, From e167e5b268b2d06a7b59872c189fae0f587562ee Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:02:00 +0530 Subject: [PATCH 460/651] ASoC: amd: acp: Refactor renoir platform resource structure Refactor renoir platform resource private structure to amd.h header file. Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-14-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 1 + sound/soc/amd/acp/acp-renoir.c | 10 ---------- sound/soc/amd/acp/amd.h | 9 +++++++++ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 6dd905e75f1d..9322379cb36f 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -135,6 +135,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id switch (pci->revision) { case 0x01: chip->name = "acp_asoc_renoir"; + chip->rsrc = &rn_rsrc; chip->acp_hw_ops_init = acp31_hw_ops_init; chip->machines = snd_soc_acpi_amd_acp_machines; break; diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 970ca613a439..b8ded929d52e 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -27,15 +27,6 @@ #define DRV_NAME "acp_asoc_renoir" -static struct acp_resource rsrc = { - .offset = 20, - .no_of_ctrls = 1, - .irqp_used = 0, - .irq_reg_offset = 0x1800, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x02052800, -}; - static struct snd_soc_dai_driver acp_renoir_dai[] = { { .name = "acp-i2s-sp", @@ -121,7 +112,6 @@ static int renoir_audio_probe(struct platform_device *pdev) } chip->dev = dev; - chip->rsrc = &rsrc; chip->dai_driver = acp_renoir_dai; chip->num_dai = ARRAY_SIZE(acp_renoir_dai); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 0cb6d2abf832..796f8efd395c 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,6 +238,15 @@ enum acp_config { ACP_CONFIG_20, }; +struct acp_resource rn_rsrc = { + .offset = 20, + .no_of_ctrls = 1, + .irqp_used = 0, + .irq_reg_offset = 0x1800, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x02052800, +}; + struct acp_resource rmb_rsrc = { .offset = 0, .no_of_ctrls = 2, From 02e1cf7a352a3ba5f768849f2b4fcaaaa19f89e3 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Tue, 11 Mar 2025 00:02:01 +0530 Subject: [PATCH 461/651] ASoC: amd: acp: Fix for enabling DMIC on acp platforms via _DSD entry Add condition check to register ACP PDM sound card by reading _WOV acpi entry. Fixes: 09068d624c49 ("ASoC: amd: acp: fix for acp platform device creation failure") Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250310183201.11979-15-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 988b7a17b2f4..255f90ca956a 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -13,6 +13,7 @@ */ #include "amd.h" +#include #include #include @@ -511,7 +512,9 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip) { struct acpi_device *pdm_dev; const union acpi_object *obj; - u32 pdm_addr; + acpi_handle handle; + acpi_integer dmic_status; + u32 pdm_addr, ret; switch (chip->acp_rev) { case ACP_RN_PCI_ID: @@ -543,6 +546,11 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip) obj->integer.value == pdm_addr) chip->is_pdm_dev = true; } + + handle = ACPI_HANDLE(&pci->dev); + ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status); + if (!ACPI_FAILURE(ret)) + chip->is_pdm_dev = dmic_status; } } EXPORT_SYMBOL_NS_GPL(check_acp_config, "SND_SOC_ACP_COMMON"); From 87fa872a1ecf542efc66a9184127faf03037f827 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 12 Mar 2025 11:02:25 +0100 Subject: [PATCH 462/651] ASoC: samsung: speyside: Free gpiod table We create a gpio descriptor table but it needs to be free:ed when the module is removed. Add a devm_ action to do the job. Suggested-by: Andy Shevchenko Fixes: da9146c19b17 ("ASoC: samsung: speyside: Convert to GPIO descriptor") Signed-off-by: Linus Walleij Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20250312-cleanup-table-v1-1-1d9a14464482@linaro.org Signed-off-by: Mark Brown --- sound/soc/samsung/speyside.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index f781e2be2fd4..9262e5626584 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -347,6 +347,11 @@ static struct gpiod_lookup_table wm8996_gpiod_table = { }, }; +static void speyside_gpiod_table_action(void *data) +{ + gpiod_remove_lookup_table(&wm8996_gpiod_table); +} + static int speyside_probe(struct platform_device *pdev) { struct snd_soc_card *card = &speyside; @@ -355,6 +360,11 @@ static int speyside_probe(struct platform_device *pdev) card->dev = &pdev->dev; gpiod_add_lookup_table(&wm8996_gpiod_table); + ret = devm_add_action_or_reset(&pdev->dev, speyside_gpiod_table_action, + NULL); + if (ret) + return ret; + ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) dev_err_probe(&pdev->dev, ret, "snd_soc_register_card() failed\n"); From 520a563b9a162d8a7484a32086de8e7c84d69945 Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Sat, 8 Mar 2025 13:52:59 -0500 Subject: [PATCH 463/651] ALSA: ctxfi: change dao_set_input functions from kzalloc to kcalloc We are trying to get rid of all multiplications from allocation functions to prevent potential integer overflows. Here the multiplication is probably safe, but using kcalloc() is more appropriate and improves readability. This patch has no effect on runtime behavior. Link: https://github.com/KSPP/linux/issues/162 [1] Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Signed-off-by: Ethan Carter Edwards Link: https://patch.msgid.link/20250308-ctdaio-kzalloc-v1-1-804a09875b0e@ethancedwards.com Signed-off-by: Takashi Iwai --- sound/pci/ctxfi/ctdaio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index 9993b02d2968..806c4d754387 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -159,7 +159,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input) struct daio *daio = &dao->daio; int i; - entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL); + entry = kcalloc(daio->rscl.msr, sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; @@ -188,7 +188,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input) struct daio *daio = &dao->daio; int i; - entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL); + entry = kcalloc(daio->rscr.msr, sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; From a935b3f981809272d2649ad9c27a751685137846 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 12 Mar 2025 18:05:16 +0200 Subject: [PATCH 464/651] ASoC: SOF: ipc4-topology: Allocate ref_params on stack Currently the compiler (clang 19.1.7) is not happy about the size of the stack frame in sof_ipc4_prepare_copier_module: sound/soc/sof/ipc4-topology.c:1800:1: error: stack frame size (1288) exceeds limit (1024) in 'sof_ipc4_prepare_copier_module' [-Werror,-Wframe-larger-than] 1800 | sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, | ^ Work around this by allocating ref_params on stack, as it looks the biggest variable on stack right now. Note, this only happens when compile for 32-bit machines (x86_32 in my case). Signed-off-by: Andy Shevchenko Acked-by: Peter Ujfalusi Link: https://patch.msgid.link/20250312160516.3864295-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index f14b8ef8d0b0..540ba140e155 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -7,6 +7,7 @@ // // #include +#include #include #include #include @@ -1807,8 +1808,8 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct sof_ipc4_copier_data *copier_data; int input_fmt_index, output_fmt_index; - struct snd_pcm_hw_params ref_params; struct sof_ipc4_copier *ipc4_copier; + struct snd_pcm_hw_params *ref_params __free(kfree) = NULL; struct snd_sof_dai *dai; u32 gtw_cfg_config_length; u32 dma_config_tlv_size = 0; @@ -1885,9 +1886,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, * for capture. */ if (dir == SNDRV_PCM_STREAM_PLAYBACK) - ref_params = *fe_params; + ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL); else - ref_params = *pipeline_params; + ref_params = kmemdup(pipeline_params, sizeof(*ref_params), GFP_KERNEL); + if (!ref_params) + return -ENOMEM; copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; copier_data->gtw_cfg.node_id |= @@ -1924,8 +1927,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, * In case of capture the ref_params returned will be used to * find the input configuration of the copier. */ - ref_params = *fe_params; - ret = sof_ipc4_prepare_dai_copier(sdev, dai, &ref_params, dir); + ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL); + if (!ref_params) + return -ENOMEM; + + ret = sof_ipc4_prepare_dai_copier(sdev, dai, ref_params, dir); if (ret < 0) return ret; @@ -1934,7 +1940,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, * input configuration of the copier. */ if (dir == SNDRV_PCM_STREAM_PLAYBACK) - ref_params = *pipeline_params; + memcpy(ref_params, pipeline_params, sizeof(*ref_params)); break; } @@ -1946,7 +1952,10 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, ipc4_copier = (struct sof_ipc4_copier *)swidget->private; copier_data = &ipc4_copier->data; available_fmt = &ipc4_copier->available_fmt; - ref_params = *pipeline_params; + + ref_params = kmemdup(pipeline_params, sizeof(*ref_params), GFP_KERNEL); + if (!ref_params) + return -ENOMEM; break; } @@ -1959,7 +1968,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, /* set input and output audio formats */ input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, - &ref_params, available_fmt); + ref_params, available_fmt); if (input_fmt_index < 0) return input_fmt_index; From de74ec718e0788e1998eb7289ad07970e27cae27 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 28 Feb 2025 00:29:30 +0000 Subject: [PATCH 465/651] ASoC: simple-card-utils: Don't use __free(device_node) at graph_util_parse_dai() commit 419d1918105e ("ASoC: simple-card-utils: use __free(device_node) for device node") uses __free(device_node) for dlc->of_node, but we need to keep it while driver is in use. Don't use __free(device_node) in graph_util_parse_dai(). Fixes: 419d1918105e ("ASoC: simple-card-utils: use __free(device_node) for device node") Reported-by: Thuan Nguyen Reported-by: Detlev Casanova Signed-off-by: Kuninori Morimoto Tested-by: Thuan Nguyen Tested-by: Detlev Casanova Link: https://patch.msgid.link/87eczisyhh.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/simple-card-utils.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index c2445c5ccd84..32efb30c55d6 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -1077,6 +1077,7 @@ static int graph_get_dai_id(struct device_node *ep) int graph_util_parse_dai(struct device *dev, struct device_node *ep, struct snd_soc_dai_link_component *dlc, int *is_single_link) { + struct device_node *node; struct of_phandle_args args = {}; struct snd_soc_dai *dai; int ret; @@ -1084,7 +1085,7 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep, if (!ep) return 0; - struct device_node *node __free(device_node) = of_graph_get_port_parent(ep); + node = of_graph_get_port_parent(ep); /* * Try to find from DAI node @@ -1126,8 +1127,10 @@ int graph_util_parse_dai(struct device *dev, struct device_node *ep, * if he unbinded CPU or Codec. */ ret = snd_soc_get_dlc(&args, dlc); - if (ret < 0) + if (ret < 0) { + of_node_put(node); return ret; + } parse_dai_end: if (is_single_link) From 25a83f870b8a25a4b10bf5ba474a017ed5a72e7d Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Thu, 27 Feb 2025 22:07:28 +1000 Subject: [PATCH 466/651] ASoC: dt-bindings: tas27xx: add compatible for SN012776 The TI SN012776 is a variant of TAS2764 found in Apple Silicon Macs. It continues Apple's long-standing policy of getting vendors to spin out subtly incompatible and Apple-exclusive variants of their publicly available parts. Reviewed-by: Neal Gompa Acked-by: Rob Herring (Arm) Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-1-cbb130030acf@gmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/ti,tas27xx.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/ti,tas27xx.yaml b/Documentation/devicetree/bindings/sound/ti,tas27xx.yaml index 5447482179c1..fcaae848e78a 100644 --- a/Documentation/devicetree/bindings/sound/ti,tas27xx.yaml +++ b/Documentation/devicetree/bindings/sound/ti,tas27xx.yaml @@ -24,6 +24,7 @@ properties: enum: - ti,tas2764 - ti,tas2780 + - ti,sn012776 # Apple variant of TAS2764 reg: maxItems: 1 From ce9233937f3233e277ff23395e61ea690c769bef Mon Sep 17 00:00:00 2001 From: James Calligeros Date: Thu, 27 Feb 2025 22:07:29 +1000 Subject: [PATCH 467/651] ASoC: dt-bindings: tas2770: add compatible for TAS5770L A variant of TAS2770 known as TAS5770L is found in Apple Silicon Macs. Reviewed-by: Neal Gompa Acked-by: Rob Herring (Arm) Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-2-cbb130030acf@gmail.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/ti,tas2770.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/ti,tas2770.yaml b/Documentation/devicetree/bindings/sound/ti,tas2770.yaml index 5e7aea43aced..8eab98a0f7a2 100644 --- a/Documentation/devicetree/bindings/sound/ti,tas2770.yaml +++ b/Documentation/devicetree/bindings/sound/ti,tas2770.yaml @@ -23,6 +23,7 @@ properties: compatible: enum: - ti,tas2770 + - ti,tas5770l # Apple variant reg: maxItems: 1 From ad18392962df46a858432839cc6bcaf2ede7cc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 27 Feb 2025 22:07:30 +1000 Subject: [PATCH 468/651] ASoC: tas2764: Extend driver to SN012776 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SN012776 is a speaker amp chip found in Apple's 2021 laptops. It appears similar and more-or-less compatible to TAS2764. Extend the TAS2764 driver with some SN012776 specifics and configure the chip assuming it's in one of the Apple machines. Reviewed-by: Neal Gompa Signed-off-by: Martin PoviÅ¡er Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-3-cbb130030acf@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2764.c | 43 +++++++++++++++++++++++++++++++++++--- sound/soc/codecs/tas2764.h | 3 +++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index c0a1d0c2a938..d9b4f898789f 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,11 @@ #include "tas2764.h" +enum tas2764_devid { + DEVID_TAS2764 = 0, + DEVID_SN012776 = 1 +}; + struct tas2764_priv { struct snd_soc_component *component; struct gpio_desc *reset_gpio; @@ -30,7 +36,8 @@ struct tas2764_priv { struct regmap *regmap; struct device *dev; int irq; - + enum tas2764_devid devid; + int v_sense_slot; int i_sense_slot; @@ -533,10 +540,16 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = { }, }; +static uint8_t sn012776_bop_presets[] = { + 0x01, 0x32, 0x02, 0x22, 0x83, 0x2d, 0x80, 0x02, 0x06, + 0x32, 0x46, 0x30, 0x02, 0x06, 0x38, 0x40, 0x30, 0x02, + 0x06, 0x3e, 0x37, 0x30, 0xff, 0xe6 +}; + static int tas2764_codec_probe(struct snd_soc_component *component) { struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); - int ret; + int ret, i; tas2764->component = component; @@ -585,6 +598,27 @@ static int tas2764_codec_probe(struct snd_soc_component *component) if (ret < 0) return ret; + switch (tas2764->devid) { + case DEVID_SN012776: + ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL, + TAS2764_PWR_CTRL_BOP_SRC, + TAS2764_PWR_CTRL_BOP_SRC); + if (ret < 0) + return ret; + + for (i = 0; i < ARRAY_SIZE(sn012776_bop_presets); i++) { + ret = snd_soc_component_write(component, + TAS2764_BOP_CFG0 + i, + sn012776_bop_presets[i]); + + if (ret < 0) + return ret; + } + break; + default: + break; + } + return 0; } @@ -716,6 +750,8 @@ static int tas2764_i2c_probe(struct i2c_client *client) if (!tas2764) return -ENOMEM; + tas2764->devid = (enum tas2764_devid)of_device_get_match_data(&client->dev); + tas2764->dev = &client->dev; tas2764->irq = client->irq; i2c_set_clientdata(client, tas2764); @@ -752,7 +788,8 @@ MODULE_DEVICE_TABLE(i2c, tas2764_i2c_id); #if defined(CONFIG_OF) static const struct of_device_id tas2764_of_match[] = { - { .compatible = "ti,tas2764" }, + { .compatible = "ti,tas2764", .data = (void *)DEVID_TAS2764 }, + { .compatible = "ti,sn012776", .data = (void *)DEVID_SN012776 }, {}, }; MODULE_DEVICE_TABLE(of, tas2764_of_match); diff --git a/sound/soc/codecs/tas2764.h b/sound/soc/codecs/tas2764.h index 9490f2686e38..69c0f91cb423 100644 --- a/sound/soc/codecs/tas2764.h +++ b/sound/soc/codecs/tas2764.h @@ -29,6 +29,7 @@ #define TAS2764_PWR_CTRL_ACTIVE 0x0 #define TAS2764_PWR_CTRL_MUTE BIT(0) #define TAS2764_PWR_CTRL_SHUTDOWN BIT(1) +#define TAS2764_PWR_CTRL_BOP_SRC BIT(7) #define TAS2764_VSENSE_POWER_EN 3 #define TAS2764_ISENSE_POWER_EN 4 @@ -116,4 +117,6 @@ #define TAS2764_INT_CLK_CFG TAS2764_REG(0x0, 0x5c) #define TAS2764_INT_CLK_CFG_IRQZ_CLR BIT(2) +#define TAS2764_BOP_CFG0 TAS2764_REG(0X0, 0x1d) + #endif /* __TAS2764__ */ From f8d5f28e3f2ece5a1392205022afe30c87107a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 27 Feb 2025 22:07:31 +1000 Subject: [PATCH 469/651] ASoC: tas2764: Add control concerning overcurrent events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add control to expose the option of autoretry behavior on overcurrent events in the codec. Reviewed-by: Neal Gompa Signed-off-by: Martin PoviÅ¡er Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-4-cbb130030acf@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2764.c | 9 +++++++++ sound/soc/codecs/tas2764.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index d9b4f898789f..08aa7ee34256 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -634,12 +634,21 @@ static SOC_ENUM_SINGLE_DECL( tas2764_hpf_enum, TAS2764_DC_BLK0, TAS2764_DC_BLK0_HPF_FREQ_PB_SHIFT, tas2764_hpf_texts); +static const char * const tas2764_oce_texts[] = { + "Disable", "Retry", +}; + +static SOC_ENUM_SINGLE_DECL( + tas2764_oce_enum, TAS2764_MISC_CFG1, + TAS2764_MISC_CFG1_OCE_RETRY_SHIFT, tas2764_oce_texts); + static const struct snd_kcontrol_new tas2764_snd_controls[] = { SOC_SINGLE_TLV("Speaker Volume", TAS2764_DVC, 0, TAS2764_DVC_MAX, 1, tas2764_playback_volume), SOC_SINGLE_TLV("Amp Gain Volume", TAS2764_CHNL_0, 1, 0x14, 0, tas2764_digital_tlv), SOC_ENUM("HPF Corner Frequency", tas2764_hpf_enum), + SOC_ENUM("OCE Handling", tas2764_oce_enum), }; static const struct snd_soc_component_driver soc_component_driver_tas2764 = { diff --git a/sound/soc/codecs/tas2764.h b/sound/soc/codecs/tas2764.h index 69c0f91cb423..3251dc0106e0 100644 --- a/sound/soc/codecs/tas2764.h +++ b/sound/soc/codecs/tas2764.h @@ -44,6 +44,10 @@ #define TAS2764_CHNL_0 TAS2764_REG(0X0, 0x03) +/* Miscellaneous */ +#define TAS2764_MISC_CFG1 TAS2764_REG(0x0, 0x06) +#define TAS2764_MISC_CFG1_OCE_RETRY_SHIFT 5 + /* TDM Configuration Reg0 */ #define TAS2764_TDM_CFG0 TAS2764_REG(0X0, 0x08) #define TAS2764_TDM_CFG0_SMP_MASK BIT(5) From 6553ee024b4452ef861de10605156c9d79e208ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 27 Feb 2025 22:07:32 +1000 Subject: [PATCH 470/651] ASoC: tas2770: Factor out set_ivsense_slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new explicit function for the setting of I/V sense TDM slots. Reviewed-by: Neal Gompa Signed-off-by: Martin PoviÅ¡er Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-5-cbb130030acf@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2770.c | 40 +++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index 863c3f672ba9..4a86fcec0c1e 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -189,6 +189,31 @@ static int tas2770_mute(struct snd_soc_dai *dai, int mute, int direction) return tas2770_update_pwr_ctrl(tas2770); } +static int tas2770_set_ivsense_transmit(struct tas2770_priv *tas2770, + int i_slot, int v_slot) +{ + struct snd_soc_component *component = tas2770->component; + int ret; + + ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG5, + TAS2770_TDM_CFG_REG5_VSNS_MASK | + TAS2770_TDM_CFG_REG5_50_MASK, + TAS2770_TDM_CFG_REG5_VSNS_ENABLE | + v_slot); + if (ret < 0) + return ret; + + ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG6, + TAS2770_TDM_CFG_REG6_ISNS_MASK | + TAS2770_TDM_CFG_REG6_50_MASK, + TAS2770_TDM_CFG_REG6_ISNS_ENABLE | + i_slot); + if (ret < 0) + return ret; + + return 0; +} + static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth) { int ret; @@ -221,19 +246,8 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth) if (ret < 0) return ret; - ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG5, - TAS2770_TDM_CFG_REG5_VSNS_MASK | - TAS2770_TDM_CFG_REG5_50_MASK, - TAS2770_TDM_CFG_REG5_VSNS_ENABLE | - tas2770->v_sense_slot); - if (ret < 0) - return ret; - - ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG6, - TAS2770_TDM_CFG_REG6_ISNS_MASK | - TAS2770_TDM_CFG_REG6_50_MASK, - TAS2770_TDM_CFG_REG6_ISNS_ENABLE | - tas2770->i_sense_slot); + ret = tas2770_set_ivsense_transmit(tas2770, tas2770->i_sense_slot, + tas2770->v_sense_slot); if (ret < 0) return ret; From f0066c8d1d3298e9f9d136a365139bac733e84c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 27 Feb 2025 22:07:33 +1000 Subject: [PATCH 471/651] ASoC: tas2770: Fix and redo I/V sense TDM slot setting logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The former code sets the V slot from inside set_bitwidth according to the bitwidth of the PCM format. That's wrong, since: * It overrides the V slot parsed from DT binding. * The V slot is set shifted behind the I slot by the length of the PCM bitwidth, but the PCM bitwidth has no assured relation to the TDM slot width. Replace the former logic by setting up the I/V sense transmission only in case of both I/V slots being specified in devicetree, and never override those values. In case the slots are left unspecified, disable the transmission completely. There's an improbable case someone is relying on the old behavior, but if so, that's a setup that only works by accident, and cannot be sanely supported going forward. There's no indication anyone is consuming the I/V sense data up to today, so break the former behavior. Reviewed-by: Neal Gompa Signed-off-by: Martin PoviÅ¡er Signed-off-by: James Calligeros Link: https://patch.msgid.link/20250227-apple-codec-changes-v3-6-cbb130030acf@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2770.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index 4a86fcec0c1e..7f219df8be70 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -224,19 +224,16 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth) ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2, TAS2770_TDM_CFG_REG2_RXW_MASK, TAS2770_TDM_CFG_REG2_RXW_16BITS); - tas2770->v_sense_slot = tas2770->i_sense_slot + 2; break; case SNDRV_PCM_FORMAT_S24_LE: ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2, TAS2770_TDM_CFG_REG2_RXW_MASK, TAS2770_TDM_CFG_REG2_RXW_24BITS); - tas2770->v_sense_slot = tas2770->i_sense_slot + 4; break; case SNDRV_PCM_FORMAT_S32_LE: ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2, TAS2770_TDM_CFG_REG2_RXW_MASK, TAS2770_TDM_CFG_REG2_RXW_32BITS); - tas2770->v_sense_slot = tas2770->i_sense_slot + 4; break; default: @@ -246,11 +243,6 @@ static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth) if (ret < 0) return ret; - ret = tas2770_set_ivsense_transmit(tas2770, tas2770->i_sense_slot, - tas2770->v_sense_slot); - if (ret < 0) - return ret; - return 0; } @@ -505,6 +497,7 @@ static int tas2770_codec_probe(struct snd_soc_component *component) { struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component); + int ret; tas2770->component = component; @@ -516,6 +509,14 @@ static int tas2770_codec_probe(struct snd_soc_component *component) tas2770_reset(tas2770); regmap_reinit_cache(tas2770->regmap, &tas2770_i2c_regmap); + if (tas2770->i_sense_slot != -1 && tas2770->v_sense_slot != -1) { + ret = tas2770_set_ivsense_transmit(tas2770, tas2770->i_sense_slot, + tas2770->v_sense_slot); + + if (ret < 0) + return ret; + } + return 0; } @@ -643,7 +644,7 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770) dev_info(tas2770->dev, "Property %s is missing setting default slot\n", "ti,imon-slot-no"); - tas2770->i_sense_slot = 0; + tas2770->i_sense_slot = -1; } rc = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", @@ -652,7 +653,7 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770) dev_info(tas2770->dev, "Property %s is missing setting default slot\n", "ti,vmon-slot-no"); - tas2770->v_sense_slot = 2; + tas2770->v_sense_slot = -1; } tas2770->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH); From 7bda89a2489fb012c4c63f3338827ad1f35c8880 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Sat, 15 Feb 2025 11:02:23 +1300 Subject: [PATCH 472/651] ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios Devices integrating Allwinner SoCs may use line-out or headphone jacks with jack detection circuits attached to a GPIO. Support defining these in DTs. A number of Anbernic devices featuring the H700 SoC use this mechanism to switch between a headphone jack and an internal speaker, so add these to the allowed routing items. Signed-off-by: Chris Morgan Signed-off-by: Ryan Walklin Reviewed-by: Rob Herring (Arm) -- Changelog v1..v2: - Remove vendor prefix from hp-det-gpios Changelog v2..v3: - Add Reviewed-by tag Reviewed-by: Rob Herring (Arm) Tested-by: Philippe Simons Link: https://patch.msgid.link/20250214220247.10810-2-ryan@testtoast.com Signed-off-by: Mark Brown --- .../bindings/sound/allwinner,sun4i-a10-codec.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml index ccae64ce3071..b4eca702febc 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml @@ -102,6 +102,10 @@ properties: maxItems: 1 description: GPIO to enable the external amplifier + hp-det-gpios: + maxItems: 1 + description: GPIO for headphone/line-out detection + required: - "#sound-dai-cells" - compatible @@ -251,8 +255,10 @@ allOf: allwinner,audio-routing: items: enum: + - Headphone - LINEOUT - Line Out + - Speaker dmas: items: From ae5f76d4044d1580849316c49290678605e0889d Mon Sep 17 00:00:00 2001 From: Ryan Walklin Date: Sat, 15 Feb 2025 11:02:24 +1300 Subject: [PATCH 473/651] ASoC: sun4i-codec: correct dapm widgets and controls for h616 The previous H616 support patch added a single LINEOUT DAPM pin switch to the card controls. As the codec in this SoC only has a single route, this seemed reasonable at the time, however is redundant given the existing DAPM codec widget definitions controlling the digital and analog sides of the codec. It is also insufficient to describe the scenario where separate components (muxes, jack detection etc) are used to modify the audio route external to the SoC. For example the Anbernic RG(##)XX series of devices uses a headphone jack detection switch, GPIO-controlled speaker amplifier and a passive external mux chip to route audio. Remove the redundant LINEOUT card control, and add a Speaker pin switch control and Headphone DAPM widget to allow control of the above hardware. Signed-off-by: Chris Morgan Signed-off-by: Ryan Walklin Tested-by: Philippe Simons Link: https://patch.msgid.link/20250214220247.10810-3-ryan@testtoast.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 886b3fa537d2..f24bbefeb392 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -1916,10 +1916,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = { }; static const struct snd_kcontrol_new sun50i_h616_card_controls[] = { - SOC_DAPM_PIN_SWITCH("LINEOUT"), + SOC_DAPM_PIN_SWITCH("Speaker"), }; static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_LINE("Line Out", NULL), SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event), }; From a149377c033afe6557c50892ebbfc0e8b7e2e253 Mon Sep 17 00:00:00 2001 From: Ryan Walklin Date: Sat, 15 Feb 2025 11:02:25 +1300 Subject: [PATCH 474/651] ASoC: sun4i-codec: support hp-det-gpios property Add support for GPIO headphone detection with the hp-det-gpios property. In order for this to properly disable the path upon removal of headphones, the output must be labelled Headphone which is a common sink in the driver. Describe a headphone jack and detection GPIO in the driver, check for a corresponding device tree node, and enable jack detection in a new machine init function if described. Signed-off-by: Chris Morgan Signed-off-by: Ryan Walklin -- Changelog v1..v2: - Separate DAPM changes into separate patch and add rationale. Tested-by: Philippe Simons Link: https://patch.msgid.link/20250214220247.10810-4-ryan@testtoast.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index f24bbefeb392..3701f56c7275 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -331,6 +332,7 @@ struct sun4i_codec { struct clk *clk_module; struct reset_control *rst; struct gpio_desc *gpio_pa; + struct gpio_desc *gpio_hp; /* ADC_FIFOC register is at different offset on different SoCs */ struct regmap_field *reg_adc_fifoc; @@ -1583,6 +1585,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = { .ops = &dummy_dai_ops, }; +static struct snd_soc_jack sun4i_headphone_jack; + +static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = { + { .pin = "Headphone", .mask = SND_JACK_HEADPHONE }, +}; + +static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = { + .name = "hp-det", + .report = SND_JACK_HEADPHONE, + .debounce_time = 150, +}; + +static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); + int ret; + + if (scodec->gpio_hp) { + ret = snd_soc_card_jack_new_pins(card, "Headphone Jack", + SND_JACK_HEADPHONE, + &sun4i_headphone_jack, + sun4i_headphone_jack_pins, + ARRAY_SIZE(sun4i_headphone_jack_pins)); + if (ret) { + dev_err(rtd->dev, + "Headphone jack creation failed: %d\n", ret); + return ret; + } + + sun4i_headphone_jack_gpio.desc = scodec->gpio_hp; + ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1, + &sun4i_headphone_jack_gpio); + + if (ret) { + dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret); + return ret; + } + } + + return 0; +} + static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, int *num_links) { @@ -1608,6 +1653,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, link->codecs->name = dev_name(dev); link->platforms->name = dev_name(dev); link->dai_fmt = SND_SOC_DAIFMT_I2S; + link->init = sun4i_codec_machine_init; *num_links = 1; @@ -2302,6 +2348,13 @@ static int sun4i_codec_probe(struct platform_device *pdev) return ret; } + scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN); + if (IS_ERR(scodec->gpio_hp)) { + ret = PTR_ERR(scodec->gpio_hp); + dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n"); + return ret; + } + /* reg_field setup */ scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev, scodec->regmap, From d389719fb4ece17ea28c0cf908066815d3ab0e25 Mon Sep 17 00:00:00 2001 From: Ryan Walklin Date: Sat, 15 Feb 2025 11:02:27 +1300 Subject: [PATCH 475/651] ASoC: sun4i-codec: add h616 card long_name Adding jack detection requires sound servers to act on the emitted events, which are described by ALSA Use Case Manager configurations in userspace. These configurations include the long card name in the file path (falling back to card->name if this is not present), so add a long card name for the H616 without spaces, making UCM referencing easier. The corresponding ALSA UCM patch is here (now merged): https://github.com/alsa-project/alsa-ucm-conf/pull/491 Signed-off-by: Ryan Walklin -- Changelog v1..v2: - Separate patch for card->long_name - Note UCM patch link Changelog v2..v3: - Add card->long_name rather than change existing card->name Link: https://patch.msgid.link/20250214220247.10810-6-ryan@testtoast.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 3701f56c7275..93733ff2e32a 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -2013,6 +2013,7 @@ static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev) card->dev = dev; card->owner = THIS_MODULE; card->name = "H616 Audio Codec"; + card->long_name = "h616-audio-codec"; card->driver_name = "sun4i-codec"; card->controls = sun50i_h616_card_controls; card->num_controls = ARRAY_SIZE(sun50i_h616_card_controls); From 3954382bb5b28e09e20c7ff24a4f5ec003399204 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:19 +0100 Subject: [PATCH 476/651] ALSA: ac97: Convert to RUNTIME_PM_OPS() macro Use a newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which makes CONFIG_PM ifdefs superfluous. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-2-tiwai@suse.de --- sound/ac97/bus.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c index 8dfffdc101a2..47c6787158a7 100644 --- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -387,7 +387,6 @@ void snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl) } EXPORT_SYMBOL_GPL(snd_ac97_controller_unregister); -#ifdef CONFIG_PM static int ac97_pm_runtime_suspend(struct device *dev) { struct ac97_codec_device *codec = to_ac97_device(dev); @@ -419,7 +418,6 @@ static int ac97_pm_runtime_resume(struct device *dev) return pm_generic_runtime_resume(dev); } -#endif /* CONFIG_PM */ static const struct dev_pm_ops ac97_pm = { .suspend = pm_generic_suspend, @@ -428,10 +426,7 @@ static const struct dev_pm_ops ac97_pm = { .thaw = pm_generic_thaw, .poweroff = pm_generic_poweroff, .restore = pm_generic_restore, - SET_RUNTIME_PM_OPS( - ac97_pm_runtime_suspend, - ac97_pm_runtime_resume, - NULL) + RUNTIME_PM_OPS(ac97_pm_runtime_suspend, ac97_pm_runtime_resume, NULL) }; static int ac97_get_enable_clk(struct ac97_codec_device *adev) @@ -535,7 +530,7 @@ const struct bus_type ac97_bus_type = { .name = "ac97bus", .dev_groups = ac97_dev_groups, .match = ac97_bus_match, - .pm = &ac97_pm, + .pm = pm_ptr(&ac97_pm), .probe = ac97_bus_probe, .remove = ac97_bus_remove, }; From 4c60cf85e2915763b7116e0233e25cab510eb93e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:20 +0100 Subject: [PATCH 477/651] ALSA: atmel: Convert to DEFINE_SIMPLE_DEV_PM_OPS() macro Use the newer DEFINE_SIMPLE_DEV_PM_OPS() macro instead of SIMPLE_DEV_PM_OPS() together with pm_ptr(), which makes CONFIG_PM_SLEEP ifdefs superfluous. Merely a cleanup, there should be no actual code change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-3-tiwai@suse.de --- sound/atmel/ac97c.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index d8f8e08f1bb7..84e264f335ca 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -817,7 +817,6 @@ err_prepare_enable: return retval; } -#ifdef CONFIG_PM_SLEEP static int atmel_ac97c_suspend(struct device *pdev) { struct snd_card *card = dev_get_drvdata(pdev); @@ -836,11 +835,7 @@ static int atmel_ac97c_resume(struct device *pdev) return ret; } -static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume); -#define ATMEL_AC97C_PM_OPS &atmel_ac97c_pm -#else -#define ATMEL_AC97C_PM_OPS NULL -#endif +static DEFINE_SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume); static void atmel_ac97c_remove(struct platform_device *pdev) { @@ -864,7 +859,7 @@ static struct platform_driver atmel_ac97c_driver = { .remove = atmel_ac97c_remove, .driver = { .name = "atmel_ac97c", - .pm = ATMEL_AC97C_PM_OPS, + .pm = pm_ptr(&atmel_ac97c_pm), .of_match_table = atmel_ac97c_dt_ids, }, }; From 0d8dfeba4b8076e7b056411d743c797e4cdc11e3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:21 +0100 Subject: [PATCH 478/651] ALSA: pcm: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS(), which makes CONFIG_PM_SLEEP ifdefs superfluous. Merely a cleanup, there should be no actual code change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-4-tiwai@suse.de --- sound/core/pcm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 290690fc2abc..283aac441fa0 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -592,7 +592,6 @@ static const struct attribute_group *pcm_dev_attr_groups[]; * PM callbacks: we need to deal only with suspend here, as the resume is * triggered either from user-space or the driver's resume callback */ -#ifdef CONFIG_PM_SLEEP static int do_pcm_suspend(struct device *dev) { struct snd_pcm_str *pstr = dev_get_drvdata(dev); @@ -601,10 +600,9 @@ static int do_pcm_suspend(struct device *dev) snd_pcm_suspend_all(pstr->pcm); return 0; } -#endif static const struct dev_pm_ops pcm_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(do_pcm_suspend, NULL) + SYSTEM_SLEEP_PM_OPS(do_pcm_suspend, NULL) }; /* device type for PCM -- basically only for passing PM callbacks */ From 3f38aa32c51eb9c3b124004e11ee48fbca3c55e7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:22 +0100 Subject: [PATCH 479/651] ALSA: hda: Use RUNTIME_PM_OPS() and pm_ptr() Clean up the code with the helper macros, and also assure that no PM ops is assigned without CONFIG_PM via pm_ptr(). Merely a cleanup, there should be no actual code change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-5-tiwai@suse.de --- sound/pci/hda/hda_bind.c | 2 +- sound/pci/hda/hda_codec.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index b7ca2a83fbb0..9521e5e0e6e6 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -185,7 +185,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, drv->core.driver.probe = hda_codec_driver_probe; drv->core.driver.remove = hda_codec_driver_remove; drv->core.driver.shutdown = hda_codec_driver_shutdown; - drv->core.driver.pm = &hda_codec_driver_pm; + drv->core.driver.pm = pm_ptr(&hda_codec_driver_pm); drv->core.type = HDA_DEV_LEGACY; drv->core.match = hda_codec_match; drv->core.unsol_event = hda_codec_unsol_event; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 14763c0f31ad..b9bce583476e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3037,8 +3037,7 @@ const struct dev_pm_ops hda_codec_driver_pm = { .thaw = pm_sleep_ptr(hda_codec_pm_thaw), .poweroff = pm_sleep_ptr(hda_codec_pm_suspend), .restore = pm_sleep_ptr(hda_codec_pm_restore), - .runtime_suspend = pm_ptr(hda_codec_runtime_suspend), - .runtime_resume = pm_ptr(hda_codec_runtime_resume), + RUNTIME_PM_OPS(hda_codec_runtime_suspend, hda_codec_runtime_resume, NULL) }; /* suspend the codec at shutdown; called from driver's shutdown callback */ From dd69342a043ef7080093b92a015ce7a22c810aad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:23 +0100 Subject: [PATCH 480/651] ALSA: hda-intel: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-6-tiwai@suse.de --- sound/pci/hda/hda_intel.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 3f11f169fe4a..62ee32f70adc 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1051,7 +1051,7 @@ static int azx_suspend(struct device *dev) return 0; } -static int __maybe_unused azx_resume(struct device *dev) +static int azx_resume(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; @@ -1098,7 +1098,7 @@ static int azx_thaw_noirq(struct device *dev) return 0; } -static int __maybe_unused azx_runtime_suspend(struct device *dev) +static int azx_runtime_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; @@ -1115,7 +1115,7 @@ static int __maybe_unused azx_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused azx_runtime_resume(struct device *dev) +static int azx_runtime_resume(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; @@ -1132,7 +1132,7 @@ static int __maybe_unused azx_runtime_resume(struct device *dev) return 0; } -static int __maybe_unused azx_runtime_idle(struct device *dev) +static int azx_runtime_idle(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; @@ -1163,7 +1163,7 @@ static const struct dev_pm_ops azx_pm = { .complete = pm_sleep_ptr(azx_complete), .freeze_noirq = pm_sleep_ptr(azx_freeze_noirq), .thaw_noirq = pm_sleep_ptr(azx_thaw_noirq), - SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle) + RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle) }; @@ -2795,7 +2795,7 @@ static struct pci_driver azx_driver = { .remove = azx_remove, .shutdown = azx_shutdown, .driver = { - .pm = &azx_pm, + .pm = pm_ptr(&azx_pm), }, }; From f923335da9e813dbebcb80e6b6f397f7746dd683 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:24 +0100 Subject: [PATCH 481/651] ALSA: hda/tegra: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-7-tiwai@suse.de --- sound/pci/hda/hda_tegra.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index b1e30a83dfb0..a590d431c5ff 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -125,7 +125,7 @@ static void hda_tegra_init(struct hda_tegra *hda) /* * power management */ -static int __maybe_unused hda_tegra_suspend(struct device *dev) +static int hda_tegra_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); int rc; @@ -138,7 +138,7 @@ static int __maybe_unused hda_tegra_suspend(struct device *dev) return 0; } -static int __maybe_unused hda_tegra_resume(struct device *dev) +static int hda_tegra_resume(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); int rc; @@ -151,7 +151,7 @@ static int __maybe_unused hda_tegra_resume(struct device *dev) return 0; } -static int __maybe_unused hda_tegra_runtime_suspend(struct device *dev) +static int hda_tegra_runtime_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; @@ -170,7 +170,7 @@ static int __maybe_unused hda_tegra_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused hda_tegra_runtime_resume(struct device *dev) +static int hda_tegra_runtime_resume(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; @@ -204,10 +204,8 @@ static int __maybe_unused hda_tegra_runtime_resume(struct device *dev) } static const struct dev_pm_ops hda_tegra_pm = { - SET_SYSTEM_SLEEP_PM_OPS(hda_tegra_suspend, hda_tegra_resume) - SET_RUNTIME_PM_OPS(hda_tegra_runtime_suspend, - hda_tegra_runtime_resume, - NULL) + SYSTEM_SLEEP_PM_OPS(hda_tegra_suspend, hda_tegra_resume) + RUNTIME_PM_OPS(hda_tegra_runtime_suspend, hda_tegra_runtime_resume, NULL) }; static int hda_tegra_dev_disconnect(struct snd_device *device) @@ -602,7 +600,7 @@ static void hda_tegra_shutdown(struct platform_device *pdev) static struct platform_driver tegra_platform_hda = { .driver = { .name = "tegra-hda", - .pm = &hda_tegra_pm, + .pm = pm_ptr(&hda_tegra_pm), .of_match_table = hda_tegra_match, }, .probe = hda_tegra_probe, From 5ea0a2206b58356779cc686630b6548a3402991c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:25 +0100 Subject: [PATCH 482/651] ALSA: oxygen: Convert to EXPORT_SIMPLE_DEV_PM_OPS() Use the newer EXPORT_SIMPLE_DEV_PM_OPS() macro instead of SIPLE_DEV_PM_OPS() and manual export, together with pm_ptr() macro, which makes CONFIG_PM_SLEEP ifdefs superfluous. Merely a cleanup, there should be no actual code change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-8-tiwai@suse.de --- sound/pci/oxygen/oxygen.c | 4 +--- sound/pci/oxygen/oxygen.h | 2 -- sound/pci/oxygen/oxygen_lib.c | 5 +---- sound/pci/oxygen/se6x.c | 4 +--- sound/pci/oxygen/virtuoso.c | 4 +--- 5 files changed, 4 insertions(+), 15 deletions(-) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index c346f42befc2..6d0deea47ee6 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -854,11 +854,9 @@ static struct pci_driver oxygen_driver = { .name = KBUILD_MODNAME, .id_table = oxygen_ids, .probe = generic_oxygen_probe, -#ifdef CONFIG_PM_SLEEP .driver = { - .pm = &oxygen_pci_pm, + .pm = pm_ptr(&oxygen_pci_pm), }, -#endif }; module_pci_driver(oxygen_driver); diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 0cae640708f3..820026daf838 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -161,9 +161,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, const struct pci_device_id *id ) ); -#ifdef CONFIG_PM_SLEEP extern const struct dev_pm_ops oxygen_pci_pm; -#endif void oxygen_pci_shutdown(struct pci_dev *pci); /* oxygen_mixer.c */ diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 92ffe9dc20c5..9340d3c9ffd6 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -713,7 +713,6 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, } EXPORT_SYMBOL(oxygen_pci_probe); -#ifdef CONFIG_PM_SLEEP static int oxygen_pci_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); @@ -789,9 +788,7 @@ static int oxygen_pci_resume(struct device *dev) return 0; } -SIMPLE_DEV_PM_OPS(oxygen_pci_pm, oxygen_pci_suspend, oxygen_pci_resume); -EXPORT_SYMBOL(oxygen_pci_pm); -#endif /* CONFIG_PM_SLEEP */ +EXPORT_SIMPLE_DEV_PM_OPS(oxygen_pci_pm, oxygen_pci_suspend, oxygen_pci_resume); void oxygen_pci_shutdown(struct pci_dev *pci) { diff --git a/sound/pci/oxygen/se6x.c b/sound/pci/oxygen/se6x.c index 17650a5b1bfa..c1bb9dd1cd54 100644 --- a/sound/pci/oxygen/se6x.c +++ b/sound/pci/oxygen/se6x.c @@ -137,11 +137,9 @@ static struct pci_driver se6x_driver = { .name = KBUILD_MODNAME, .id_table = se6x_ids, .probe = se6x_probe, -#ifdef CONFIG_PM_SLEEP .driver = { - .pm = &oxygen_pci_pm, + .pm = pm_ptr(&oxygen_pci_pm), }, -#endif .shutdown = oxygen_pci_shutdown, }; diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 2e405133371f..0bfe6d8dde3e 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -82,11 +82,9 @@ static struct pci_driver xonar_driver = { .name = KBUILD_MODNAME, .id_table = xonar_ids, .probe = xonar_probe, -#ifdef CONFIG_PM_SLEEP .driver = { - .pm = &oxygen_pci_pm, + .pm = pm_ptr(&oxygen_pci_pm), }, -#endif .shutdown = oxygen_pci_shutdown, }; From f3f9dfde4c88b5db21b350dd61cc913ec16c5f6c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:26 +0100 Subject: [PATCH 483/651] ALSA: vx222: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Use the newer DEFINE_SIMPLE_DEV_PM_OPS() macro instead of SIMPLE_DEV_PM_OPS() together with pm_ptr(), which makes CONFIG_PM_SLEEP ifdefs superfluous. Merely a cleanup, there should be no actual code change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-9-tiwai@suse.de --- sound/pci/vx222/vx222.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index 468a6a20dc1e..fdb039896205 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c @@ -204,7 +204,6 @@ static int snd_vx222_probe(struct pci_dev *pci, return 0; } -#ifdef CONFIG_PM_SLEEP static int snd_vx222_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); @@ -221,18 +220,14 @@ static int snd_vx222_resume(struct device *dev) return snd_vx_resume(&vx->core); } -static SIMPLE_DEV_PM_OPS(snd_vx222_pm, snd_vx222_suspend, snd_vx222_resume); -#define SND_VX222_PM_OPS &snd_vx222_pm -#else -#define SND_VX222_PM_OPS NULL -#endif +static DEFINE_SIMPLE_DEV_PM_OPS(snd_vx222_pm, snd_vx222_suspend, snd_vx222_resume); static struct pci_driver vx222_driver = { .name = KBUILD_MODNAME, .id_table = snd_vx222_ids, .probe = snd_vx222_probe, .driver = { - .pm = SND_VX222_PM_OPS, + .pm = pm_ptr(&snd_vx222_pm), }, }; From 9335a36faacffb91f4e2b6e98454e58c9fed99fd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Mar 2025 18:07:27 +0100 Subject: [PATCH 484/651] ALSA: intel-hdmi-audio: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313170731.26943-10-tiwai@suse.de --- sound/x86/intel_hdmi_audio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index d41ea09ffbe5..7fcc528a0204 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1617,7 +1617,7 @@ static int had_create_jack(struct snd_intelhad *ctx, * PM callbacks */ -static int __maybe_unused hdmi_lpe_audio_suspend(struct device *dev) +static int hdmi_lpe_audio_suspend(struct device *dev) { struct snd_intelhad_card *card_ctx = dev_get_drvdata(dev); @@ -1626,7 +1626,7 @@ static int __maybe_unused hdmi_lpe_audio_suspend(struct device *dev) return 0; } -static int __maybe_unused hdmi_lpe_audio_resume(struct device *dev) +static int hdmi_lpe_audio_resume(struct device *dev) { struct snd_intelhad_card *card_ctx = dev_get_drvdata(dev); @@ -1833,13 +1833,13 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) } static const struct dev_pm_ops hdmi_lpe_audio_pm = { - SET_SYSTEM_SLEEP_PM_OPS(hdmi_lpe_audio_suspend, hdmi_lpe_audio_resume) + SYSTEM_SLEEP_PM_OPS(hdmi_lpe_audio_suspend, hdmi_lpe_audio_resume) }; static struct platform_driver hdmi_lpe_audio_driver = { .driver = { .name = "hdmi-lpe-audio", - .pm = &hdmi_lpe_audio_pm, + .pm = pm_ptr(&hdmi_lpe_audio_pm), }, .probe = hdmi_lpe_audio_probe, }; From c2820405ba55a38932aa2177f026b70064296663 Mon Sep 17 00:00:00 2001 From: Ricard Wanderlof Date: Thu, 13 Mar 2025 23:16:17 +0100 Subject: [PATCH 485/651] ALSA: usb-audio: Fix CME quirk for UF series keyboards Fix quirk for CME master keyboards so it not only handles sysex but also song position pointer, MIDI timing clock, start and stop messages, and active sensing. All of these can be output by the CME UF series master keyboards. Tested with a CME UF6 in a desktop Linux environment as well as on the Zynthian Raspberry Pi based platform. Signed-off-by: Ricard Wanderlof Link: https://patch.msgid.link/20250313-cme-fix-v1-1-d404889e4de8@butoba.net Signed-off-by: Takashi Iwai --- sound/usb/midi.c | 80 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 737dd00e97b1..aa2b7c589c01 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -489,16 +489,84 @@ static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep, /* * CME protocol: like the standard protocol, but SysEx commands are sent as a - * single USB packet preceded by a 0x0F byte. + * single USB packet preceded by a 0x0F byte, as are system realtime + * messages and MIDI Active Sensing. + * Also, multiple messages can be sent in the same packet. */ static void snd_usbmidi_cme_input(struct snd_usb_midi_in_endpoint *ep, uint8_t *buffer, int buffer_length) { - if (buffer_length < 2 || (buffer[0] & 0x0f) != 0x0f) - snd_usbmidi_standard_input(ep, buffer, buffer_length); - else - snd_usbmidi_input_data(ep, buffer[0] >> 4, - &buffer[1], buffer_length - 1); + int remaining = buffer_length; + + /* + * CME send sysex, song position pointer, system realtime + * and active sensing using CIN 0x0f, which in the standard + * is only intended for single byte unparsed data. + * So we need to interpret these here before sending them on. + * By default, we assume single byte data, which is true + * for system realtime (midi clock, start, stop and continue) + * and active sensing, and handle the other (known) cases + * separately. + * In contrast to the standard, CME does not split sysex + * into multiple 4-byte packets, but lumps everything together + * into one. In addition, CME can string multiple messages + * together in the same packet; pressing the Record button + * on an UF6 sends a sysex message directly followed + * by a song position pointer in the same packet. + * For it to have any reasonable meaning, a sysex message + * needs to be at least 3 bytes in length (0xf0, id, 0xf7), + * corresponding to a packet size of 4 bytes, and the ones sent + * by CME devices are 6 or 7 bytes, making the packet fragments + * 7 or 8 bytes long (six or seven bytes plus preceding CN+CIN byte). + * For the other types, the packet size is always 4 bytes, + * as per the standard, with the data size being 3 for SPP + * and 1 for the others. + * Thus all packet fragments are at least 4 bytes long, so we can + * skip anything that is shorter; this also conveniantly skips + * packets with size 0, which CME devices continuously send when + * they have nothing better to do. + * Another quirk is that sometimes multiple messages are sent + * in the same packet. This has been observed for midi clock + * and active sensing i.e. 0x0f 0xf8 0x00 0x00 0x0f 0xfe 0x00 0x00, + * but also multiple note ons/offs, and control change together + * with MIDI clock. Similarly, some sysex messages are followed by + * the song position pointer in the same packet, and occasionally + * additionally by a midi clock or active sensing. + * We handle this by looping over all data and parsing it along the way. + */ + while (remaining >= 4) { + int source_length = 4; /* default */ + + if ((buffer[0] & 0x0f) == 0x0f) { + int data_length = 1; /* default */ + + if (buffer[1] == 0xf0) { + /* Sysex: Find EOX and send on whole message. */ + /* To kick off the search, skip the first + * two bytes (CN+CIN and SYSEX (0xf0). + */ + uint8_t *tmp_buf = buffer + 2; + int tmp_length = remaining - 2; + + while (tmp_length > 1 && *tmp_buf != 0xf7) { + tmp_buf++; + tmp_length--; + } + data_length = tmp_buf - buffer; + source_length = data_length + 1; + } else if (buffer[1] == 0xf2) { + /* Three byte song position pointer */ + data_length = 3; + } + snd_usbmidi_input_data(ep, buffer[0] >> 4, + &buffer[1], data_length); + } else { + /* normal channel events */ + snd_usbmidi_standard_input(ep, buffer, source_length); + } + buffer += source_length; + remaining -= source_length; + } } /* From 5a0c72c1da3cbc0cd4940a95d1be2830104c6edf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 15 Mar 2025 15:30:19 +0100 Subject: [PATCH 486/651] ALSA: hda/realtek: Always honor no_shutup_pins The workaround for Dell machines to skip the pin-shutup for mic pins introduced alc_headset_mic_no_shutup() that is replaced from the generic snd_hda_shutup_pins() for certain codecs. The problem is that the call is done unconditionally even if spec->no_shutup_pins is set. This seems causing problems on other platforms like Lenovo. This patch corrects the behavior and the driver honors always spec->no_shutup_pins flag and skips alc_headset_mic_no_shutup() if it's set. Fixes: dad3197da7a3 ("ALSA: hda/realtek - Fixup headphone noise via runtime suspend") Reported-and-tested-by: Oleg Gorobets Link: https://patch.msgid.link/20250315143020.27184-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a84857a3c2bf..23e5de9499a1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -586,6 +586,9 @@ static void alc_shutup_pins(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + if (spec->no_shutup_pins) + return; + switch (codec->core.vendor_id) { case 0x10ec0236: case 0x10ec0256: @@ -601,8 +604,7 @@ static void alc_shutup_pins(struct hda_codec *codec) alc_headset_mic_no_shutup(codec); break; default: - if (!spec->no_shutup_pins) - snd_hda_shutup_pins(codec); + snd_hda_shutup_pins(codec); break; } } From 399f9bd01644c827be8bfca1236ec9b4c211ccbe Mon Sep 17 00:00:00 2001 From: Weidong Wang Date: Wed, 12 Mar 2025 20:00:59 +0800 Subject: [PATCH 487/651] ASoC: dt-bindings: Add schema for "awinic,aw88166" Add the awinic,aw88166 property to support the aw88166 chip. Signed-off-by: Weidong Wang Acked-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250312120100.9730-2-wangweidong.a@awinic.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/awinic,aw88395.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/awinic,aw88395.yaml b/Documentation/devicetree/bindings/sound/awinic,aw88395.yaml index 6676406bf2de..bb92d6ca3144 100644 --- a/Documentation/devicetree/bindings/sound/awinic,aw88395.yaml +++ b/Documentation/devicetree/bindings/sound/awinic,aw88395.yaml @@ -19,6 +19,7 @@ properties: enum: - awinic,aw88081 - awinic,aw88083 + - awinic,aw88166 - awinic,aw88261 - awinic,aw88395 - awinic,aw88399 From 94e412c28e6144b86d669e4d7ecb6b097431eede Mon Sep 17 00:00:00 2001 From: Weidong Wang Date: Wed, 12 Mar 2025 20:01:00 +0800 Subject: [PATCH 488/651] ASoC: codecs: Add aw88166 amplifier driver The driver is for amplifiers aw88166 of Awinic Technology Corporation. The AW88166 is a high efficiency digital Smart K audio amplifier Signed-off-by: Weidong Wang Link: https://patch.msgid.link/20250312120100.9730-3-wangweidong.a@awinic.com Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 13 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/aw88166.c | 1933 ++++++++++++++++++++++++++++++++++++ sound/soc/codecs/aw88166.h | 534 ++++++++++ 4 files changed, 2482 insertions(+) create mode 100644 sound/soc/codecs/aw88166.c create mode 100644 sound/soc/codecs/aw88166.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ee35f3aa5521..40bb7a1d44bc 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -58,6 +58,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_AW87390 imply SND_SOC_AW88395 imply SND_SOC_AW88081 + imply SND_SOC_AW88166 imply SND_SOC_AW88261 imply SND_SOC_AW88399 imply SND_SOC_BT_SCO @@ -678,6 +679,18 @@ config SND_SOC_AW88395 digital Smart K audio amplifier with an integrated 10V smart boost convert. +config SND_SOC_AW88166 + tristate "Soc Audio for awinic aw88166" + depends on I2C + select REGMAP_I2C + select GPIOLIB + select SND_SOC_AW88395_LIB + help + This option enables support for aw88166 Smart PA. + The awinic AW88166 is an I2S/TDM input, high efficiency + digital Smart K audio amplifier with sound quality + enhancement algorithms and speaker protection. + config SND_SOC_AW88261 tristate "Soc Audio for awinic aw88261" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index d7ad795603c1..10f726066b6c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -53,6 +53,7 @@ snd-soc-aw88081-y := aw88081.o snd-soc-aw88395-lib-y := aw88395/aw88395_lib.o snd-soc-aw88395-y := aw88395/aw88395.o \ aw88395/aw88395_device.o +snd-soc-aw88166-y := aw88166.o snd-soc-aw88261-y := aw88261.o snd-soc-aw88399-y := aw88399.o snd-soc-bd28623-y := bd28623.o @@ -470,6 +471,7 @@ obj-$(CONFIG_SND_SOC_AW87390) += snd-soc-aw87390.o obj-$(CONFIG_SND_SOC_AW88081) += snd-soc-aw88081.o obj-$(CONFIG_SND_SOC_AW88395_LIB) += snd-soc-aw88395-lib.o obj-$(CONFIG_SND_SOC_AW88395) +=snd-soc-aw88395.o +obj-$(CONFIG_SND_SOC_AW88166) +=snd-soc-aw88166.o obj-$(CONFIG_SND_SOC_AW88261) +=snd-soc-aw88261.o obj-$(CONFIG_SND_SOC_AW88399) += snd-soc-aw88399.o obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o diff --git a/sound/soc/codecs/aw88166.c b/sound/soc/codecs/aw88166.c new file mode 100644 index 000000000000..6c50c4a18b6a --- /dev/null +++ b/sound/soc/codecs/aw88166.c @@ -0,0 +1,1933 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// aw88166.c -- ALSA SoC AW88166 codec support +// +// Copyright (c) 2025 AWINIC Technology CO., LTD +// +// Author: Weidong Wang +// + +#include +#include +#include +#include +#include +#include +#include "aw88166.h" +#include "aw88395/aw88395_device.h" + +struct aw88166 { + struct aw_device *aw_pa; + struct mutex lock; + struct gpio_desc *reset_gpio; + struct delayed_work start_work; + struct regmap *regmap; + struct aw_container *aw_cfg; + + unsigned int check_val; + unsigned int crc_init_val; + unsigned int vcalb_init_val; + unsigned int re_init_val; + unsigned int dither_st; + bool phase_sync; +}; + +static const struct regmap_config aw88166_remap_config = { + .val_bits = 16, + .reg_bits = 8, + .max_register = AW88166_REG_MAX, + .reg_format_endian = REGMAP_ENDIAN_LITTLE, + .val_format_endian = REGMAP_ENDIAN_BIG, +}; + +static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int dsp_data) +{ + int ret; + + ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write addr error, ret=%d", __func__, ret); + return ret; + } + + ret = regmap_write(aw_dev->regmap, AW88166_DSPMDAT_REG, (u16)dsp_data); + if (ret) { + dev_err(aw_dev->dev, "%s write data error, ret=%d", __func__, ret); + return ret; + } + + return 0; +} + +static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int *dsp_data) +{ + unsigned int temp_data; + int ret; + + ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret); + return ret; + } + + ret = regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); + return ret; + } + *dsp_data = temp_data; + + return 0; +} + +static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int *dsp_data) +{ + unsigned int temp_data; + int ret; + + ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write error, ret=%d", __func__, ret); + return ret; + } + + ret = regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); + return ret; + } + *dsp_data = temp_data; + + ret = regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s read error, ret=%d", __func__, ret); + return ret; + } + *dsp_data |= (temp_data << 16); + + return 0; +} + +static int aw_dev_dsp_read(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) +{ + u32 reg_value; + int ret; + + mutex_lock(&aw_dev->dsp_lock); + switch (data_type) { + case AW88166_DSP_16_DATA: + ret = aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit failed", (u32)dsp_addr); + break; + case AW88166_DSP_32_DATA: + ret = aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32-bit failed", (u32)dsp_addr); + break; + default: + dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); + ret = -EINVAL; + break; + } + + /* clear dsp chip select state */ + if (regmap_read(aw_dev->regmap, AW88166_ID_REG, ®_value)) + dev_err(aw_dev->dev, "%s fail to clear chip state. ret=%d\n", __func__, ret); + mutex_unlock(&aw_dev->dsp_lock); + + return ret; +} + +static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) +{ + int ret; + + if (pwd) + ret = regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_PWDN_MASK, AW88166_PWDN_POWER_DOWN_VALUE); + else + ret = regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_PWDN_MASK, AW88166_PWDN_WORKING_VALUE); + + if (ret) + dev_dbg(aw_dev->dev, "%s failed", __func__); +} + +static void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short *int_status) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(aw_dev->regmap, AW88166_SYSINT_REG, ®_val); + if (ret) + dev_err(aw_dev->dev, "read interrupt reg fail, ret=%d", ret); + else + *int_status = reg_val; + + dev_dbg(aw_dev->dev, "read interrupt reg=0x%04x", *int_status); +} + +static void aw_dev_clear_int_status(struct aw_device *aw_dev) +{ + u16 int_status; + + /* read int status and clear */ + aw_dev_get_int_status(aw_dev, &int_status); + /* make sure int status is clear */ + aw_dev_get_int_status(aw_dev, &int_status); + if (int_status) + dev_dbg(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status); +} + +static int aw_dev_get_iis_status(struct aw_device *aw_dev) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(aw_dev->regmap, AW88166_SYSST_REG, ®_val); + if (ret) + return ret; + if ((reg_val & AW88166_BIT_PLL_CHECK) != AW88166_BIT_PLL_CHECK) { + dev_err(aw_dev->dev, "check pll lock fail, reg_val:0x%04x", reg_val); + return -EINVAL; + } + + return 0; +} + +static int aw_dev_check_mode1_pll(struct aw_device *aw_dev) +{ + int ret, i; + + for (i = 0; i < AW88166_DEV_SYSST_CHECK_MAX; i++) { + ret = aw_dev_get_iis_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "mode1 iis signal check error"); + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + } else { + return 0; + } + } + + return -EPERM; +} + +static int aw_dev_check_mode2_pll(struct aw_device *aw_dev) +{ + unsigned int reg_val; + int ret, i; + + ret = regmap_read(aw_dev->regmap, AW88166_PLLCTRL2_REG, ®_val); + if (ret) + return ret; + + reg_val &= (~AW88166_CCO_MUX_MASK); + if (reg_val == AW88166_CCO_MUX_DIVIDED_VALUE) { + dev_dbg(aw_dev->dev, "CCO_MUX is already divider"); + return -EPERM; + } + + /* change mode2 */ + ret = regmap_update_bits(aw_dev->regmap, AW88166_PLLCTRL2_REG, + ~AW88166_CCO_MUX_MASK, AW88166_CCO_MUX_DIVIDED_VALUE); + if (ret) + return ret; + + for (i = 0; i < AW88166_DEV_SYSST_CHECK_MAX; i++) { + ret = aw_dev_get_iis_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "mode2 iis signal check error"); + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + } else { + break; + } + } + + /* change mode1 */ + regmap_update_bits(aw_dev->regmap, AW88166_PLLCTRL2_REG, + ~AW88166_CCO_MUX_MASK, AW88166_CCO_MUX_BYPASS_VALUE); + if (ret == 0) { + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + for (i = 0; i < AW88166_DEV_SYSST_CHECK_MAX; i++) { + ret = aw_dev_get_iis_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + } else { + break; + } + } + } + + return ret; +} + +static int aw_dev_check_syspll(struct aw_device *aw_dev) +{ + int ret; + + ret = aw_dev_check_mode1_pll(aw_dev); + if (ret) { + dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); + ret = aw_dev_check_mode2_pll(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "mode2 check iis failed"); + return ret; + } + } + + return 0; +} + +static int aw_dev_check_sysst(struct aw_device *aw_dev) +{ + unsigned int check_val; + unsigned int reg_val; + int ret, i; + + ret = regmap_read(aw_dev->regmap, AW88166_PWMCTRL3_REG, ®_val); + if (ret) + return ret; + + if (reg_val & (~AW88166_NOISE_GATE_EN_MASK)) + check_val = AW88166_BIT_SYSST_NOSWS_CHECK; + else + check_val = AW88166_BIT_SYSST_SWS_CHECK; + + for (i = 0; i < AW88166_DEV_SYSST_CHECK_MAX; i++) { + ret = regmap_read(aw_dev->regmap, AW88166_SYSST_REG, ®_val); + if (ret) + return ret; + + if ((reg_val & (~AW88166_BIT_SYSST_CHECK_MASK) & check_val) != check_val) { + dev_err(aw_dev->dev, "check sysst fail, cnt=%d, reg_val=0x%04x, check:0x%x", + i, reg_val, AW88166_BIT_SYSST_NOSWS_CHECK); + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + } else { + return 0; + } + } + + return -EPERM; +} + +static void aw_dev_amppd(struct aw_device *aw_dev, bool amppd) +{ + int ret; + + if (amppd) + ret = regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_AMPPD_MASK, AW88166_AMPPD_POWER_DOWN_VALUE); + else + ret = regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_AMPPD_MASK, AW88166_AMPPD_WORKING_VALUE); + + if (ret) + dev_dbg(aw_dev->dev, "%s failed", __func__); +} + +static void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable) +{ + int ret; + + if (is_enable) + ret = regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_DSPBY_MASK, AW88166_DSPBY_WORKING_VALUE); + else + ret = regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_DSPBY_MASK, AW88166_DSPBY_BYPASS_VALUE); + + if (ret) + dev_dbg(aw_dev->dev, "%s failed\n", __func__); +} + +static int aw88166_dev_get_icalk(struct aw88166 *aw88166, int16_t *icalk) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + unsigned int efrm_reg_val, efrl_reg_val; + uint16_t ef_isn_geslp, ef_isn_h5bits; + uint16_t icalk_val; + int ret; + + ret = regmap_read(aw_dev->regmap, AW88166_EFRM2_REG, &efrm_reg_val); + if (ret) + return ret; + + ef_isn_geslp = (efrm_reg_val & (~AW88166_EF_ISN_GESLP_MASK)) >> + AW88166_EF_ISN_GESLP_SHIFT; + + ret = regmap_read(aw_dev->regmap, AW88166_EFRL_REG, &efrl_reg_val); + if (ret) + return ret; + + ef_isn_h5bits = (efrl_reg_val & (~AW88166_EF_ISN_H5BITS_MASK)) >> + AW88166_EF_ISN_H5BITS_SHIFT; + + if (aw88166->check_val == AW_EF_AND_CHECK) + icalk_val = ef_isn_geslp & (ef_isn_h5bits | AW88166_EF_ISN_H5BITS_SIGN_MASK); + else + icalk_val = ef_isn_geslp | (ef_isn_h5bits & (~AW88166_EF_ISN_H5BITS_SIGN_MASK)); + + if (icalk_val & (~AW88166_ICALK_SIGN_MASK)) + icalk_val = icalk_val | AW88166_ICALK_NEG_MASK; + *icalk = (int16_t)icalk_val; + + return 0; +} + +static int aw88166_dev_get_vcalk(struct aw88166 *aw88166, int16_t *vcalk) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + unsigned int efrm_reg_val, efrl_reg_val; + uint16_t ef_vsn_geslp, ef_vsn_h3bits; + uint16_t vcalk_val; + int ret; + + ret = regmap_read(aw_dev->regmap, AW88166_EFRM2_REG, &efrm_reg_val); + if (ret) + return ret; + + ef_vsn_geslp = (efrm_reg_val & (~AW88166_EF_VSN_GESLP_MASK)) >> + AW88166_EF_VSN_GESLP_SHIFT; + + ret = regmap_read(aw_dev->regmap, AW88166_EFRL_REG, &efrl_reg_val); + if (ret) + return ret; + + ef_vsn_h3bits = (efrl_reg_val & (~AW88166_EF_VSN_H3BITS_MASK)) >> + AW88166_EF_VSN_H3BITS_SHIFT; + + if (aw88166->check_val == AW_EF_AND_CHECK) + vcalk_val = ef_vsn_geslp & (ef_vsn_h3bits | AW88166_EF_VSN_H3BITS_SIGN_MASK); + else + vcalk_val = ef_vsn_geslp | (ef_vsn_h3bits & (~AW88166_EF_VSN_H3BITS_SIGN_MASK)); + + if (vcalk_val & (~AW88166_VCALK_SIGN_MASK)) + vcalk_val = vcalk_val | AW88166_VCALK_NEG_MASK; + *vcalk = (int16_t)vcalk_val; + + return 0; +} + +static int aw88166_dev_set_vcalb(struct aw88166 *aw88166) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + int32_t ical_k, vcal_k, vcalb; + int16_t icalk, vcalk; + unsigned int reg_val; + int ret; + + ret = aw88166_dev_get_icalk(aw88166, &icalk); + if (ret) { + dev_err(aw_dev->dev, "get icalk failed\n"); + return ret; + } + ical_k = icalk * AW88166_ICABLK_FACTOR + AW88166_CABL_BASE_VALUE; + + ret = aw88166_dev_get_vcalk(aw88166, &vcalk); + if (ret) { + dev_err(aw_dev->dev, "get vbcalk failed\n"); + return ret; + } + vcal_k = vcalk * AW88166_VCABLK_FACTOR + AW88166_CABL_BASE_VALUE; + + vcalb = AW88166_VCALB_ACCURACY * AW88166_VSCAL_FACTOR / + AW88166_ISCAL_FACTOR * ical_k / vcal_k * aw88166->vcalb_init_val; + + vcalb = vcalb >> AW88166_VCALB_ADJ_FACTOR; + reg_val = (uint32_t)vcalb; + + regmap_write(aw_dev->regmap, AW88166_DSPVCALB_REG, reg_val); + + return 0; +} + +static int aw_dev_init_vcalb_update(struct aw88166 *aw88166, int flag) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + int ret; + + switch (flag) { + case AW88166_RECOVERY_SEC_DATA: + ret = regmap_write(aw_dev->regmap, AW88166_DSPVCALB_REG, aw88166->vcalb_init_val); + break; + case AW88166_RECORD_SEC_DATA: + ret = regmap_read(aw_dev->regmap, AW88166_DSPVCALB_REG, &aw88166->vcalb_init_val); + break; + default: + dev_err(aw_dev->dev, "unsupported type:%d\n", flag); + ret = -EINVAL; + break; + } + + return ret; +} + +static int aw_dev_init_re_update(struct aw88166 *aw88166, int flag) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + unsigned int re_temp_h, re_temp_l; + int ret; + + switch (flag) { + case AW88166_RECOVERY_SEC_DATA: + ret = regmap_write(aw_dev->regmap, AW88166_ACR1_REG, aw88166->re_init_val >> 16); + if (ret) + return ret; + ret = regmap_write(aw_dev->regmap, AW88166_ACR2_REG, + (uint16_t)aw88166->re_init_val); + if (ret) + return ret; + break; + case AW88166_RECORD_SEC_DATA: + ret = regmap_read(aw_dev->regmap, AW88166_ACR1_REG, &re_temp_h); + if (ret) + return ret; + ret = regmap_read(aw_dev->regmap, AW88166_ACR2_REG, &re_temp_l); + if (ret) + return ret; + aw88166->re_init_val = (re_temp_h << 16) + re_temp_l; + break; + default: + dev_err(aw_dev->dev, "unsupported type:%d\n", flag); + ret = -EINVAL; + break; + } + + return ret; +} + +static void aw_dev_backup_sec_record(struct aw88166 *aw88166) +{ + aw_dev_init_vcalb_update(aw88166, AW88166_RECORD_SEC_DATA); + aw_dev_init_re_update(aw88166, AW88166_RECOVERY_SEC_DATA); +} + +static void aw_dev_backup_sec_recovery(struct aw88166 *aw88166) +{ + aw_dev_init_vcalb_update(aw88166, AW88166_RECOVERY_SEC_DATA); + aw_dev_init_re_update(aw88166, AW88166_RECOVERY_SEC_DATA); +} + +static int aw_dev_update_cali_re(struct aw_cali_desc *cali_desc) +{ + struct aw_device *aw_dev = + container_of(cali_desc, struct aw_device, cali_desc); + uint16_t re_lbits, re_hbits; + u32 cali_re; + int ret; + + if ((aw_dev->cali_desc.cali_re >= AW88166_CALI_RE_MAX) || + (aw_dev->cali_desc.cali_re <= AW88166_CALI_RE_MIN)) + return -EINVAL; + + cali_re = AW88166_SHOW_RE_TO_DSP_RE((aw_dev->cali_desc.cali_re + + aw_dev->cali_desc.ra), AW88166_DSP_RE_SHIFT); + + re_hbits = (cali_re & (~AW88166_CALI_RE_HBITS_MASK)) >> AW88166_CALI_RE_HBITS_SHIFT; + re_lbits = (cali_re & (~AW88166_CALI_RE_LBITS_MASK)) >> AW88166_CALI_RE_LBITS_SHIFT; + + ret = regmap_write(aw_dev->regmap, AW88166_ACR1_REG, re_hbits); + if (ret) { + dev_err(aw_dev->dev, "set cali re error"); + return ret; + } + + ret = regmap_write(aw_dev->regmap, AW88166_ACR2_REG, re_lbits); + if (ret) + dev_err(aw_dev->dev, "set cali re error"); + + return ret; +} + +static int aw_dev_fw_crc_check(struct aw_device *aw_dev) +{ + uint16_t check_val, fw_len_val; + unsigned int reg_val; + int ret; + + /* calculate fw_end_addr */ + fw_len_val = ((aw_dev->dsp_fw_len / AW_FW_ADDR_LEN) - 1) + AW88166_CRC_FW_BASE_ADDR; + + /* write fw_end_addr to crc_end_addr */ + ret = regmap_update_bits(aw_dev->regmap, AW88166_CRCCTRL_REG, + ~AW88166_CRC_END_ADDR_MASK, fw_len_val); + if (ret) + return ret; + /* enable fw crc check */ + ret = regmap_update_bits(aw_dev->regmap, AW88166_CRCCTRL_REG, + ~AW88166_CRC_CODE_EN_MASK, AW88166_CRC_CODE_EN_ENABLE_VALUE); + + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + + /* read crc check result */ + regmap_read(aw_dev->regmap, AW88166_HAGCST_REG, ®_val); + if (ret) + return ret; + + check_val = (reg_val & (~AW88166_CRC_CHECK_BITS_MASK)) >> AW88166_CRC_CHECK_START_BIT; + + /* disable fw crc check */ + ret = regmap_update_bits(aw_dev->regmap, AW88166_CRCCTRL_REG, + ~AW88166_CRC_CODE_EN_MASK, AW88166_CRC_CODE_EN_DISABLE_VALUE); + if (ret) + return ret; + + if (check_val != AW88166_CRC_CHECK_PASS_VAL) { + dev_err(aw_dev->dev, "%s failed, check_val 0x%x != 0x%x\n", + __func__, check_val, AW88166_CRC_CHECK_PASS_VAL); + ret = -EINVAL; + } + + return ret; +} + +static int aw_dev_cfg_crc_check(struct aw_device *aw_dev) +{ + uint16_t check_val, cfg_len_val; + unsigned int reg_val; + int ret; + + /* calculate cfg end addr */ + cfg_len_val = ((aw_dev->dsp_cfg_len / AW_FW_ADDR_LEN) - 1) + AW88166_CRC_CFG_BASE_ADDR; + + /* write cfg_end_addr to crc_end_addr */ + ret = regmap_update_bits(aw_dev->regmap, AW88166_CRCCTRL_REG, + ~AW88166_CRC_END_ADDR_MASK, cfg_len_val); + if (ret) + return ret; + + /* enable cfg crc check */ + ret = regmap_update_bits(aw_dev->regmap, AW88166_CRCCTRL_REG, + ~AW88166_CRC_CFG_EN_MASK, AW88166_CRC_CFG_EN_ENABLE_VALUE); + if (ret) + return ret; + + usleep_range(AW88166_1000_US, AW88166_1000_US + 10); + + /* read crc check result */ + ret = regmap_read(aw_dev->regmap, AW88166_HAGCST_REG, ®_val); + if (ret) + return ret; + + check_val = (reg_val & (~AW88166_CRC_CHECK_BITS_MASK)) >> AW88166_CRC_CHECK_START_BIT; + + /* disable cfg crc check */ + ret = regmap_update_bits(aw_dev->regmap, AW88166_CRCCTRL_REG, + ~AW88166_CRC_CFG_EN_MASK, AW88166_CRC_CFG_EN_DISABLE_VALUE); + if (ret) + return ret; + + if (check_val != AW88166_CRC_CHECK_PASS_VAL) { + dev_err(aw_dev->dev, "crc_check failed, check val 0x%x != 0x%x\n", + check_val, AW88166_CRC_CHECK_PASS_VAL); + ret = -EINVAL; + } + + return ret; +} + +static int aw_dev_hw_crc_check(struct aw88166 *aw88166) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + int ret; + + ret = regmap_update_bits(aw_dev->regmap, AW88166_I2SCFG1_REG, + ~AW88166_RAM_CG_BYP_MASK, AW88166_RAM_CG_BYP_BYPASS_VALUE); + if (ret) + return ret; + + ret = aw_dev_fw_crc_check(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "fw_crc_check failed\n"); + goto crc_check_failed; + } + + ret = aw_dev_cfg_crc_check(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "cfg_crc_check failed\n"); + goto crc_check_failed; + } + + ret = regmap_write(aw_dev->regmap, AW88166_CRCCTRL_REG, aw88166->crc_init_val); + if (ret) + return ret; + + ret = regmap_update_bits(aw_dev->regmap, AW88166_I2SCFG1_REG, + ~AW88166_RAM_CG_BYP_MASK, AW88166_RAM_CG_BYP_WORK_VALUE); + + return ret; + +crc_check_failed: + regmap_update_bits(aw_dev->regmap, AW88166_I2SCFG1_REG, + ~AW88166_RAM_CG_BYP_MASK, AW88166_RAM_CG_BYP_WORK_VALUE); + return ret; +} + +static void aw_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) +{ + int ret; + + if (flag) + ret = regmap_update_bits(aw_dev->regmap, AW88166_I2SCTRL3_REG, + ~AW88166_I2STXEN_MASK, AW88166_I2STXEN_ENABLE_VALUE); + else + ret = regmap_update_bits(aw_dev->regmap, AW88166_I2SCTRL3_REG, + ~AW88166_I2STXEN_MASK, AW88166_I2STXEN_DISABLE_VALUE); + + if (ret) + dev_dbg(aw_dev->dev, "%s failed", __func__); +} + +static int aw_dev_get_dsp_status(struct aw_device *aw_dev) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(aw_dev->regmap, AW88166_WDT_REG, ®_val); + if (ret) + return ret; + if (!(reg_val & (~AW88166_WDT_CNT_MASK))) + return -EPERM; + + return 0; +} + +static int aw_dev_dsp_check(struct aw_device *aw_dev) +{ + int ret, i; + + switch (aw_dev->dsp_cfg) { + case AW88166_DEV_DSP_BYPASS: + dev_dbg(aw_dev->dev, "dsp bypass"); + ret = 0; + break; + case AW88166_DEV_DSP_WORK: + aw_dev_dsp_enable(aw_dev, false); + aw_dev_dsp_enable(aw_dev, true); + usleep_range(AW88166_1000_US, AW88166_1000_US + 10); + for (i = 0; i < AW88166_DEV_DSP_CHECK_MAX; i++) { + ret = aw_dev_get_dsp_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp wdt status error=%d", ret); + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + } + } + break; + default: + dev_err(aw_dev->dev, "unknown dsp cfg=%d", aw_dev->dsp_cfg); + ret = -EINVAL; + break; + } + + return ret; +} + +static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value) +{ + struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; + unsigned int reg_value; + u16 real_value; + int ret; + + real_value = min((value + vol_desc->init_volume), (unsigned int)AW88166_MUTE_VOL); + + ret = regmap_read(aw_dev->regmap, AW88166_SYSCTRL2_REG, ®_value); + if (ret) + return ret; + + dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value); + + real_value = (real_value << AW88166_VOL_START_BIT) | (reg_value & AW88166_VOL_MASK); + + ret = regmap_write(aw_dev->regmap, AW88166_SYSCTRL2_REG, real_value); + + return ret; +} + +static void aw_dev_fade_in(struct aw_device *aw_dev) +{ + struct aw_volume_desc *desc = &aw_dev->volume_desc; + u16 fade_in_vol = desc->ctl_volume; + int fade_step = aw_dev->fade_step; + int i; + + if (fade_step == 0 || aw_dev->fade_in_time == 0) { + aw_dev_set_volume(aw_dev, fade_in_vol); + return; + } + + for (i = AW88166_MUTE_VOL; i >= fade_in_vol; i -= fade_step) { + aw_dev_set_volume(aw_dev, i); + usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); + } + + if (i != fade_in_vol) + aw_dev_set_volume(aw_dev, fade_in_vol); +} + +static void aw_dev_fade_out(struct aw_device *aw_dev) +{ + struct aw_volume_desc *desc = &aw_dev->volume_desc; + int fade_step = aw_dev->fade_step; + int i; + + if (fade_step == 0 || aw_dev->fade_out_time == 0) { + aw_dev_set_volume(aw_dev, AW88166_MUTE_VOL); + return; + } + + for (i = desc->ctl_volume; i <= AW88166_MUTE_VOL; i += fade_step) { + aw_dev_set_volume(aw_dev, i); + usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); + } + + if (i != AW88166_MUTE_VOL) { + aw_dev_set_volume(aw_dev, AW88166_MUTE_VOL); + usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); + } +} + +static void aw88166_dev_mute(struct aw_device *aw_dev, bool is_mute) +{ + if (is_mute) { + aw_dev_fade_out(aw_dev); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_HMUTE_MASK, AW88166_HMUTE_ENABLE_VALUE); + } else { + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_HMUTE_MASK, AW88166_HMUTE_DISABLE_VALUE); + aw_dev_fade_in(aw_dev); + } +} + +static void aw88166_dev_set_dither(struct aw88166 *aw88166, bool dither) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + + if (dither) + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, + ~AW88166_DITHER_EN_MASK, AW88166_DITHER_EN_ENABLE_VALUE); + else + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, + ~AW88166_DITHER_EN_MASK, AW88166_DITHER_EN_DISABLE_VALUE); +} + +static int aw88166_dev_start(struct aw88166 *aw88166) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + int ret; + + if (aw_dev->status == AW88166_DEV_PW_ON) { + dev_dbg(aw_dev->dev, "already power on"); + return 0; + } + + aw88166_dev_set_dither(aw88166, false); + + /* power on */ + aw_dev_pwd(aw_dev, false); + usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + + ret = aw_dev_check_syspll(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "pll check failed cannot start\n"); + goto pll_check_fail; + } + + /* amppd on */ + aw_dev_amppd(aw_dev, false); + usleep_range(AW88166_1000_US, AW88166_1000_US + 50); + + /* check i2s status */ + ret = aw_dev_check_sysst(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "sysst check failed\n"); + goto sysst_check_fail; + } + + if (aw_dev->dsp_cfg == AW88166_DEV_DSP_WORK) { + aw_dev_backup_sec_recovery(aw88166); + ret = aw_dev_hw_crc_check(aw88166); + if (ret) { + dev_err(aw_dev->dev, "dsp crc check failed\n"); + goto crc_check_fail; + } + aw_dev_dsp_enable(aw_dev, false); + aw88166_dev_set_vcalb(aw88166); + aw_dev_update_cali_re(&aw_dev->cali_desc); + ret = aw_dev_dsp_check(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp status check failed\n"); + goto dsp_check_fail; + } + } else { + dev_dbg(aw_dev->dev, "start pa with dsp bypass"); + } + + /* enable tx feedback */ + aw_dev_i2s_tx_enable(aw_dev, true); + + if (aw88166->dither_st == AW88166_DITHER_EN_ENABLE_VALUE) + aw88166_dev_set_dither(aw88166, true); + + /* close mute */ + aw88166_dev_mute(aw_dev, false); + /* clear inturrupt */ + aw_dev_clear_int_status(aw_dev); + aw_dev->status = AW88166_DEV_PW_ON; + + return 0; + +dsp_check_fail: +crc_check_fail: + aw_dev_dsp_enable(aw_dev, false); +sysst_check_fail: + aw_dev_clear_int_status(aw_dev); + aw_dev_amppd(aw_dev, true); +pll_check_fail: + aw_dev_pwd(aw_dev, true); + aw_dev->status = AW88166_DEV_PW_OFF; + + return ret; +} + +static int aw_dev_dsp_update_container(struct aw_device *aw_dev, + unsigned char *data, unsigned int len, unsigned short base) +{ + u32 tmp_len; + int i, ret; + + mutex_lock(&aw_dev->dsp_lock); + ret = regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, base); + if (ret) + goto error_operation; + + for (i = 0; i < len; i += AW88166_MAX_RAM_WRITE_BYTE_SIZE) { + if ((len - i) < AW88166_MAX_RAM_WRITE_BYTE_SIZE) + tmp_len = len - i; + else + tmp_len = AW88166_MAX_RAM_WRITE_BYTE_SIZE; + + ret = regmap_raw_write(aw_dev->regmap, AW88166_DSPMDAT_REG, + &data[i], tmp_len); + if (ret) + goto error_operation; + } + mutex_unlock(&aw_dev->dsp_lock); + + return 0; + +error_operation: + mutex_unlock(&aw_dev->dsp_lock); + return ret; +} + +static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) +{ + struct aw_device *aw_dev = + container_of(cali_desc, struct aw_device, cali_desc); + u32 dsp_ra; + int ret; + + ret = aw_dev_dsp_read(aw_dev, AW88166_DSP_REG_CFG_ADPZ_RA, + &dsp_ra, AW88166_DSP_32_DATA); + if (ret) { + dev_err(aw_dev->dev, "read ra error\n"); + return ret; + } + + cali_desc->ra = AW88166_DSP_RE_TO_SHOW_RE(dsp_ra, + AW88166_DSP_RE_SHIFT); + + return 0; +} + +static int aw_dev_dsp_update_cfg(struct aw_device *aw_dev, + unsigned char *data, unsigned int len) +{ + int ret; + + dev_dbg(aw_dev->dev, "dsp config len:%d", len); + + if (!len || !data) { + dev_err(aw_dev->dev, "dsp config data is null or len is 0\n"); + return -EINVAL; + } + + ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88166_DSP_CFG_ADDR); + if (ret) + return ret; + + aw_dev->dsp_cfg_len = len; + + ret = aw_dev_get_ra(&aw_dev->cali_desc); + + return ret; +} + +static int aw_dev_dsp_update_fw(struct aw_device *aw_dev, + unsigned char *data, unsigned int len) +{ + int ret; + + dev_dbg(aw_dev->dev, "dsp firmware len:%d", len); + + if (!len || !data) { + dev_err(aw_dev->dev, "dsp firmware data is null or len is 0\n"); + return -EINVAL; + } + + aw_dev->dsp_fw_len = len; + ret = aw_dev_dsp_update_container(aw_dev, data, len, AW88166_DSP_FW_ADDR); + + return ret; +} + +static int aw_dev_check_sram(struct aw_device *aw_dev) +{ + unsigned int reg_val; + + mutex_lock(&aw_dev->dsp_lock); + /* read dsp_rom_check_reg */ + aw_dev_dsp_read_16bit(aw_dev, AW88166_DSP_ROM_CHECK_ADDR, ®_val); + if (reg_val != AW88166_DSP_ROM_CHECK_DATA) { + dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] != check[0x%x]\n", + reg_val, AW88166_DSP_ROM_CHECK_DATA); + goto error; + } + + /* check dsp_cfg_base_addr */ + aw_dev_dsp_write_16bit(aw_dev, AW88166_DSP_CFG_ADDR, AW88166_DSP_ODD_NUM_BIT_TEST); + aw_dev_dsp_read_16bit(aw_dev, AW88166_DSP_CFG_ADDR, ®_val); + if (reg_val != AW88166_DSP_ODD_NUM_BIT_TEST) { + dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] != write[0x%x]\n", + reg_val, AW88166_DSP_ODD_NUM_BIT_TEST); + goto error; + } + mutex_unlock(&aw_dev->dsp_lock); + + return 0; +error: + mutex_unlock(&aw_dev->dsp_lock); + return -EPERM; +} + +static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char flag) +{ + int ret; + + switch (flag) { + case AW88166_DEV_MEMCLK_PLL: + ret = regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, + ~AW88166_MEM_CLKSEL_MASK, + AW88166_MEM_CLKSEL_DAPHCLK_VALUE); + if (ret) + dev_err(aw_dev->dev, "memclk select pll failed\n"); + break; + case AW88166_DEV_MEMCLK_OSC: + ret = regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, + ~AW88166_MEM_CLKSEL_MASK, + AW88166_MEM_CLKSEL_OSCCLK_VALUE); + if (ret) + dev_err(aw_dev->dev, "memclk select OSC failed\n"); + break; + default: + dev_err(aw_dev->dev, "unknown memclk config, flag=0x%x\n", flag); + break; + } +} + +static int aw_dev_update_reg_container(struct aw88166 *aw88166, + unsigned char *data, unsigned int len) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + struct aw_volume_desc *vol_desc = &aw_dev->volume_desc; + u16 read_vol, reg_val; + int data_len, i, ret; + int16_t *reg_data; + u8 reg_addr; + + reg_data = (int16_t *)data; + data_len = len >> 1; + + if (data_len & 0x1) { + dev_err(aw_dev->dev, "data len:%d unsupported\n", data_len); + return -EINVAL; + } + + for (i = 0; i < data_len; i += 2) { + reg_addr = reg_data[i]; + reg_val = reg_data[i + 1]; + + if (reg_addr == AW88166_DSPVCALB_REG) { + aw88166->vcalb_init_val = reg_val; + continue; + } + + if (reg_addr == AW88166_SYSCTRL_REG) { + if (reg_val & (~AW88166_DSPBY_MASK)) + aw_dev->dsp_cfg = AW88166_DEV_DSP_BYPASS; + else + aw_dev->dsp_cfg = AW88166_DEV_DSP_WORK; + + reg_val &= (AW88166_HMUTE_MASK | AW88166_PWDN_MASK | + AW88166_DSPBY_MASK); + reg_val |= (AW88166_HMUTE_ENABLE_VALUE | AW88166_PWDN_POWER_DOWN_VALUE | + AW88166_DSPBY_BYPASS_VALUE); + } + + if (reg_addr == AW88166_I2SCTRL3_REG) { + reg_val &= AW88166_I2STXEN_MASK; + reg_val |= AW88166_I2STXEN_DISABLE_VALUE; + } + + if (reg_addr == AW88166_SYSCTRL2_REG) { + read_vol = (reg_val & (~AW88166_VOL_MASK)) >> + AW88166_VOL_START_BIT; + aw_dev->volume_desc.init_volume = read_vol; + } + + if (reg_addr == AW88166_DBGCTRL_REG) { + if ((reg_val & (~AW88166_EF_DBMD_MASK)) == AW88166_EF_DBMD_OR_VALUE) + aw88166->check_val = AW_EF_OR_CHECK; + else + aw88166->check_val = AW_EF_AND_CHECK; + + aw88166->dither_st = reg_val & (~AW88166_DITHER_EN_MASK); + } + + if (reg_addr == AW88166_ACR1_REG) { + aw88166->re_init_val |= (uint32_t)reg_val << 16; + continue; + } + + if (reg_addr == AW88166_ACR2_REG) { + aw88166->re_init_val |= (uint32_t)reg_val; + continue; + } + + if (reg_addr == AW88166_CRCCTRL_REG) + aw88166->crc_init_val = reg_val; + + ret = regmap_write(aw_dev->regmap, reg_addr, reg_val); + if (ret) + return ret; + } + + aw_dev_pwd(aw_dev, false); + usleep_range(AW88166_1000_US, AW88166_1000_US + 10); + + if (aw_dev->prof_cur != aw_dev->prof_index) + vol_desc->ctl_volume = 0; + else + aw_dev_set_volume(aw_dev, vol_desc->ctl_volume); + + return 0; +} + +static int aw_dev_reg_update(struct aw88166 *aw88166, + unsigned char *data, unsigned int len) +{ + int ret; + + if (!len || !data) { + dev_err(aw88166->aw_pa->dev, "reg data is null or len is 0\n"); + return -EINVAL; + } + + ret = aw_dev_update_reg_container(aw88166, data, len); + if (ret) + dev_err(aw88166->aw_pa->dev, "reg update failed\n"); + + return ret; +} + +static int aw88166_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name) +{ + struct aw_prof_info *prof_info = &aw_dev->prof_info; + struct aw_prof_desc *prof_desc; + + if ((index >= aw_dev->prof_info.count) || (index < 0)) { + dev_err(aw_dev->dev, "index[%d] overflow count[%d]\n", + index, aw_dev->prof_info.count); + return -EINVAL; + } + + prof_desc = &aw_dev->prof_info.prof_desc[index]; + + *prof_name = prof_info->prof_name_list[prof_desc->id]; + + return 0; +} + +static int aw88166_dev_get_prof_data(struct aw_device *aw_dev, int index, + struct aw_prof_desc **prof_desc) +{ + if ((index >= aw_dev->prof_info.count) || (index < 0)) { + dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", + __func__, index, aw_dev->prof_info.count); + return -EINVAL; + } + + *prof_desc = &aw_dev->prof_info.prof_desc[index]; + + return 0; +} + +static int aw88166_dev_fw_update(struct aw88166 *aw88166, bool up_dsp_fw_en, bool force_up_en) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + struct aw_prof_desc *prof_index_desc; + struct aw_sec_data_desc *sec_desc; + char *prof_name; + int ret; + + if ((aw_dev->prof_cur == aw_dev->prof_index) && + (force_up_en == AW88166_FORCE_UPDATE_OFF)) { + dev_dbg(aw_dev->dev, "scene no change, not update"); + return 0; + } + + if (aw_dev->fw_status == AW88166_DEV_FW_FAILED) { + dev_err(aw_dev->dev, "fw status[%d] error\n", aw_dev->fw_status); + return -EPERM; + } + + ret = aw88166_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); + if (ret) + return ret; + + dev_dbg(aw_dev->dev, "start update %s", prof_name); + + ret = aw88166_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc); + if (ret) + return ret; + + /* update reg */ + sec_desc = prof_index_desc->sec_desc; + ret = aw_dev_reg_update(aw88166, sec_desc[AW88395_DATA_TYPE_REG].data, + sec_desc[AW88395_DATA_TYPE_REG].len); + if (ret) { + dev_err(aw_dev->dev, "update reg failed\n"); + return ret; + } + + aw88166_dev_mute(aw_dev, true); + + if (aw_dev->dsp_cfg == AW88166_DEV_DSP_WORK) + aw_dev_dsp_enable(aw_dev, false); + + aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_OSC); + + ret = aw_dev_check_sram(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "check sram failed\n"); + goto error; + } + + aw_dev_backup_sec_recovery(aw88166); + + if (up_dsp_fw_en) { + dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver); + ret = aw_dev_dsp_update_fw(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_FW].data, + sec_desc[AW88395_DATA_TYPE_DSP_FW].len); + if (ret) { + dev_err(aw_dev->dev, "update dsp fw failed\n"); + goto error; + } + } + + /* update dsp config */ + ret = aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_CFG].data, + sec_desc[AW88395_DATA_TYPE_DSP_CFG].len); + if (ret) { + dev_err(aw_dev->dev, "update dsp cfg failed\n"); + goto error; + } + + aw_dev_backup_sec_record(aw88166); + + aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_PLL); + + aw_dev->prof_cur = aw_dev->prof_index; + + return 0; + +error: + aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_PLL); + return ret; +} + +static void aw88166_start_pa(struct aw88166 *aw88166) +{ + int ret, i; + + for (i = 0; i < AW88166_START_RETRIES; i++) { + ret = aw88166_dev_start(aw88166); + if (ret) { + dev_err(aw88166->aw_pa->dev, "aw88166 device start failed. retry = %d", i); + ret = aw88166_dev_fw_update(aw88166, AW88166_DSP_FW_UPDATE_ON, true); + if (ret) { + dev_err(aw88166->aw_pa->dev, "fw update failed"); + continue; + } + } else { + dev_dbg(aw88166->aw_pa->dev, "start success\n"); + break; + } + } +} + +static void aw88166_startup_work(struct work_struct *work) +{ + struct aw88166 *aw88166 = + container_of(work, struct aw88166, start_work.work); + + mutex_lock(&aw88166->lock); + aw88166_start_pa(aw88166); + mutex_unlock(&aw88166->lock); +} + +static void aw88166_start(struct aw88166 *aw88166, bool sync_start) +{ + int ret; + + if (aw88166->aw_pa->fw_status != AW88166_DEV_FW_OK) + return; + + if (aw88166->aw_pa->status == AW88166_DEV_PW_ON) + return; + + ret = aw88166_dev_fw_update(aw88166, AW88166_DSP_FW_UPDATE_OFF, aw88166->phase_sync); + if (ret) { + dev_err(aw88166->aw_pa->dev, "fw update failed\n"); + return; + } + + if (sync_start == AW88166_SYNC_START) + aw88166_start_pa(aw88166); + else + queue_delayed_work(system_wq, + &aw88166->start_work, + AW88166_START_WORK_DELAY_MS); +} + +static int aw_dev_check_sysint(struct aw_device *aw_dev) +{ + u16 reg_val; + + aw_dev_get_int_status(aw_dev, ®_val); + if (reg_val & AW88166_BIT_SYSINT_CHECK) { + dev_err(aw_dev->dev, "pa stop check fail:0x%04x\n", reg_val); + return -EINVAL; + } + + return 0; +} + +static int aw88166_stop(struct aw_device *aw_dev) +{ + struct aw_sec_data_desc *dsp_cfg = + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_CFG]; + struct aw_sec_data_desc *dsp_fw = + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYPE_DSP_FW]; + int int_st; + + if (aw_dev->status == AW88166_DEV_PW_OFF) { + dev_dbg(aw_dev->dev, "already power off"); + return 0; + } + + aw_dev->status = AW88166_DEV_PW_OFF; + + aw88166_dev_mute(aw_dev, true); + usleep_range(AW88166_4000_US, AW88166_4000_US + 100); + + aw_dev_i2s_tx_enable(aw_dev, false); + usleep_range(AW88166_1000_US, AW88166_1000_US + 100); + + int_st = aw_dev_check_sysint(aw_dev); + + aw_dev_dsp_enable(aw_dev, false); + + aw_dev_amppd(aw_dev, true); + + if (int_st) { + aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_OSC); + aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len); + aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len); + aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_PLL); + } + + aw_dev_pwd(aw_dev, true); + + return 0; +} + +static struct snd_soc_dai_driver aw88166_dai[] = { + { + .name = "aw88166-aif", + .id = 1, + .playback = { + .stream_name = "Speaker_Playback", + .channels_min = 1, + .channels_max = 2, + .rates = AW88166_RATES, + .formats = AW88166_FORMATS, + }, + .capture = { + .stream_name = "Speaker_Capture", + .channels_min = 1, + .channels_max = 2, + .rates = AW88166_RATES, + .formats = AW88166_FORMATS, + }, + }, +}; + +static int aw88166_get_fade_in_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(component); + struct aw_device *aw_dev = aw88166->aw_pa; + + ucontrol->value.integer.value[0] = aw_dev->fade_in_time; + + return 0; +} + +static int aw88166_set_fade_in_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(component); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct aw_device *aw_dev = aw88166->aw_pa; + int time; + + time = ucontrol->value.integer.value[0]; + + if (time < mc->min || time > mc->max) + return -EINVAL; + + if (time != aw_dev->fade_in_time) { + aw_dev->fade_in_time = time; + return 1; + } + + return 0; +} + +static int aw88166_get_fade_out_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(component); + struct aw_device *aw_dev = aw88166->aw_pa; + + ucontrol->value.integer.value[0] = aw_dev->fade_out_time; + + return 0; +} + +static int aw88166_set_fade_out_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(component); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct aw_device *aw_dev = aw88166->aw_pa; + int time; + + time = ucontrol->value.integer.value[0]; + if (time < mc->min || time > mc->max) + return -EINVAL; + + if (time != aw_dev->fade_out_time) { + aw_dev->fade_out_time = time; + return 1; + } + + return 0; +} + +static int aw88166_dev_set_profile_index(struct aw_device *aw_dev, int index) +{ + /* check the index whether is valid */ + if ((index >= aw_dev->prof_info.count) || (index < 0)) + return -EINVAL; + /* check the index whether change */ + if (aw_dev->prof_index == index) + return -EINVAL; + + aw_dev->prof_index = index; + dev_dbg(aw_dev->dev, "set prof[%s]", + aw_dev->prof_info.prof_name_list[aw_dev->prof_info.prof_desc[index].id]); + + return 0; +} + +static int aw88166_profile_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + char *prof_name, *name; + int count, ret; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + + count = aw88166->aw_pa->prof_info.count; + if (count <= 0) { + uinfo->value.enumerated.items = 0; + return 0; + } + + uinfo->value.enumerated.items = count; + + if (uinfo->value.enumerated.item >= count) + uinfo->value.enumerated.item = count - 1; + + name = uinfo->value.enumerated.name; + count = uinfo->value.enumerated.item; + + ret = aw88166_dev_get_prof_name(aw88166->aw_pa, count, &prof_name); + if (ret) { + strscpy(uinfo->value.enumerated.name, "null", + strlen("null") + 1); + return 0; + } + + strscpy(name, prof_name, sizeof(uinfo->value.enumerated.name)); + + return 0; +} + +static int aw88166_profile_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aw88166->aw_pa->prof_index; + + return 0; +} + +static int aw88166_profile_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + int ret; + + mutex_lock(&aw88166->lock); + ret = aw88166_dev_set_profile_index(aw88166->aw_pa, ucontrol->value.integer.value[0]); + if (ret) { + dev_dbg(codec->dev, "profile index does not change"); + mutex_unlock(&aw88166->lock); + return 0; + } + + if (aw88166->aw_pa->status) { + aw88166_stop(aw88166->aw_pa); + aw88166_start(aw88166, AW88166_SYNC_START); + } + + mutex_unlock(&aw88166->lock); + + return 1; +} + +static int aw88166_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + struct aw_volume_desc *vol_desc = &aw88166->aw_pa->volume_desc; + + ucontrol->value.integer.value[0] = vol_desc->ctl_volume; + + return 0; +} + +static int aw88166_volume_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + struct aw_volume_desc *vol_desc = &aw88166->aw_pa->volume_desc; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int value; + + value = ucontrol->value.integer.value[0]; + if (value < mc->min || value > mc->max) + return -EINVAL; + + if (vol_desc->ctl_volume != value) { + vol_desc->ctl_volume = value; + aw_dev_set_volume(aw88166->aw_pa, vol_desc->ctl_volume); + + return 1; + } + + return 0; +} + +static int aw88166_get_fade_step(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + + ucontrol->value.integer.value[0] = aw88166->aw_pa->fade_step; + + return 0; +} + +static int aw88166_set_fade_step(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int value; + + value = ucontrol->value.integer.value[0]; + if (value < mc->min || value > mc->max) + return -EINVAL; + + if (aw88166->aw_pa->fade_step != value) { + aw88166->aw_pa->fade_step = value; + return 1; + } + + return 0; +} + +static int aw88166_re_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + struct aw_device *aw_dev = aw88166->aw_pa; + + ucontrol->value.integer.value[0] = aw_dev->cali_desc.cali_re; + + return 0; +} + +static int aw88166_re_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec); + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct aw_device *aw_dev = aw88166->aw_pa; + int value; + + value = ucontrol->value.integer.value[0]; + if (value < mc->min || value > mc->max) + return -EINVAL; + + if (aw_dev->cali_desc.cali_re != value) { + aw_dev->cali_desc.cali_re = value; + return 1; + } + + return 0; +} + +static int aw88166_dev_init(struct aw88166 *aw88166, struct aw_container *aw_cfg) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + int ret; + + ret = aw88395_dev_cfg_load(aw_dev, aw_cfg); + if (ret) { + dev_err(aw_dev->dev, "aw_dev acf parse failed\n"); + return -EINVAL; + } + aw_dev->fade_in_time = AW88166_1000_US / 10; + aw_dev->fade_out_time = AW88166_1000_US >> 1; + aw_dev->prof_cur = aw_dev->prof_info.prof_desc[0].id; + aw_dev->prof_index = aw_dev->prof_info.prof_desc[0].id; + + ret = aw88166_dev_fw_update(aw88166, AW88166_FORCE_UPDATE_ON, AW88166_DSP_FW_UPDATE_ON); + if (ret) { + dev_err(aw_dev->dev, "fw update failed ret = %d\n", ret); + return ret; + } + + aw88166_dev_mute(aw_dev, true); + + /* close tx feedback */ + aw_dev_i2s_tx_enable(aw_dev, false); + usleep_range(AW88166_1000_US, AW88166_1000_US + 100); + + /* enable amppd */ + aw_dev_amppd(aw_dev, true); + + /* close dsp */ + aw_dev_dsp_enable(aw_dev, false); + /* set power down */ + aw_dev_pwd(aw_dev, true); + + return 0; +} + +static int aw88166_request_firmware_file(struct aw88166 *aw88166) +{ + const struct firmware *cont = NULL; + int ret; + + aw88166->aw_pa->fw_status = AW88166_DEV_FW_FAILED; + + ret = request_firmware(&cont, AW88166_ACF_FILE, aw88166->aw_pa->dev); + if (ret) { + dev_err(aw88166->aw_pa->dev, "request [%s] failed!\n", AW88166_ACF_FILE); + return ret; + } + + dev_dbg(aw88166->aw_pa->dev, "loaded %s - size: %zu\n", + AW88166_ACF_FILE, cont ? cont->size : 0); + + aw88166->aw_cfg = devm_kzalloc(aw88166->aw_pa->dev, + struct_size(aw88166->aw_cfg, data, cont->size), GFP_KERNEL); + if (!aw88166->aw_cfg) { + release_firmware(cont); + return -ENOMEM; + } + aw88166->aw_cfg->len = (int)cont->size; + memcpy(aw88166->aw_cfg->data, cont->data, cont->size); + release_firmware(cont); + + ret = aw88395_dev_load_acf_check(aw88166->aw_pa, aw88166->aw_cfg); + if (ret) { + dev_err(aw88166->aw_pa->dev, "load [%s] failed!\n", AW88166_ACF_FILE); + return ret; + } + + mutex_lock(&aw88166->lock); + /* aw device init */ + ret = aw88166_dev_init(aw88166, aw88166->aw_cfg); + if (ret) + dev_err(aw88166->aw_pa->dev, "dev init failed\n"); + mutex_unlock(&aw88166->lock); + + return ret; +} + +static const struct snd_kcontrol_new aw88166_controls[] = { + SOC_SINGLE_EXT("PCM Playback Volume", AW88166_SYSCTRL2_REG, + 6, AW88166_MUTE_VOL, 0, aw88166_volume_get, + aw88166_volume_set), + SOC_SINGLE_EXT("Fade Step", 0, 0, AW88166_MUTE_VOL, 0, + aw88166_get_fade_step, aw88166_set_fade_step), + SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN, + aw88166_get_fade_in_time, aw88166_set_fade_in_time), + SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN, + aw88166_get_fade_out_time, aw88166_set_fade_out_time), + SOC_SINGLE_EXT("Calib", 0, 0, AW88166_CALI_RE_MAX, 0, + aw88166_re_get, aw88166_re_set), + AW88166_PROFILE_EXT("AW88166 Profile Set", aw88166_profile_info, + aw88166_profile_get, aw88166_profile_set), +}; + +static int aw88166_playback_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(component); + + mutex_lock(&aw88166->lock); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aw88166_start(aw88166, AW88166_ASYNC_START); + break; + case SND_SOC_DAPM_POST_PMD: + aw88166_stop(aw88166->aw_pa); + break; + default: + break; + } + mutex_unlock(&aw88166->lock); + + return 0; +} + +static const struct snd_soc_dapm_widget aw88166_dapm_widgets[] = { + /* playback */ + SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, SND_SOC_NOPM, 0, 0, + aw88166_playback_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUTPUT("DAC Output"), + + /* capture */ + SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_INPUT("ADC Input"), +}; + +static const struct snd_soc_dapm_route aw88166_audio_map[] = { + {"DAC Output", NULL, "AIF_RX"}, + {"AIF_TX", NULL, "ADC Input"}, +}; + +static int aw88166_codec_probe(struct snd_soc_component *component) +{ + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(component); + int ret; + + INIT_DELAYED_WORK(&aw88166->start_work, aw88166_startup_work); + + ret = aw88166_request_firmware_file(aw88166); + if (ret) + dev_err(aw88166->aw_pa->dev, "%s failed\n", __func__); + + return ret; +} + +static void aw88166_codec_remove(struct snd_soc_component *aw_codec) +{ + struct aw88166 *aw88166 = snd_soc_component_get_drvdata(aw_codec); + + cancel_delayed_work_sync(&aw88166->start_work); +} + +static const struct snd_soc_component_driver soc_codec_dev_aw88166 = { + .probe = aw88166_codec_probe, + .remove = aw88166_codec_remove, + .dapm_widgets = aw88166_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aw88166_dapm_widgets), + .dapm_routes = aw88166_audio_map, + .num_dapm_routes = ARRAY_SIZE(aw88166_audio_map), + .controls = aw88166_controls, + .num_controls = ARRAY_SIZE(aw88166_controls), +}; + +static void aw88166_hw_reset(struct aw88166 *aw88166) +{ + if (aw88166->reset_gpio) { + gpiod_set_value_cansleep(aw88166->reset_gpio, 1); + usleep_range(AW88166_1000_US, AW88166_1000_US + 10); + gpiod_set_value_cansleep(aw88166->reset_gpio, 0); + usleep_range(AW88166_1000_US, AW88166_1000_US + 10); + } +} + +static void aw88166_parse_channel_dt(struct aw88166 *aw88166) +{ + struct aw_device *aw_dev = aw88166->aw_pa; + struct device_node *np = aw_dev->dev->of_node; + u32 channel_value; + + of_property_read_u32(np, "awinic,audio-channel", &channel_value); + aw_dev->channel = channel_value; + aw88166->phase_sync = of_property_read_bool(np, "awinic,sync-flag"); +} + +static int aw88166_init(struct aw88166 *aw88166, struct i2c_client *i2c, struct regmap *regmap) +{ + struct aw_device *aw_dev; + unsigned int chip_id; + int ret; + + ret = regmap_read(regmap, AW88166_ID_REG, &chip_id); + if (ret) { + dev_err(&i2c->dev, "%s read chipid error. ret = %d\n", __func__, ret); + return ret; + } + + aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL); + if (!aw_dev) + return -ENOMEM; + aw88166->aw_pa = aw_dev; + + aw_dev->i2c = i2c; + aw_dev->dev = &i2c->dev; + aw_dev->regmap = regmap; + mutex_init(&aw_dev->dsp_lock); + + aw_dev->chip_id = chip_id; + aw_dev->acf = NULL; + aw_dev->prof_info.prof_desc = NULL; + aw_dev->prof_info.count = 0; + aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID; + aw_dev->channel = AW88166_DEV_DEFAULT_CH; + aw_dev->fw_status = AW88166_DEV_FW_FAILED; + + aw_dev->fade_step = AW88166_VOLUME_STEP_DB; + aw_dev->volume_desc.ctl_volume = AW88166_VOL_DEFAULT_VALUE; + + aw88166_parse_channel_dt(aw88166); + + return 0; +} + +static int aw88166_i2c_probe(struct i2c_client *i2c) +{ + struct aw88166 *aw88166; + int ret; + + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) + return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed\n"); + + aw88166 = devm_kzalloc(&i2c->dev, sizeof(*aw88166), GFP_KERNEL); + if (!aw88166) + return -ENOMEM; + + mutex_init(&aw88166->lock); + + i2c_set_clientdata(i2c, aw88166); + + aw88166->reset_gpio = devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(aw88166->reset_gpio)) + return dev_err_probe(&i2c->dev, PTR_ERR(aw88166->reset_gpio), + "reset gpio not defined\n"); + aw88166_hw_reset(aw88166); + + aw88166->regmap = devm_regmap_init_i2c(i2c, &aw88166_remap_config); + if (IS_ERR(aw88166->regmap)) + return dev_err_probe(&i2c->dev, PTR_ERR(aw88166->regmap), + "failed to init regmap\n"); + + /* aw pa init */ + ret = aw88166_init(aw88166, i2c, aw88166->regmap); + if (ret) + return ret; + + return devm_snd_soc_register_component(&i2c->dev, + &soc_codec_dev_aw88166, + aw88166_dai, ARRAY_SIZE(aw88166_dai)); +} + +static const struct i2c_device_id aw88166_i2c_id[] = { + { AW88166_I2C_NAME }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aw88166_i2c_id); + +static struct i2c_driver aw88166_i2c_driver = { + .driver = { + .name = AW88166_I2C_NAME, + }, + .probe = aw88166_i2c_probe, + .id_table = aw88166_i2c_id, +}; +module_i2c_driver(aw88166_i2c_driver); + +MODULE_DESCRIPTION("ASoC AW88166 Smart PA Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/aw88166.h b/sound/soc/codecs/aw88166.h new file mode 100644 index 000000000000..3a53ba0ac625 --- /dev/null +++ b/sound/soc/codecs/aw88166.h @@ -0,0 +1,534 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// aw88166.h -- ALSA SoC AW88166 codec support +// +// Copyright (c) 2025 AWINIC Technology CO., LTD +// +// Author: Weidong Wang +// + +#ifndef __AW88166_H__ +#define __AW88166_H__ + +/* registers list */ +#define AW88166_ID_REG (0x00) +#define AW88166_SYSST_REG (0x01) +#define AW88166_SYSINT_REG (0x02) +#define AW88166_SYSINTM_REG (0x03) +#define AW88166_SYSCTRL_REG (0x04) +#define AW88166_SYSCTRL2_REG (0x05) +#define AW88166_I2SCTRL1_REG (0x06) +#define AW88166_I2SCTRL2_REG (0x07) +#define AW88166_I2SCTRL3_REG (0x08) +#define AW88166_DACCFG1_REG (0x09) +#define AW88166_DACCFG2_REG (0x0A) +#define AW88166_DACCFG3_REG (0x0B) +#define AW88166_DACCFG4_REG (0x0C) +#define AW88166_DACCFG5_REG (0x0D) +#define AW88166_DACCFG6_REG (0x0E) +#define AW88166_DACCFG7_REG (0x0F) +#define AW88166_MPDCFG1_REG (0x10) +#define AW88166_MPDCFG2_REG (0x11) +#define AW88166_MPDCFG3_REG (0x12) +#define AW88166_MPDCFG4_REG (0x13) +#define AW88166_PWMCTRL1_REG (0x14) +#define AW88166_PWMCTRL2_REG (0x15) +#define AW88166_PWMCTRL3_REG (0x16) +#define AW88166_I2SCFG1_REG (0x17) +#define AW88166_DBGCTRL_REG (0x18) +#define AW88166_HAGCST_REG (0x20) +#define AW88166_VBAT_REG (0x21) +#define AW88166_TEMP_REG (0x22) +#define AW88166_PVDD_REG (0x23) +#define AW88166_ISNDAT_REG (0x24) +#define AW88166_I2SINT_REG (0x25) +#define AW88166_I2SCAPCNT_REG (0x26) +#define AW88166_ANASTA1_REG (0x27) +#define AW88166_ANASTA2_REG (0x28) +#define AW88166_ANASTA3_REG (0x29) +#define AW88166_TESTDET_REG (0x2A) +#define AW88166_TESTIN_REG (0x38) +#define AW88166_TESTOUT_REG (0x39) +#define AW88166_MEMTEST_REG (0x3A) +#define AW88166_DSPMADD_REG (0x40) +#define AW88166_DSPMDAT_REG (0x41) +#define AW88166_WDT_REG (0x42) +#define AW88166_ACR1_REG (0x43) +#define AW88166_ACR2_REG (0x44) +#define AW88166_ASR1_REG (0x45) +#define AW88166_ASR2_REG (0x46) +#define AW88166_DSPCFG_REG (0x47) +#define AW88166_ASR3_REG (0x48) +#define AW88166_ASR4_REG (0x49) +#define AW88166_DSPVCALB_REG (0x4A) +#define AW88166_CRCCTRL_REG (0x4B) +#define AW88166_DSPDBG1_REG (0x4C) +#define AW88166_DSPDBG2_REG (0x4D) +#define AW88166_DSPDBG3_REG (0x4E) +#define AW88166_ISNCTRL1_REG (0x50) +#define AW88166_PLLCTRL1_REG (0x51) +#define AW88166_PLLCTRL2_REG (0x52) +#define AW88166_PLLCTRL3_REG (0x53) +#define AW88166_CDACTRL1_REG (0x54) +#define AW88166_CDACTRL2_REG (0x55) +#define AW88166_CDACTRL3_REG (0x56) +#define AW88166_SADCCTRL1_REG (0x57) +#define AW88166_SADCCTRL2_REG (0x58) +#define AW88166_BOPCTRL1_REG (0x59) +#define AW88166_BOPCTRL2_REG (0x5A) +#define AW88166_BOPCTRL3_REG (0x5B) +#define AW88166_BOPCTRL4_REG (0x5C) +#define AW88166_BOPCTRL5_REG (0x5D) +#define AW88166_BOPCTRL6_REG (0x5E) +#define AW88166_BOPCTRL7_REG (0x5F) +#define AW88166_BSTCTRL1_REG (0x60) +#define AW88166_BSTCTRL2_REG (0x61) +#define AW88166_BSTCTRL3_REG (0x62) +#define AW88166_BSTCTRL4_REG (0x63) +#define AW88166_BSTCTRL5_REG (0x64) +#define AW88166_BSTCTRL6_REG (0x65) +#define AW88166_DSMCFG1_REG (0x66) +#define AW88166_DSMCFG2_REG (0x67) +#define AW88166_DSMCFG3_REG (0x68) +#define AW88166_DSMCFG4_REG (0x69) +#define AW88166_DSMCFG5_REG (0x6A) +#define AW88166_DSMCFG6_REG (0x6B) +#define AW88166_DSMCFG7_REG (0x6C) +#define AW88166_DSMCFG8_REG (0x6D) +#define AW88166_TESTCTRL1_REG (0x70) +#define AW88166_TESTCTRL2_REG (0x71) +#define AW88166_EFCTRL1_REG (0x72) +#define AW88166_EFCTRL2_REG (0x73) +#define AW88166_EFWH_REG (0x74) +#define AW88166_EFWM2_REG (0x75) +#define AW88166_EFWM1_REG (0x76) +#define AW88166_EFRH_REG (0x77) +#define AW88166_EFRM2_REG (0x78) +#define AW88166_EFRM1_REG (0x79) +#define AW88166_EFRL_REG (0x7A) +#define AW88166_TM_REG (0x7C) +#define AW88166_TM2_REG (0x7D) + +#define AW88166_REG_MAX (0x7E) +#define AW88166_MUTE_VOL (1023) + +#define AW88166_DSP_CFG_ADDR (0x9B00) +#define AW88166_DSP_REG_CFG_ADPZ_RA (0x9B68) +#define AW88166_DSP_FW_ADDR (0x8980) +#define AW88166_DSP_ROM_CHECK_ADDR (0x1F40) + +#define AW88166_CALI_RE_HBITS_MASK (~(0xFFFF0000)) +#define AW88166_CALI_RE_HBITS_SHIFT (16) + +#define AW88166_CALI_RE_LBITS_MASK (~(0xFFFF)) +#define AW88166_CALI_RE_LBITS_SHIFT (0) + +#define AW88166_I2STXEN_START_BIT (9) +#define AW88166_I2STXEN_BITS_LEN (1) +#define AW88166_I2STXEN_MASK \ + (~(((1<> (shift)) +#define AW88166_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000)) + +#define AW88166_DSP_ODD_NUM_BIT_TEST (0x5555) +#define AW88166_DSP_ROM_CHECK_DATA (0xFF99) + +#define AW88166_DEV_DEFAULT_CH (0) +#define AW88166_DEV_DSP_CHECK_MAX (5) +#define AW88166_MAX_RAM_WRITE_BYTE_SIZE (128) +#define AW_FW_ADDR_LEN (4) +#define AW88166_CRC_CHECK_PASS_VAL (0x4) +#define AW88166_CRC_CFG_BASE_ADDR (0xD80) +#define AW88166_CRC_FW_BASE_ADDR (0x4C0) +#define AW88166_DEV_SYSST_CHECK_MAX (10) +#define AW88166_START_RETRIES (5) +#define AW88166_START_WORK_DELAY_MS (0) +#define FADE_TIME_MAX 100000 +#define FADE_TIME_MIN 0 +#define AW88166_CHIP_ID (0x2066) +#define AW88166_I2C_NAME "aw88166" +#define AW88166_ACF_FILE "aw88166_acf.bin" + +#define AW88166_RATES (SNDRV_PCM_RATE_8000_48000 | \ + SNDRV_PCM_RATE_96000) +#define AW88166_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define AW88166_PROFILE_EXT(xname, profile_info, profile_get, profile_set) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .info = profile_info, \ + .get = profile_get, \ + .put = profile_set, \ +} + +enum { + AW_EF_AND_CHECK = 0, + AW_EF_OR_CHECK, +}; + +enum { + AW88166_DSP_FW_UPDATE_OFF = 0, + AW88166_DSP_FW_UPDATE_ON = 1, +}; + +enum { + AW88166_FORCE_UPDATE_OFF = 0, + AW88166_FORCE_UPDATE_ON = 1, +}; + +enum { + AW88166_1000_US = 1000, + AW88166_2000_US = 2000, + AW88166_3000_US = 3000, + AW88166_4000_US = 4000, +}; + +enum AW88166_DEV_STATUS { + AW88166_DEV_PW_OFF = 0, + AW88166_DEV_PW_ON, +}; + +enum AW88166_DEV_FW_STATUS { + AW88166_DEV_FW_FAILED = 0, + AW88166_DEV_FW_OK, +}; + +enum AW88166_DEV_MEMCLK { + AW88166_DEV_MEMCLK_OSC = 0, + AW88166_DEV_MEMCLK_PLL = 1, +}; + +enum AW88166_DEV_DSP_CFG { + AW88166_DEV_DSP_WORK = 0, + AW88166_DEV_DSP_BYPASS = 1, +}; + +enum { + AW88166_DSP_16_DATA = 0, + AW88166_DSP_32_DATA = 1, +}; + +enum { + AW88166_SYNC_START = 0, + AW88166_ASYNC_START, +}; + +enum { + AW88166_RECORD_SEC_DATA = 0, + AW88166_RECOVERY_SEC_DATA = 1, +}; + +#endif From 3fec903f2cb18805b1ef22a0e310498020c1f15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Thu, 6 Mar 2025 16:52:15 -0300 Subject: [PATCH 489/651] ASoC: dt-bindings: mediatek,mt8188-mt6359: Add mediatek,accdet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a mediatek,accdet phandle property to allow getting a reference to the MT6359 ACCDET block, which is responsible for detecting jack insertion/removal. Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Rob Herring (Arm) Signed-off-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250306-mt8188-accdet-v3-1-7828e835ff4b@collabora.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml index 8c77e7f68ad7..76d5a437dc8f 100644 --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml @@ -40,6 +40,14 @@ properties: hardware that provides additional audio functionalities if present. The AFE will link to ADSP when the phandle is provided. + mediatek,accdet: + $ref: /schemas/types.yaml#/definitions/phandle + description: + The phandle to the MT6359 accessory detection block, which detects audio + jack insertion and removal. This property should only be present if the + accdet block is actually wired to the audio jack pins and to be used for + jack detection. + patternProperties: "^dai-link-[0-9]+$": type: object From cf536e2622e2b0a60c99e799995b6e9acf539c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Thu, 6 Mar 2025 16:52:16 -0300 Subject: [PATCH 490/651] ASoC: mediatek: common: Handle mediatek,accdet property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle the optional mediatek,accdet property. When present, retrieve the sound component from its phandle, so the machine sound driver can use it to register the audio jack and initialize the MT6359 ACCDET for jack detection. Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250306-mt8188-accdet-v3-2-7828e835ff4b@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/common/mtk-soc-card.h | 1 + .../mediatek/common/mtk-soundcard-driver.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sound/soc/mediatek/common/mtk-soc-card.h b/sound/soc/mediatek/common/mtk-soc-card.h index 3f6e24dd22df..a1d2794ac1f7 100644 --- a/sound/soc/mediatek/common/mtk-soc-card.h +++ b/sound/soc/mediatek/common/mtk-soc-card.h @@ -16,6 +16,7 @@ struct mtk_soc_card_data { const struct mtk_sof_priv *sof_priv; struct list_head sof_dai_link_list; struct mtk_platform_card_data *card_data; + struct snd_soc_component *accdet; void *mach_priv; }; diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.c b/sound/soc/mediatek/common/mtk-soundcard-driver.c index f4314dddc460..713a368f79cf 100644 --- a/sound/soc/mediatek/common/mtk-soundcard-driver.c +++ b/sound/soc/mediatek/common/mtk-soundcard-driver.c @@ -8,6 +8,7 @@ #include #include +#include #include #include "mtk-dsp-sof-common.h" @@ -192,7 +193,9 @@ EXPORT_SYMBOL_GPL(mtk_soundcard_common_capture_ops); int mtk_soundcard_common_probe(struct platform_device *pdev) { - struct device_node *platform_node, *adsp_node; + struct device_node *platform_node, *adsp_node, *accdet_node; + struct snd_soc_component *accdet_comp; + struct platform_device *accdet_pdev; const struct mtk_soundcard_pdata *pdata; struct mtk_soc_card_data *soc_card_data; struct snd_soc_dai_link *orig_dai_link, *dai_link; @@ -250,6 +253,20 @@ int mtk_soundcard_common_probe(struct platform_device *pdev) soc_card_data->card_data->jacks = jacks; + accdet_node = of_parse_phandle(pdev->dev.of_node, "mediatek,accdet", 0); + if (accdet_node) { + accdet_pdev = of_find_device_by_node(accdet_node); + if (accdet_pdev) { + accdet_comp = snd_soc_lookup_component(&accdet_pdev->dev, NULL); + if (accdet_comp) + soc_card_data->accdet = accdet_comp; + else + dev_err(&pdev->dev, "No sound component found from mediatek,accdet property\n"); + } else { + dev_err(&pdev->dev, "No device found from mediatek,accdet property\n"); + } + } + platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); if (!platform_node) return dev_err_probe(&pdev->dev, -EINVAL, From 0116a7d84b32537a10d9bea1fd1bfc06577ef527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Thu, 6 Mar 2025 16:52:17 -0300 Subject: [PATCH 491/651] ASoC: mediatek: mt6359: Add stub for mt6359_accdet_enable_jack_detect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a stub for mt6359_accdet_enable_jack_detect() to prevent linker failures in the machine sound drivers calling it when CONFIG_SND_SOC_MT6359_ACCDET is not enabled. Suggested-by: AngeloGioacchino Del Regno Signed-off-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250306-mt8188-accdet-v3-3-7828e835ff4b@collabora.com Signed-off-by: Mark Brown --- sound/soc/codecs/mt6359-accdet.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/mt6359-accdet.h b/sound/soc/codecs/mt6359-accdet.h index c234f2f4276a..78ada3a5bfae 100644 --- a/sound/soc/codecs/mt6359-accdet.h +++ b/sound/soc/codecs/mt6359-accdet.h @@ -123,6 +123,15 @@ struct mt6359_accdet { struct workqueue_struct *jd_workqueue; }; +#if IS_ENABLED(CONFIG_SND_SOC_MT6359_ACCDET) int mt6359_accdet_enable_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); +#else +static inline int +mt6359_accdet_enable_jack_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack) +{ + return -EOPNOTSUPP; +} +#endif #endif From f35d834d67adbbf121ee4397376d9eac21d99a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Thu, 6 Mar 2025 16:52:18 -0300 Subject: [PATCH 492/651] ASoC: mediatek: mt8188-mt6359: Add accdet headset jack detect support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable headset jack detection for MT8188 platforms that use the MT6359 ACCDET block for it, indicated by the mediatek,accdet property in DT. For those platforms, register a jack and initialize the ACCDET block to report jack events through it. Co-developed-by: Zoran Zhan Signed-off-by: Zoran Zhan Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Nícolas F. R. A. Prado Link: https://patch.msgid.link/20250306-mt8188-accdet-v3-4-7828e835ff4b@collabora.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-mt6359.c | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index 420b1427b71d..20dc9470ba76 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -17,6 +17,7 @@ #include "mt8188-afe-common.h" #include "../../codecs/nau8825.h" #include "../../codecs/mt6359.h" +#include "../../codecs/mt6359-accdet.h" #include "../../codecs/rt5682.h" #include "../common/mtk-afe-platform-driver.h" #include "../common/mtk-soundcard-driver.h" @@ -271,6 +272,17 @@ static struct snd_soc_jack_pin nau8825_jack_pins[] = { }, }; +static struct snd_soc_jack_pin mt8188_headset_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = { SOC_DAPM_PIN_SWITCH("Ext Spk"), }; @@ -506,6 +518,35 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) return 0; } +static int mt8188_mt6359_accdet_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HEADSET]; + int ret; + + if (!soc_card_data->accdet) + return 0; + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, mt8188_headset_jack_pins, + ARRAY_SIZE(mt8188_headset_jack_pins)); + if (ret) { + dev_err(rtd->dev, "Headset Jack create failed: %d\n", ret); + return ret; + } + + ret = mt6359_accdet_enable_jack_detect(soc_card_data->accdet, jack); + if (ret) { + dev_err(rtd->dev, "Headset Jack enable failed: %d\n", ret); + return ret; + } + + return 0; +} + static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *cmpnt_codec = @@ -518,6 +559,8 @@ static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd) /* mtkaif calibration */ mt8188_mt6359_mtkaif_calibration(rtd); + mt8188_mt6359_accdet_init(rtd); + return 0; } From 98dba9dab5d9af3c25e61a5d751bc943fec3f918 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 12 Mar 2025 14:31:50 +0100 Subject: [PATCH 493/651] ASoC: pcm1681: Drop unused include This driver includes the legacy GPIO header but does not use any symbols from it so drop the include. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250312-pcm-codecs-v1-1-41ffc4f8fc5c@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/pcm1681.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index fc152496d5dc..a1ec881d7084 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include From ef5aa8bd22372dd67b7fe19613b86181cd765af8 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 12 Mar 2025 14:31:51 +0100 Subject: [PATCH 494/651] ASoC: pcm3008: Convert to GPIO descriptors This converts the PCM3008 driver to look up the GPIO lines using descriptors. Apparently there are no in-tree users of the platform data struct, so users need to adopt. New users can associate the GPIO lines with the platform device "pcm3008-codec". Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250312-pcm-codecs-v1-2-41ffc4f8fc5c@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3008.c | 61 ++++++++++++++++++++------------------ sound/soc/codecs/pcm3008.h | 19 ------------ 2 files changed, 32 insertions(+), 48 deletions(-) delete mode 100644 sound/soc/codecs/pcm3008.h diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 09c6c1326833..d3d2e7f40170 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -22,17 +22,22 @@ #include #include -#include "pcm3008.h" +struct pcm3008 { + struct gpio_desc *dem0_pin; + struct gpio_desc *dem1_pin; + struct gpio_desc *pdad_pin; + struct gpio_desc *pdda_pin; +}; static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct pcm3008_setup_data *setup = component->dev->platform_data; + struct pcm3008 *pcm = component->dev->platform_data; - gpio_set_value_cansleep(setup->pdda_pin, - SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(pcm->pdda_pin, + SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -42,10 +47,10 @@ static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct pcm3008_setup_data *setup = component->dev->platform_data; + struct pcm3008 *pcm = component->dev->platform_data; - gpio_set_value_cansleep(setup->pdad_pin, - SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(pcm->pdad_pin, + SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -106,11 +111,13 @@ static const struct snd_soc_component_driver soc_component_dev_pcm3008 = { static int pcm3008_codec_probe(struct platform_device *pdev) { - struct pcm3008_setup_data *setup = pdev->dev.platform_data; - int ret; + struct device *dev = &pdev->dev; + struct pcm3008 *pcm; - if (!setup) - return -EINVAL; + pcm = devm_kzalloc(dev, sizeof(*pcm), GFP_KERNEL); + if (!pcm) + return -ENOMEM; + platform_set_drvdata(pdev, pcm); /* DEM1 DEM0 DE-EMPHASIS_MODE * Low Low De-emphasis 44.1 kHz ON @@ -120,30 +127,26 @@ static int pcm3008_codec_probe(struct platform_device *pdev) */ /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */ - ret = devm_gpio_request_one(&pdev->dev, setup->dem0_pin, - GPIOF_OUT_INIT_HIGH, "codec_dem0"); - if (ret != 0) - return ret; + pcm->dem0_pin = devm_gpiod_get(dev, "dem0", GPIOD_OUT_HIGH); + if (IS_ERR(pcm->dem0_pin)) + return PTR_ERR(pcm->dem0_pin); /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */ - ret = devm_gpio_request_one(&pdev->dev, setup->dem1_pin, - GPIOF_OUT_INIT_LOW, "codec_dem1"); - if (ret != 0) - return ret; + pcm->dem1_pin = devm_gpiod_get(dev, "dem1", GPIOD_OUT_LOW); + if (IS_ERR(pcm->dem1_pin)) + return PTR_ERR(pcm->dem1_pin); /* Configure PDAD GPIO. */ - ret = devm_gpio_request_one(&pdev->dev, setup->pdad_pin, - GPIOF_OUT_INIT_LOW, "codec_pdad"); - if (ret != 0) - return ret; + pcm->pdad_pin = devm_gpiod_get(dev, "pdad", GPIOD_OUT_LOW); + if (IS_ERR(pcm->pdad_pin)) + return PTR_ERR(pcm->pdad_pin); /* Configure PDDA GPIO. */ - ret = devm_gpio_request_one(&pdev->dev, setup->pdda_pin, - GPIOF_OUT_INIT_LOW, "codec_pdda"); - if (ret != 0) - return ret; + pcm->pdda_pin = devm_gpiod_get(dev, "pdda", GPIOD_OUT_LOW); + if (IS_ERR(pcm->pdda_pin)) + return PTR_ERR(pcm->pdda_pin); - return devm_snd_soc_register_component(&pdev->dev, + return devm_snd_soc_register_component(dev, &soc_component_dev_pcm3008, &pcm3008_dai, 1); } diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h deleted file mode 100644 index f7f4fbbd89db..000000000000 --- a/sound/soc/codecs/pcm3008.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * PCM3008 ALSA SoC Layer - * - * Author: Hugo Villeneuve - * Copyright (C) 2008 Lyrtech inc - */ - -#ifndef __LINUX_SND_SOC_PCM3008_H -#define __LINUX_SND_SOC_PCM3008_H - -struct pcm3008_setup_data { - unsigned dem0_pin; - unsigned dem1_pin; - unsigned pdad_pin; - unsigned pdda_pin; -}; - -#endif From 17fdf318f5fbe5c27353ae917c0c5a2899d9c259 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 12 Mar 2025 14:31:52 +0100 Subject: [PATCH 495/651] ASoC: pcm6240: Drop bogus code handling IRQ as GPIO The current code for the IRQ in pcm6240 makes no sense: it looks up an IRQ with of_irq_get(), treat it as a GPIO by issuing gpio_request(), gpio_direction_input() and gpio_to_irq() on it. This is just wrong, if the device tree assigns the IRQ from a GPIO number this is just incorrect: it is clearly stated that GPIO providers and IRQ providers are orthogonal. It is possible to look up an IRQ to a corresponding GPIO line but this is taking an IRQ and pretending it's a GPIO, which is just semantically wrong. Drop the offending code and treat the IRQ that we get from the device tree as any other IRQ, see for example other codec drivers. The DT bindings for this codec does not have any in-tree DTS files, which may explain why things are weird. As a bonus, this moves the driver away from the legacy include. Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20250312-pcm-codecs-v1-3-41ffc4f8fc5c@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/pcm6240.c | 28 +++++++--------------------- sound/soc/codecs/pcm6240.h | 7 +------ 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/sound/soc/codecs/pcm6240.c b/sound/soc/codecs/pcm6240.c index 4ff39e0b95b2..b2bd2f172ae7 100644 --- a/sound/soc/codecs/pcm6240.c +++ b/sound/soc/codecs/pcm6240.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include @@ -2035,10 +2035,8 @@ static const struct regmap_config pcmdevice_i2c_regmap = { static void pcmdevice_remove(struct pcmdevice_priv *pcm_dev) { - if (gpio_is_valid(pcm_dev->irq_info.gpio)) { - gpio_free(pcm_dev->irq_info.gpio); - free_irq(pcm_dev->irq_info.nmb, pcm_dev); - } + if (pcm_dev->irq) + free_irq(pcm_dev->irq, pcm_dev); mutex_destroy(&pcm_dev->codec_lock); } @@ -2109,7 +2107,7 @@ static int pcmdevice_i2c_probe(struct i2c_client *i2c) ndev = 1; dev_addrs[0] = i2c->addr; } - pcm_dev->irq_info.gpio = of_irq_get(np, 0); + pcm_dev->irq = of_irq_get(np, 0); for (i = 0; i < ndev; i++) pcm_dev->addr[i] = dev_addrs[i]; @@ -2132,22 +2130,10 @@ static int pcmdevice_i2c_probe(struct i2c_client *i2c) if (pcm_dev->chip_id == PCM1690) goto skip_interrupt; - if (gpio_is_valid(pcm_dev->irq_info.gpio)) { - dev_dbg(pcm_dev->dev, "irq-gpio = %d", pcm_dev->irq_info.gpio); - - ret = gpio_request(pcm_dev->irq_info.gpio, "PCMDEV-IRQ"); - if (!ret) { - int gpio = pcm_dev->irq_info.gpio; - - gpio_direction_input(gpio); - pcm_dev->irq_info.nmb = gpio_to_irq(gpio); - - } else - dev_err(pcm_dev->dev, "%s: GPIO %d request error\n", - __func__, pcm_dev->irq_info.gpio); + if (pcm_dev->irq) { + dev_dbg(pcm_dev->dev, "irq = %d", pcm_dev->irq); } else - dev_err(pcm_dev->dev, "Looking up irq-gpio failed %d\n", - pcm_dev->irq_info.gpio); + dev_err(pcm_dev->dev, "No irq provided\n"); skip_interrupt: ret = devm_snd_soc_register_component(&i2c->dev, diff --git a/sound/soc/codecs/pcm6240.h b/sound/soc/codecs/pcm6240.h index 1e125bb97286..2d8f9e798139 100644 --- a/sound/soc/codecs/pcm6240.h +++ b/sound/soc/codecs/pcm6240.h @@ -208,11 +208,6 @@ struct pcmdevice_regbin { struct pcmdevice_config_info **cfg_info; }; -struct pcmdevice_irqinfo { - int gpio; - int nmb; -}; - struct pcmdevice_priv { struct snd_soc_component *component; struct i2c_client *client; @@ -221,7 +216,7 @@ struct pcmdevice_priv { struct gpio_desc *hw_rst; struct regmap *regmap; struct pcmdevice_regbin regbin; - struct pcmdevice_irqinfo irq_info; + int irq; unsigned int addr[PCMDEVICE_MAX_I2C_DEVICES]; unsigned int chip_id; int cur_conf; From 988adcb73669a4015974da9057d43226ddc1aa9d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 12 Mar 2025 17:22:00 +0000 Subject: [PATCH 496/651] ASoC: SDCA: Tidy up initialization write parsing Slightly neaten up the initialization write code to overlay a struct rather than shifting the pointer along manually. This also removes the Sparse warning: sound/soc/sdca/sdca_functions.c:233:36: warning: cast to restricted __le32 Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250312172205.4152686-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sdca/sdca_functions.c | 47 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 091d55abe109..133cbde17ef4 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -186,14 +187,18 @@ void sdca_lookup_functions(struct sdw_slave *slave) } EXPORT_SYMBOL_NS(sdca_lookup_functions, "SND_SOC_SDCA"); +struct raw_init_write { + __le32 addr; + u8 val; +} __packed; + static int find_sdca_init_table(struct device *dev, struct fwnode_handle *function_node, struct sdca_function_data *function) { + struct raw_init_write *raw __free(kfree) = NULL; struct sdca_init_write *init_write; - int write_size = sizeof(init_write->addr) + sizeof(init_write->val); - u8 *init_list, *init_iter; - int num_init_writes; + int i, num_init_writes; num_init_writes = fwnode_property_count_u8(function_node, "mipi-sdca-function-initialization-table"); @@ -203,7 +208,7 @@ static int find_sdca_init_table(struct device *dev, dev_err(dev, "%pfwP: failed to read initialization table: %d\n", function_node, num_init_writes); return num_init_writes; - } else if (num_init_writes % write_size != 0) { + } else if (num_init_writes % sizeof(*raw) != 0) { dev_err(dev, "%pfwP: init table size invalid\n", function_node); return -EINVAL; } else if (num_init_writes > SDCA_MAX_INIT_COUNT) { @@ -211,34 +216,28 @@ static int find_sdca_init_table(struct device *dev, return -EINVAL; } - init_write = devm_kcalloc(dev, num_init_writes / write_size, - sizeof(*init_write), GFP_KERNEL); - if (!init_write) - return -ENOMEM; - - init_list = kcalloc(num_init_writes, sizeof(*init_list), GFP_KERNEL); - if (!init_list) + raw = kzalloc(num_init_writes, GFP_KERNEL); + if (!raw) return -ENOMEM; fwnode_property_read_u8_array(function_node, "mipi-sdca-function-initialization-table", - init_list, num_init_writes); + (u8 *)raw, num_init_writes); + + num_init_writes /= sizeof(*raw); + + init_write = devm_kcalloc(dev, num_init_writes, sizeof(*init_write), GFP_KERNEL); + if (!init_write) + return -ENOMEM; + + for (i = 0; i < num_init_writes; i++) { + init_write[i].addr = le32_to_cpu(raw[i].addr); + init_write[i].val = raw[i].val; + } function->num_init_table = num_init_writes; function->init_table = init_write; - for (init_iter = init_list; init_iter < init_list + num_init_writes;) { - u32 *addr = (u32 *)init_iter; - - init_write->addr = le32_to_cpu(*addr); - init_iter += sizeof(init_write->addr); - - init_write->val = *init_iter; - init_iter += sizeof(init_write->val); - } - - kfree(init_list); - return 0; } From 0d16daa9405ef7de5c278183d4079013f39a51ac Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 12 Mar 2025 17:22:01 +0000 Subject: [PATCH 497/651] ASoC: SDCA: Use __free() to manage local buffers Use the cleanup.h helpers to manage some local buffers, this cleans up the error paths a little. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250312172205.4152686-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sdca/sdca_functions.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 133cbde17ef4..4ee98d8fe89e 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -913,9 +913,9 @@ static int find_sdca_entity_pde(struct device *dev, { static const int mult_delay = 3; struct sdca_entity_pde *power = &entity->pde; + u32 *delay_list __free(kfree) = NULL; struct sdca_pde_delay *delays; int num_delays; - u32 *delay_list; int i, j; num_delays = fwnode_property_count_u32(entity_node, @@ -962,8 +962,6 @@ static int find_sdca_entity_pde(struct device *dev, power->num_max_delay = num_delays; power->max_delay = delays; - kfree(delay_list); - return 0; } @@ -1022,8 +1020,8 @@ static int find_sdca_entities(struct device *dev, struct fwnode_handle *function_node, struct sdca_function_data *function) { + u32 *entity_list __free(kfree) = NULL; struct sdca_entity *entities; - u32 *entity_list; int num_entities; int i, ret; @@ -1054,8 +1052,6 @@ static int find_sdca_entities(struct device *dev, for (i = 0; i < num_entities; i++) entities[i].id = entity_list[i]; - kfree(entity_list); - /* now read subproperties */ for (i = 0; i < num_entities; i++) { char entity_property[SDCA_PROPERTY_LENGTH]; @@ -1170,8 +1166,8 @@ static int find_sdca_entity_connection_pde(struct device *dev, struct sdca_entity *entity) { struct sdca_entity_pde *power = &entity->pde; + u32 *managed_list __free(kfree) = NULL; struct sdca_entity **managed; - u32 *managed_list; int num_managed; int i; @@ -1205,15 +1201,12 @@ static int find_sdca_entity_connection_pde(struct device *dev, 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; @@ -1453,9 +1446,9 @@ static int find_sdca_clusters(struct device *dev, struct fwnode_handle *function_node, struct sdca_function_data *function) { + u32 *cluster_list __free(kfree) = NULL; struct sdca_cluster *clusters; int num_clusters; - u32 *cluster_list; int i, ret; num_clusters = fwnode_property_count_u32(function_node, "mipi-sdca-cluster-id-list"); @@ -1484,8 +1477,6 @@ static int find_sdca_clusters(struct device *dev, for (i = 0; i < num_clusters; i++) clusters[i].id = cluster_list[i]; - kfree(cluster_list); - /* now read subproperties */ for (i = 0; i < num_clusters; i++) { char cluster_property[SDCA_PROPERTY_LENGTH]; From 49680c9f13b64c13e79e1312c7616d0ab9775e4a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 12 Mar 2025 17:22:02 +0000 Subject: [PATCH 498/651] ASoC: SDCA: Allow naming of imp def controls Implementation defined controls will not be present in the large list of known controls for SDCA. The driver should not return an error for these, because it is perfectly legal to have implementation defined controls. Update the handling to instead generate a generic name. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250312172205.4152686-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sdca/sdca_functions.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 4ee98d8fe89e..1e36dd20d7ab 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -241,7 +241,8 @@ static int find_sdca_init_table(struct device *dev, return 0; } -static const char *find_sdca_control_label(const struct sdca_entity *entity, +static const char *find_sdca_control_label(struct device *dev, + const struct sdca_entity *entity, const struct sdca_control *control) { switch (SDCA_CTL_TYPE(entity->type, control->sel)) { @@ -530,7 +531,7 @@ static const char *find_sdca_control_label(const struct sdca_entity *entity, case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_SDCA_VERSION): return SDCA_CTL_DEVICE_SDCA_VERSION_NAME; default: - return NULL; + return devm_kasprintf(dev, GFP_KERNEL, "Imp-Def %#x", control->sel); } } @@ -739,12 +740,9 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti if (!ret) control->interrupt_position = tmp; - control->label = find_sdca_control_label(entity, control); - if (!control->label) { - dev_err(dev, "%s: control %#x: name not found\n", - entity->label, control->sel); - return -EINVAL; - } + control->label = find_sdca_control_label(dev, entity, control); + if (!control->label) + return -ENOMEM; control->nbits = find_sdca_control_bits(entity, control); From 2a4667f3d589524bd2fbfe4f7dc0e2f12b832e10 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 12 Mar 2025 17:22:03 +0000 Subject: [PATCH 499/651] ASoC: SDCA: Add type flag for Controls SDCA Controls come in a variety of data formats, to simplify later parsing work out this data type as the control is parsed and stash it for later use. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250312172205.4152686-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 23 +++++ sound/soc/sdca/sdca_functions.c | 173 ++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index f001ab643fed..ca0376903e87 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -600,6 +600,27 @@ enum sdca_entity0_controls { #define SDCA_CTL_DEVICE_VERSION_NAME "Device Version" #define SDCA_CTL_DEVICE_SDCA_VERSION_NAME "Device SDCA Version" +/** + * enum sdca_control_datatype - SDCA Control Data Types + * + * Data Types as described in the SDCA specification v1.0 section + * 7.3. + */ +enum sdca_control_datatype { + SDCA_CTL_DATATYPE_ONEBIT, + SDCA_CTL_DATATYPE_INTEGER, + SDCA_CTL_DATATYPE_SPEC_ENCODED_VALUE, + SDCA_CTL_DATATYPE_BCD, + SDCA_CTL_DATATYPE_Q7P8DB, + SDCA_CTL_DATATYPE_BYTEINDEX, + SDCA_CTL_DATATYPE_POSTURENUMBER, + SDCA_CTL_DATATYPE_DP_INDEX, + SDCA_CTL_DATATYPE_BITINDEX, + SDCA_CTL_DATATYPE_BITMAP, + SDCA_CTL_DATATYPE_GUID, + SDCA_CTL_DATATYPE_IMPDEF, +}; + /** * enum sdca_access_mode - SDCA Control access mode * @@ -653,6 +674,7 @@ struct sdca_control_range { * @cn_list: A bitmask showing the valid Control Numbers within this Control, * Control Numbers typically represent channels. * @range: Buffer describing valid range of values for the Control. + * @type: Format of the data in the Control. * @mode: Access mode of the Control. * @layers: Bitmask of access layers of the Control. * @deferrable: Indicates if the access to the Control can be deferred. @@ -669,6 +691,7 @@ struct sdca_control { u64 cn_list; struct sdca_control_range range; + enum sdca_control_datatype type; enum sdca_access_mode mode; u8 layers; diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 1e36dd20d7ab..0cc25fb9679b 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -603,6 +603,178 @@ static unsigned int find_sdca_control_bits(const struct sdca_entity *entity, } } +static enum sdca_control_datatype +find_sdca_control_datatype(const struct sdca_entity *entity, + const struct sdca_control *control) +{ + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { + case SDCA_CTL_TYPE_S(XU, BYPASS): + case SDCA_CTL_TYPE_S(MFPU, BYPASS): + case SDCA_CTL_TYPE_S(FU, MUTE): + case SDCA_CTL_TYPE_S(FU, AGC): + case SDCA_CTL_TYPE_S(FU, BASS_BOOST): + case SDCA_CTL_TYPE_S(FU, LOUDNESS): + return SDCA_CTL_DATATYPE_ONEBIT; + case SDCA_CTL_TYPE_S(IT, LATENCY): + case SDCA_CTL_TYPE_S(OT, LATENCY): + case SDCA_CTL_TYPE_S(MU, LATENCY): + case SDCA_CTL_TYPE_S(SU, LATENCY): + case SDCA_CTL_TYPE_S(FU, LATENCY): + case SDCA_CTL_TYPE_S(XU, LATENCY): + case SDCA_CTL_TYPE_S(CRU, LATENCY): + case SDCA_CTL_TYPE_S(UDMPU, LATENCY): + case SDCA_CTL_TYPE_S(MFPU, LATENCY): + case SDCA_CTL_TYPE_S(SMPU, LATENCY): + case SDCA_CTL_TYPE_S(SAPU, LATENCY): + case SDCA_CTL_TYPE_S(PPU, LATENCY): + case SDCA_CTL_TYPE_S(SU, SELECTOR): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_0): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_1): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_2): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_3): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_4): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_5): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_6): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_7): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_8): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_9): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_10): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_11): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_12): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_13): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_14): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_15): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_16): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_17): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_18): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_19): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_20): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_21): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_22): + case SDCA_CTL_TYPE_S(UDMPU, OPAQUESET_23): + case SDCA_CTL_TYPE_S(SAPU, PROTECTION_MODE): + case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_PREAMBLE): + case SDCA_CTL_TYPE_S(XU, FDL_HOST_REQUEST): + case SDCA_CTL_TYPE_S(XU, XU_ID): + case SDCA_CTL_TYPE_S(CX, CLOCK_SELECT): + case SDCA_CTL_TYPE_S(TG, TONE_DIVIDER): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_MANUFACTURER_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_MANUFACTURER_ID): + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_PART_ID): + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(XU, FDL_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SPE, AUTHTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SPE, AUTHRX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(MFPU, AE_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SMPU, HIST_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SMPU, DTODTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SMPU, DTODRX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SAPU, DTODTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(SAPU, DTODRX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(HIDE, HIDTX_MESSAGELENGTH): + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGEOFFSET): + case SDCA_CTL_TYPE_S(HIDE, HIDRX_MESSAGELENGTH): + return SDCA_CTL_DATATYPE_INTEGER; + case SDCA_CTL_TYPE_S(IT, MIC_BIAS): + case SDCA_CTL_TYPE_S(SMPU, HIST_BUFFER_MODE): + case SDCA_CTL_TYPE_S(PDE, REQUESTED_PS): + case SDCA_CTL_TYPE_S(PDE, ACTUAL_PS): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_TYPE): + return SDCA_CTL_DATATYPE_SPEC_ENCODED_VALUE; + case SDCA_CTL_TYPE_S(XU, XU_VERSION): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_SDCA_VERSION): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_VERSION): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_EXTENSION_VERSION): + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_VERSION): + case SDCA_CTL_TYPE_S(ENTITY_0, DEVICE_SDCA_VERSION): + return SDCA_CTL_DATATYPE_BCD; + case SDCA_CTL_TYPE_S(FU, CHANNEL_VOLUME): + case SDCA_CTL_TYPE_S(FU, GAIN): + case SDCA_CTL_TYPE_S(MU, MIXER): + case SDCA_CTL_TYPE_S(PPU, HORIZONTALBALANCE): + case SDCA_CTL_TYPE_S(PPU, VERTICALBALANCE): + case SDCA_CTL_TYPE_S(MFPU, ULTRASOUND_LEVEL): + case SDCA_CTL_TYPE_S(UDMPU, ACOUSTIC_ENERGY_LEVEL_MONITOR): + case SDCA_CTL_TYPE_S(UDMPU, ULTRASOUND_LOOP_GAIN): + return SDCA_CTL_DATATYPE_Q7P8DB; + case SDCA_CTL_TYPE_S(IT, USAGE): + case SDCA_CTL_TYPE_S(OT, USAGE): + case SDCA_CTL_TYPE_S(IT, CLUSTERINDEX): + case SDCA_CTL_TYPE_S(CRU, CLUSTERINDEX): + case SDCA_CTL_TYPE_S(UDMPU, CLUSTERINDEX): + case SDCA_CTL_TYPE_S(MFPU, CLUSTERINDEX): + case SDCA_CTL_TYPE_S(MFPU, CENTER_FREQUENCY_INDEX): + case SDCA_CTL_TYPE_S(MFPU, AE_NUMBER): + case SDCA_CTL_TYPE_S(SAPU, OPAQUESETREQ_INDEX): + case SDCA_CTL_TYPE_S(XU, FDL_SET_INDEX): + case SDCA_CTL_TYPE_S(CS, SAMPLERATEINDEX): + case SDCA_CTL_TYPE_S(GE, SELECTED_MODE): + case SDCA_CTL_TYPE_S(GE, DETECTED_MODE): + return SDCA_CTL_DATATYPE_BYTEINDEX; + case SDCA_CTL_TYPE_S(PPU, POSTURENUMBER): + return SDCA_CTL_DATATYPE_POSTURENUMBER; + case SDCA_CTL_TYPE_S(IT, DATAPORT_SELECTOR): + case SDCA_CTL_TYPE_S(OT, DATAPORT_SELECTOR): + return SDCA_CTL_DATATYPE_DP_INDEX; + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_READY): + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_ENABLE): + case SDCA_CTL_TYPE_S(MFPU, ALGORITHM_PREPARE): + case SDCA_CTL_TYPE_S(SAPU, PROTECTION_STATUS): + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_ENABLE): + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_STATUS): + case SDCA_CTL_TYPE_S(SMPU, TRIGGER_READY): + case SDCA_CTL_TYPE_S(SPE, PRIVACY_POLICY): + case SDCA_CTL_TYPE_S(SPE, PRIVACY_OWNER): + return SDCA_CTL_DATATYPE_BITINDEX; + case SDCA_CTL_TYPE_S(IT, KEEP_ALIVE): + case SDCA_CTL_TYPE_S(OT, KEEP_ALIVE): + case SDCA_CTL_TYPE_S(IT, NDAI_STREAM): + case SDCA_CTL_TYPE_S(OT, NDAI_STREAM): + case SDCA_CTL_TYPE_S(IT, NDAI_CATEGORY): + case SDCA_CTL_TYPE_S(OT, NDAI_CATEGORY): + case SDCA_CTL_TYPE_S(IT, NDAI_CODINGTYPE): + case SDCA_CTL_TYPE_S(OT, NDAI_CODINGTYPE): + case SDCA_CTL_TYPE_S(IT, NDAI_PACKETTYPE): + case SDCA_CTL_TYPE_S(OT, NDAI_PACKETTYPE): + case SDCA_CTL_TYPE_S(SMPU, HIST_ERROR): + case SDCA_CTL_TYPE_S(XU, FDL_STATUS): + case SDCA_CTL_TYPE_S(CS, CLOCK_VALID): + case SDCA_CTL_TYPE_S(SPE, PRIVACY_LOCKSTATE): + case SDCA_CTL_TYPE_S(ENTITY_0, COMMIT_GROUP_MASK): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_STATUS): + case SDCA_CTL_TYPE_S(ENTITY_0, FUNCTION_ACTION): + case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER): + case SDCA_CTL_TYPE_S(SPE, AUTHTX_CURRENTOWNER): + case SDCA_CTL_TYPE_S(SPE, AUTHRX_CURRENTOWNER): + case SDCA_CTL_TYPE_S(MFPU, AE_CURRENTOWNER): + case SDCA_CTL_TYPE_S(SMPU, HIST_CURRENTOWNER): + case SDCA_CTL_TYPE_S(SMPU, DTODTX_CURRENTOWNER): + case SDCA_CTL_TYPE_S(SMPU, DTODRX_CURRENTOWNER): + case SDCA_CTL_TYPE_S(SAPU, DTODTX_CURRENTOWNER): + case SDCA_CTL_TYPE_S(SAPU, DTODRX_CURRENTOWNER): + case SDCA_CTL_TYPE_S(HIDE, HIDTX_CURRENTOWNER): + case SDCA_CTL_TYPE_S(HIDE, HIDRX_CURRENTOWNER): + return SDCA_CTL_DATATYPE_BITMAP; + case SDCA_CTL_TYPE_S(IT, MATCHING_GUID): + case SDCA_CTL_TYPE_S(OT, MATCHING_GUID): + case SDCA_CTL_TYPE_S(ENTITY_0, MATCHING_GUID): + return SDCA_CTL_DATATYPE_GUID; + default: + return SDCA_CTL_DATATYPE_IMPDEF; + } +} + static int find_sdca_control_range(struct device *dev, struct fwnode_handle *control_node, struct sdca_control_range *range) @@ -744,6 +916,7 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti if (!control->label) return -ENOMEM; + control->type = find_sdca_control_datatype(entity, control); control->nbits = find_sdca_control_bits(entity, control); dev_info(dev, "%s: %s: control %#x mode %#x layers %#x cn %#llx int %d value %#x %s\n", From 1bcbb88bedb17804491e692a3f1a38223e09152c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 12 Mar 2025 17:22:04 +0000 Subject: [PATCH 500/651] ASoC: SDCA: Add SDCA Control Range data access helper SDCA Ranges are two dimensional arrays of data associated with controls, add a helper to provide an x,y access mechanism to the data and a helper to locate a specific value inside a range. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250312172205.4152686-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index ca0376903e87..d7489e3c7e47 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -1136,6 +1136,25 @@ struct sdca_function_data { unsigned int busy_max_delay; }; +static inline u32 sdca_range(struct sdca_control_range *range, + unsigned int col, unsigned int row) +{ + return range->data[(row * range->cols) + col]; +} + +static inline u32 sdca_range_search(struct sdca_control_range *range, + int search_col, int value, int result_col) +{ + int i; + + for (i = 0; i < range->rows; i++) { + if (sdca_range(range, search_col, i) == value) + return sdca_range(range, result_col, i); + } + + return 0; +} + int sdca_parse_function(struct device *dev, struct sdca_function_desc *desc, struct sdca_function_data *function); From d1cd13f80dc6c8525c539a28d4eb1df913d542de Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 12 Mar 2025 17:22:05 +0000 Subject: [PATCH 501/651] ASoC: SDCA: Add support for GE Entity properties Add support for parsing the Group Entity properties from DisCo/ACPI. Group Entities allow control of several other Entities, typically Selector Units, from a single control. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250312172205.4152686-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/sdca_function.h | 48 ++++++++++++ sound/soc/sdca/sdca_functions.c | 129 ++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h index d7489e3c7e47..253654568a41 100644 --- a/include/sound/sdca_function.h +++ b/include/sound/sdca_function.h @@ -44,6 +44,11 @@ struct sdca_function_desc; */ #define SDCA_MAX_DELAY_COUNT 256 +/* + * Sanity check on size of affected controls data, can be expanded if needed. + */ +#define SDCA_MAX_AFFECTED_COUNT 2048 + /** * enum sdca_function_type - SDCA Function Type codes * @SDCA_FUNCTION_TYPE_SMART_AMP: Amplifier with protection features. @@ -927,11 +932,51 @@ enum sdca_entity_type { SDCA_ENTITY_TYPE_HIDE = 0x31, }; +/** + * struct sdca_ge_control - control entry in the affected controls list + * @id: Entity ID of the Control affected. + * @sel: Control Selector of the Control affected. + * @cn: Control Number of the Control affected. + * @val: Value written to Control for this Mode. + */ +struct sdca_ge_control { + int id; + int sel; + int cn; + int val; +}; + +/** + * struct sdca_ge_mode - mode entry in the affected controls list + * @controls: Dynamically allocated array of controls written for this Mode. + * @num_controls: Number of controls written in this Mode. + * @val: GE Selector Mode value. + */ +struct sdca_ge_mode { + struct sdca_ge_control *controls; + int num_controls; + int val; +}; + +/** + * struct sdca_entity_ge - information specific to Group Entities + * @kctl: ALSA control pointer that can be used by linked Entities. + * @modes: Dynamically allocated array of Modes and the Controls written + * in each mode. + * @num_modes: Number of Modes. + */ +struct sdca_entity_ge { + struct snd_kcontrol_new *kctl; + struct sdca_ge_mode *modes; + int num_modes; +}; + /** * struct sdca_entity - information for one SDCA Entity * @label: String such as "OT 12". * @id: Identifier used for addressing. * @type: Type code for the Entity. + * @group: Pointer to Group Entity controlling this one, NULL if N/A. * @sources: Dynamically allocated array pointing to each input Entity * connected to this Entity. * @controls: Dynamically allocated array of Controls. @@ -940,12 +985,14 @@ enum sdca_entity_type { * @iot: Input/Output Terminal specific Entity properties. * @cs: Clock Source specific Entity properties. * @pde: Power Domain Entity specific Entity properties. + * @ge: Group Entity specific Entity properties. */ struct sdca_entity { const char *label; int id; enum sdca_entity_type type; + struct sdca_entity *group; struct sdca_entity **sources; struct sdca_control *controls; int num_sources; @@ -954,6 +1001,7 @@ struct sdca_entity { struct sdca_entity_iot iot; struct sdca_entity_cs cs; struct sdca_entity_pde pde; + struct sdca_entity_ge ge; }; }; diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 0cc25fb9679b..c8efdc5301b5 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -1136,6 +1136,92 @@ static int find_sdca_entity_pde(struct device *dev, return 0; } +struct raw_ge_mode { + u8 val; + u8 num_controls; + struct { + u8 id; + u8 sel; + u8 cn; + __le32 val; + } __packed controls[] __counted_by(num_controls); +} __packed; + +static int find_sdca_entity_ge(struct device *dev, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + struct sdca_entity_ge *group = &entity->ge; + u8 *affected_list __free(kfree) = NULL; + u8 *affected_iter; + int num_affected; + int i, j; + + num_affected = fwnode_property_count_u8(entity_node, + "mipi-sdca-ge-selectedmode-controls-affected"); + if (!num_affected || num_affected == -EINVAL) { + return 0; + } else if (num_affected < 0) { + dev_err(dev, "%s: failed to read affected controls: %d\n", + entity->label, num_affected); + return num_affected; + } else if (num_affected > SDCA_MAX_AFFECTED_COUNT) { + dev_err(dev, "%s: maximum affected controls size exceeded\n", + entity->label); + return -EINVAL; + } + + affected_list = kcalloc(num_affected, sizeof(*affected_list), GFP_KERNEL); + if (!affected_list) + return -ENOMEM; + + fwnode_property_read_u8_array(entity_node, + "mipi-sdca-ge-selectedmode-controls-affected", + affected_list, num_affected); + + group->num_modes = *affected_list; + affected_iter = affected_list + 1; + + group->modes = devm_kcalloc(dev, group->num_modes, sizeof(*group->modes), + GFP_KERNEL); + if (!group->modes) + return -ENOMEM; + + for (i = 0; i < group->num_modes; i++) { + struct raw_ge_mode *raw = (struct raw_ge_mode *)affected_iter; + struct sdca_ge_mode *mode = &group->modes[i]; + + affected_iter += sizeof(*raw); + if (affected_iter > affected_list + num_affected) + goto bad_list; + + mode->val = raw->val; + mode->num_controls = raw->num_controls; + + affected_iter += mode->num_controls * sizeof(raw->controls[0]); + if (affected_iter > affected_list + num_affected) + goto bad_list; + + mode->controls = devm_kcalloc(dev, mode->num_controls, + sizeof(*mode->controls), GFP_KERNEL); + if (!mode->controls) + return -ENOMEM; + + for (j = 0; j < mode->num_controls; j++) { + mode->controls[j].id = raw->controls[j].id; + mode->controls[j].sel = raw->controls[j].sel; + mode->controls[j].cn = raw->controls[j].cn; + mode->controls[j].val = le32_to_cpu(raw->controls[j].val); + } + } + + return 0; + +bad_list: + dev_err(dev, "%s: malformed affected controls list\n", entity->label); + return -EINVAL; +} + static int find_sdca_entity(struct device *dev, struct fwnode_handle *function_node, struct fwnode_handle *entity_node, @@ -1174,6 +1260,9 @@ static int find_sdca_entity(struct device *dev, case SDCA_ENTITY_TYPE_PDE: ret = find_sdca_entity_pde(dev, entity_node, entity); break; + case SDCA_ENTITY_TYPE_GE: + ret = find_sdca_entity_ge(dev, entity_node, entity); + break; default: break; } @@ -1384,6 +1473,42 @@ static int find_sdca_entity_connection_pde(struct device *dev, return 0; } +static int find_sdca_entity_connection_ge(struct device *dev, + struct sdca_function_data *function, + struct fwnode_handle *entity_node, + struct sdca_entity *entity) +{ + int i, j; + + for (i = 0; i < entity->ge.num_modes; i++) { + struct sdca_ge_mode *mode = &entity->ge.modes[i]; + + for (j = 0; j < mode->num_controls; j++) { + struct sdca_ge_control *affected = &mode->controls[j]; + struct sdca_entity *managed; + + managed = find_sdca_entity_by_id(function, affected->id); + if (!managed) { + dev_err(dev, "%s: failed to find entity with id %#x\n", + entity->label, affected->id); + return -EINVAL; + } + + if (managed->group && managed->group != entity) { + dev_err(dev, + "%s: entity controlled by two groups %s, %s\n", + managed->label, managed->group->label, + entity->label); + return -EINVAL; + } + + managed->group = entity; + } + } + + return 0; +} + static int find_sdca_entity_connection(struct device *dev, struct sdca_function_data *function, struct fwnode_handle *entity_node, @@ -1404,6 +1529,10 @@ static int find_sdca_entity_connection(struct device *dev, ret = find_sdca_entity_connection_pde(dev, function, entity_node, entity); break; + case SDCA_ENTITY_TYPE_GE: + ret = find_sdca_entity_connection_ge(dev, function, + entity_node, entity); + break; default: ret = 0; break; From 1458fae110c85d98d356496e4eb120f6de0e3a7e Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Wed, 12 Mar 2025 11:35:09 +0800 Subject: [PATCH 502/651] ASoC: ti: davinci-i2s: remove unnecessary NULL check before clk_disable_unprepare() clk_disable_unprepare() already checks NULL by using IS_ERR_OR_NULL. Remove unneeded NULL check for dev->ext_clk here. Signed-off-by: Chen Ni Link: https://patch.msgid.link/20250312033509.1235268-1-nichen@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/ti/davinci-i2s.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c index d682b98d6848..059967f0e632 100644 --- a/sound/soc/ti/davinci-i2s.c +++ b/sound/soc/ti/davinci-i2s.c @@ -892,8 +892,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) err_unregister_component: snd_soc_unregister_component(&pdev->dev); err_disable_ext_clk: - if (dev->ext_clk) - clk_disable_unprepare(dev->ext_clk); + clk_disable_unprepare(dev->ext_clk); err_disable_clk: clk_disable_unprepare(dev->clk); @@ -908,8 +907,7 @@ static void davinci_i2s_remove(struct platform_device *pdev) clk_disable_unprepare(dev->clk); - if (dev->ext_clk) - clk_disable_unprepare(dev->ext_clk); + clk_disable_unprepare(dev->ext_clk); } static const struct of_device_id davinci_i2s_match[] __maybe_unused = { From f37ab219a3336ef787ce4babd20510f060f6f48d Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Wed, 12 Mar 2025 11:26:00 +0800 Subject: [PATCH 503/651] ASoC: mt8365: remove unnecessary NULL check before clk_disable_unprepare() clk_disable_unprepare() already checks NULL by using IS_ERR_OR_NULL. Remove unneeded NULL check for clk here. Signed-off-by: Chen Ni Link: https://patch.msgid.link/20250312032600.1235158-1-nichen@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8365/mt8365-afe-clk.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-clk.c b/sound/soc/mediatek/mt8365/mt8365-afe-clk.c index 8a0af2ea8546..7078c01ba19b 100644 --- a/sound/soc/mediatek/mt8365/mt8365-afe-clk.c +++ b/sound/soc/mediatek/mt8365/mt8365-afe-clk.c @@ -49,8 +49,7 @@ int mt8365_afe_init_audio_clk(struct mtk_base_afe *afe) void mt8365_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk) { - if (clk) - clk_disable_unprepare(clk); + clk_disable_unprepare(clk); } int mt8365_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, From 0ec6bd16705fe21d6429d6b8f7981eae2142bba8 Mon Sep 17 00:00:00 2001 From: Chenyuan Yang Date: Mon, 10 Mar 2025 20:57:14 -0500 Subject: [PATCH 504/651] ASoC: sma1307: Add NULL check in sma1307_setting_loaded() All varibale allocated by kzalloc and devm_kzalloc could be NULL. Multiple pointer checks and their cleanup are added. This issue is found by our static analysis tool Signed-off-by: Chenyuan Yang Link: https://patch.msgid.link/20250311015714.1333857-1-chenyuan0y@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/sma1307.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/soc/codecs/sma1307.c b/sound/soc/codecs/sma1307.c index dac17da9cedd..f5c303d4bb62 100644 --- a/sound/soc/codecs/sma1307.c +++ b/sound/soc/codecs/sma1307.c @@ -1723,6 +1723,11 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil } data = kzalloc(fw->size, GFP_KERNEL); + if (!data) { + release_firmware(fw); + sma1307->set.status = false; + return; + } size = fw->size >> 2; memcpy(data, fw->data, fw->size); @@ -1736,6 +1741,12 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil sma1307->set.header = devm_kzalloc(sma1307->dev, sma1307->set.header_size, GFP_KERNEL); + if (!sma1307->set.header) { + kfree(data); + sma1307->set.status = false; + return; + } + memcpy(sma1307->set.header, data, sma1307->set.header_size * sizeof(int)); @@ -1751,6 +1762,13 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil sma1307->set.def = devm_kzalloc(sma1307->dev, sma1307->set.def_size * sizeof(int), GFP_KERNEL); + if (!sma1307->set.def) { + kfree(data); + kfree(sma1307->set.header); + sma1307->set.status = false; + return; + } + memcpy(sma1307->set.def, &data[sma1307->set.header_size], sma1307->set.def_size * sizeof(int)); @@ -1763,6 +1781,16 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil = devm_kzalloc(sma1307->dev, sma1307->set.mode_size * 2 * sizeof(int), GFP_KERNEL); + if (!sma1307->set.mode_set[i]) { + kfree(data); + kfree(sma1307->set.header); + kfree(sma1307->set.def); + for (int j = 0; j < i; j++) + kfree(sma1307->set.mode_set[j]); + sma1307->set.status = false; + return; + } + for (int j = 0; j < sma1307->set.mode_size; j++) { sma1307->set.mode_set[i][2 * j] = data[offset + ((num_mode + 1) * j)]; From f1d742c35b659fb0122da0a8ff09ad9309cb29d8 Mon Sep 17 00:00:00 2001 From: Ritu Chaudhary Date: Tue, 11 Mar 2025 06:20:10 +0000 Subject: [PATCH 505/651] ASoC: tegra: Use non-atomic timeout for ADX status register ADX startup() callback uses atomic poll timeout on ADX status register. This is unnecessary because: - The startup() callback itself is non-atomic. - The subsequent timeout call in the same function already uses a non-atomic version. Using atomic version can hog CPU when it is not really needed, so replace it with non-atomic version. Fixes: a99ab6f395a9e ("ASoC: tegra: Add Tegra210 based ADX driver") Signed-off-by: Ritu Chaudhary Signed-off-by: Sheetal Link: https://patch.msgid.link/20250311062010.33412-1-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_adx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c index 0aa93b948378..3c10e09976ad 100644 --- a/sound/soc/tegra/tegra210_adx.c +++ b/sound/soc/tegra/tegra210_adx.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -// SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. +// SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. // All rights reserved. // // tegra210_adx.c - Tegra210 ADX driver @@ -57,8 +57,8 @@ static int tegra210_adx_startup(struct snd_pcm_substream *substream, int err; /* Ensure if ADX status is disabled */ - err = regmap_read_poll_timeout_atomic(adx->regmap, TEGRA210_ADX_STATUS, - val, !(val & 0x1), 10, 10000); + err = regmap_read_poll_timeout(adx->regmap, TEGRA210_ADX_STATUS, + val, !(val & 0x1), 10, 10000); if (err < 0) { dev_err(dai->dev, "failed to stop ADX, err = %d\n", err); return err; From 9aa499f28ef8aeda82556dd204bc42dc96e2f1e4 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Wed, 12 Mar 2025 11:43:37 +0800 Subject: [PATCH 506/651] ASoC: tlv320adc3xxx: remove unnecessary NULL check before clk_disable_unprepare() clk_disable_unprepare() already checks NULL by using IS_ERR_OR_NULL. Remove unneeded NULL check for adc3xxx->mclk here. Signed-off-by: Chen Ni Link: https://patch.msgid.link/20250312034337.1235378-1-nichen@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adc3xxx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c index 1a50ff675244..191e067ed1c9 100644 --- a/sound/soc/codecs/tlv320adc3xxx.c +++ b/sound/soc/codecs/tlv320adc3xxx.c @@ -1493,8 +1493,7 @@ static void adc3xxx_i2c_remove(struct i2c_client *client) { struct adc3xxx *adc3xxx = i2c_get_clientdata(client); - if (adc3xxx->mclk) - clk_disable_unprepare(adc3xxx->mclk); + clk_disable_unprepare(adc3xxx->mclk); adc3xxx_free_gpio(adc3xxx); snd_soc_unregister_component(&client->dev); } From 02026aabaa8225bd7dfdcb8ae106453e002cb0a8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Mar 2025 13:11:43 +0300 Subject: [PATCH 507/651] ASoC: amd: acp: Fix leak in acp_pci_probe() There needs to be some cleanup on this error path. We can't just return directly. Fixes: aaf7a668bb38 ("ASoC: amd: acp: Add new interrupt handle callbacks in acp_common_hw_ops") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/3dad80cb-e177-45aa-97ac-df9c98a47d94@stanley.mountain Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 9322379cb36f..123524f90d6c 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -183,7 +183,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id IRQF_SHARED, "ACP_I2S_IRQ", chip); if (ret) { dev_err(&pci->dev, "ACP I2S IRQ request failed %d\n", ret); - return ret; + goto de_init; } check_acp_config(pci, chip); From ede6445d5405edb418c05582d46d12687b632236 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 10 Mar 2025 02:02:11 +0000 Subject: [PATCH 508/651] ASoC: soc-pcm: tidyup function name to snd_soc_dpcm_be_can_xxx() We have similar but different function names snd_soc_dpcm_fe_can_xxx() snd_soc_dpcm_be_can_xxx() snd_soc_dpcm_can_be_xxx() ~~~~~~ Let's unified these to can_xx Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87plip7ie4.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 403edd2fd8cf..4308a6cbb2e6 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -36,7 +36,7 @@ static inline int _soc_pcm_ret(struct snd_soc_pcm_runtime *rtd, /* is the current PCM operation for this FE ? */ #if 0 -static int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream) +static int snd_soc_dpcm_can_fe_update(struct snd_soc_pcm_runtime *fe, int stream) { if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) return 1; @@ -45,7 +45,7 @@ static int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream #endif /* is the current PCM operation for this BE ? */ -static int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe, +static int snd_soc_dpcm_can_be_update(struct snd_soc_pcm_runtime *fe, struct snd_soc_pcm_runtime *be, int stream) { if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) || @@ -1632,7 +1632,7 @@ void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream, return; /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; if (be->dpcm[stream].users == 0) { @@ -1682,7 +1682,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) } /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* first time the dpcm is open ? */ @@ -2007,7 +2007,7 @@ void dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) snd_soc_dpcm_get_substream(be, stream); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* only free hw when no longer used - check all FEs */ @@ -2073,7 +2073,7 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) be_substream = snd_soc_dpcm_get_substream(be, stream); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* copy params for each dpcm */ @@ -2118,7 +2118,7 @@ unwind: be = dpcm->be; be_substream = snd_soc_dpcm_get_substream(be, stream); - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; /* only allow hw_free() if no connected FEs are running */ @@ -2188,7 +2188,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, snd_pcm_stream_lock_irqsave_nested(be_substream, flags); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) goto next; dev_dbg(be->dev, "ASoC: trigger BE %s cmd %d\n", @@ -2465,7 +2465,7 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) snd_soc_dpcm_get_substream(be, stream); /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; if (!snd_soc_dpcm_can_be_prepared(fe, be, stream)) @@ -2623,7 +2623,7 @@ disconnect: struct snd_soc_pcm_runtime *be = dpcm->be; /* is this op for this BE ? */ - if (!snd_soc_dpcm_be_can_update(fe, be, stream)) + if (!snd_soc_dpcm_can_be_update(fe, be, stream)) continue; if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE || From 3e330acf4efd63876d673c046cd073a1d4ed57a8 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Wed, 26 Feb 2025 16:50:50 +0800 Subject: [PATCH 509/651] ASoC: codecs: wcd937x: fix a potential memory leak in wcd937x_soc_codec_probe() When snd_soc_dapm_new_controls() or snd_soc_dapm_add_routes() fails, wcd937x_soc_codec_probe() returns without releasing 'wcd937x->clsh_info', which is allocated by wcd_clsh_ctrl_alloc. Add wcd_clsh_ctrl_free() to prevent potential memory leak. Fixes: 313e978df7fc ("ASoC: codecs: wcd937x: add audio routing and Kconfig") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Link: https://patch.msgid.link/20250226085050.3584898-1-haoxiang_li2024@163.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd937x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c index e8d3fddbc7b1..ff8bb01edf42 100644 --- a/sound/soc/codecs/wcd937x.c +++ b/sound/soc/codecs/wcd937x.c @@ -2571,6 +2571,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component) ARRAY_SIZE(wcd9375_dapm_widgets)); if (ret < 0) { dev_err(component->dev, "Failed to add snd_ctls\n"); + wcd_clsh_ctrl_free(wcd937x->clsh_info); return ret; } @@ -2578,6 +2579,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component) ARRAY_SIZE(wcd9375_audio_map)); if (ret < 0) { dev_err(component->dev, "Failed to add routes\n"); + wcd_clsh_ctrl_free(wcd937x->clsh_info); return ret; } } From 3cab1fc85f9d381de6767fe97299eecdb8c868fa Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Wed, 12 Mar 2025 15:26:35 +0800 Subject: [PATCH 510/651] ASoC: cs35l56: Remove redundant 'flush_workqueue()' calls 'destroy_workqueue()' already drains the queue before destroying it, so there is no need to flush it explicitly. Remove the redundant 'flush_workqueue()' calls. This was generated with coccinelle: @@ expression E; @@ -flush_workqueue(E); destroy_workqueue(E); Signed-off-by: Chen Ni Link: https://patch.msgid.link/20250312072635.1429870-1-nichen@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l56.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 735a1e487c6f..b3158a84b87a 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -1441,7 +1441,6 @@ void cs35l56_remove(struct cs35l56_private *cs35l56) if (cs35l56->base.irq) devm_free_irq(cs35l56->base.dev, cs35l56->base.irq, &cs35l56->base); - flush_workqueue(cs35l56->dsp_wq); destroy_workqueue(cs35l56->dsp_wq); pm_runtime_dont_use_autosuspend(cs35l56->base.dev); From 3c423a68643cceb69c4e4244b5b4d09df2a19c79 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 6 Mar 2025 12:10:13 -0500 Subject: [PATCH 511/651] ASoC: dt-bindings: fsl,sai: Add i.MX94 support Add compatible string "fsl,imx94-sai" for the i.MX94 chip, which is backward compatible with i.MX95. Set it to fall back to "fsl,imx95-sai". Signed-off-by: Frank Li Acked-by: Conor Dooley Link: https://patch.msgid.link/20250306171013.243332-1-Frank.Li@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl,sai.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl,sai.yaml b/Documentation/devicetree/bindings/sound/fsl,sai.yaml index a5d9c246cc47..e16e52c9f58c 100644 --- a/Documentation/devicetree/bindings/sound/fsl,sai.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,sai.yaml @@ -41,6 +41,10 @@ properties: - fsl,imx93-sai - fsl,imx95-sai - fsl,vf610-sai + - items: + - enum: + - fsl,imx94-sai + - const: fsl,imx95-sai reg: maxItems: 1 From 309b367eafc8e162603cd29189da6db770411fea Mon Sep 17 00:00:00 2001 From: keenplify Date: Sat, 15 Mar 2025 19:16:17 +0800 Subject: [PATCH 512/651] ASoC: amd: Add DMI quirk for ACP6X mic support Some AMD laptops with ACP6X do not expose the DMIC properly on Linux. Adding a DMI quirk enables mic functionality. Similar to Bugzilla #218402, this issue affects multiple users. Link: https://bugzilla.kernel.org/show_bug.cgi?id=219853 Signed-off-by: keenplify Link: https://patch.msgid.link/20250315111617.12194-1-keenplify@gmail.com Signed-off-by: Mark Brown --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index a7637056972a..bd3808f98ec9 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -584,6 +584,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "pang13"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."), + DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7UCX"), + } + }, {} }; From 958448bfee503d24e706605f01b98d3ce547d1bd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:23 +0100 Subject: [PATCH 513/651] ASoC: au1x: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Use the new DEFINE_SIMPLE_DEV_PM_OPS() macro instead of open code together with pm_ptr(), which allows us dropping CONFIG_PM ifdefs. Merely a cleanup, there should be no actual code change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-2-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/au1x/i2sc.c | 17 +++-------------- sound/soc/au1x/psc-ac97.c | 17 +++-------------- sound/soc/au1x/psc-i2s.c | 17 +++-------------- 3 files changed, 9 insertions(+), 42 deletions(-) diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 7d296f29dade..57735004f416 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -279,7 +279,6 @@ static void au1xi2s_drvremove(struct platform_device *pdev) WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ } -#ifdef CONFIG_PM static int au1xi2s_drvsuspend(struct device *dev) { struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev); @@ -294,23 +293,13 @@ static int au1xi2s_drvresume(struct device *dev) return 0; } -static const struct dev_pm_ops au1xi2sc_pmops = { - .suspend = au1xi2s_drvsuspend, - .resume = au1xi2s_drvresume, -}; - -#define AU1XI2SC_PMOPS (&au1xi2sc_pmops) - -#else - -#define AU1XI2SC_PMOPS NULL - -#endif +static DEFINE_SIMPLE_DEV_PM_OPS(au1xi2sc_pmops, au1xi2s_drvsuspend, + au1xi2s_drvresume); static struct platform_driver au1xi2s_driver = { .driver = { .name = "alchemy-i2sc", - .pm = AU1XI2SC_PMOPS, + .pm = pm_ptr(&au1xi2sc_pmops), }, .probe = au1xi2s_drvprobe, .remove = au1xi2s_drvremove, diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 8a59a50978b9..94698e08a513 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -436,7 +436,6 @@ static void au1xpsc_ac97_drvremove(struct platform_device *pdev) au1xpsc_ac97_workdata = NULL; /* MDEV */ } -#ifdef CONFIG_PM static int au1xpsc_ac97_drvsuspend(struct device *dev) { struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); @@ -467,23 +466,13 @@ static int au1xpsc_ac97_drvresume(struct device *dev) return 0; } -static const struct dev_pm_ops au1xpscac97_pmops = { - .suspend = au1xpsc_ac97_drvsuspend, - .resume = au1xpsc_ac97_drvresume, -}; - -#define AU1XPSCAC97_PMOPS &au1xpscac97_pmops - -#else - -#define AU1XPSCAC97_PMOPS NULL - -#endif +static DEFINE_SIMPLE_DEV_PM_OPS(au1xpscac97_pmops, au1xpsc_ac97_drvsuspend, + au1xpsc_ac97_drvresume); static struct platform_driver au1xpsc_ac97_driver = { .driver = { .name = "au1xpsc_ac97", - .pm = AU1XPSCAC97_PMOPS, + .pm = pm_ptr(&au1xpscac97_pmops), }, .probe = au1xpsc_ac97_drvprobe, .remove = au1xpsc_ac97_drvremove, diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index bee013555e7a..bf59105fcb7a 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -354,7 +354,6 @@ static void au1xpsc_i2s_drvremove(struct platform_device *pdev) wmb(); /* drain writebuffer */ } -#ifdef CONFIG_PM static int au1xpsc_i2s_drvsuspend(struct device *dev) { struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); @@ -385,23 +384,13 @@ static int au1xpsc_i2s_drvresume(struct device *dev) return 0; } -static const struct dev_pm_ops au1xpsci2s_pmops = { - .suspend = au1xpsc_i2s_drvsuspend, - .resume = au1xpsc_i2s_drvresume, -}; - -#define AU1XPSCI2S_PMOPS &au1xpsci2s_pmops - -#else - -#define AU1XPSCI2S_PMOPS NULL - -#endif +static DEFINE_SIMPLE_DEV_PM_OPS(au1xpsci2s_pmops, au1xpsc_i2s_drvsuspend, + au1xpsc_i2s_drvresume); static struct platform_driver au1xpsc_i2s_driver = { .driver = { .name = "au1xpsc_i2s", - .pm = AU1XPSCI2S_PMOPS, + .pm = pm_ptr(&au1xpsci2s_pmops), }, .probe = au1xpsc_i2s_drvprobe, .remove = au1xpsc_i2s_drvremove, From 5f3aeb44694fbd6ebc8790cfcf157f2f7f072207 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:24 +0100 Subject: [PATCH 514/651] ASoC: ak4375: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS () and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-3-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/ak4375.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/ak4375.c b/sound/soc/codecs/ak4375.c index 3ee5a5c3c5fe..452559d8c97b 100644 --- a/sound/soc/codecs/ak4375.c +++ b/sound/soc/codecs/ak4375.c @@ -438,7 +438,7 @@ static int ak4375_power_on(struct ak4375_priv *ak4375) return 0; } -static int __maybe_unused ak4375_runtime_suspend(struct device *dev) +static int ak4375_runtime_suspend(struct device *dev) { struct ak4375_priv *ak4375 = dev_get_drvdata(dev); @@ -448,7 +448,7 @@ static int __maybe_unused ak4375_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused ak4375_runtime_resume(struct device *dev) +static int ak4375_runtime_resume(struct device *dev) { struct ak4375_priv *ak4375 = dev_get_drvdata(dev); int ret; @@ -490,9 +490,8 @@ static const struct ak4375_drvdata ak4375_drvdata = { }; static const struct dev_pm_ops ak4375_pm = { - SET_RUNTIME_PM_OPS(ak4375_runtime_suspend, ak4375_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(ak4375_runtime_suspend, ak4375_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static int ak4375_i2c_probe(struct i2c_client *i2c) @@ -594,7 +593,7 @@ MODULE_DEVICE_TABLE(of, ak4375_of_match); static struct i2c_driver ak4375_i2c_driver = { .driver = { .name = "ak4375", - .pm = &ak4375_pm, + .pm = pm_ptr(&ak4375_pm), .of_match_table = ak4375_of_match, }, .probe = ak4375_i2c_probe, From 9f9c8e9064ea8ceb13540a283f08550c097bb673 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:25 +0100 Subject: [PATCH 515/651] ASoC: ak4458: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes and CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-4-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/ak4458.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c index d472d9952628..5f3a68dfe7bd 100644 --- a/sound/soc/codecs/ak4458.c +++ b/sound/soc/codecs/ak4458.c @@ -639,8 +639,7 @@ static void ak4458_reset(struct ak4458_priv *ak4458, bool active) } } -#ifdef CONFIG_PM -static int __maybe_unused ak4458_runtime_suspend(struct device *dev) +static int ak4458_runtime_suspend(struct device *dev) { struct ak4458_priv *ak4458 = dev_get_drvdata(dev); @@ -656,7 +655,7 @@ static int __maybe_unused ak4458_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused ak4458_runtime_resume(struct device *dev) +static int ak4458_runtime_resume(struct device *dev) { struct ak4458_priv *ak4458 = dev_get_drvdata(dev); int ret; @@ -678,7 +677,6 @@ static int __maybe_unused ak4458_runtime_resume(struct device *dev) return regcache_sync(ak4458->regmap); } -#endif /* CONFIG_PM */ static const struct snd_soc_component_driver soc_codec_dev_ak4458 = { .controls = ak4458_snd_controls, @@ -727,9 +725,8 @@ static const struct ak4458_drvdata ak4497_drvdata = { }; static const struct dev_pm_ops ak4458_pm = { - SET_RUNTIME_PM_OPS(ak4458_runtime_suspend, ak4458_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(ak4458_runtime_suspend, ak4458_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static int ak4458_i2c_probe(struct i2c_client *i2c) @@ -805,7 +802,7 @@ MODULE_DEVICE_TABLE(of, ak4458_of_match); static struct i2c_driver ak4458_i2c_driver = { .driver = { .name = "ak4458", - .pm = &ak4458_pm, + .pm = pm_ptr(&ak4458_pm), .of_match_table = ak4458_of_match, }, .probe = ak4458_i2c_probe, From 5ef209dcdc3fe8f9661a80af4c8ed7a2326c9206 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:26 +0100 Subject: [PATCH 516/651] ASoC: ak5558: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-5-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/ak5558.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c index 6c767609f95d..683f3e472f50 100644 --- a/sound/soc/codecs/ak5558.c +++ b/sound/soc/codecs/ak5558.c @@ -342,7 +342,7 @@ static void ak5558_remove(struct snd_soc_component *component) ak5558_reset(ak5558, true); } -static int __maybe_unused ak5558_runtime_suspend(struct device *dev) +static int ak5558_runtime_suspend(struct device *dev) { struct ak5558_priv *ak5558 = dev_get_drvdata(dev); @@ -354,7 +354,7 @@ static int __maybe_unused ak5558_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused ak5558_runtime_resume(struct device *dev) +static int ak5558_runtime_resume(struct device *dev) { struct ak5558_priv *ak5558 = dev_get_drvdata(dev); int ret; @@ -376,9 +376,8 @@ static int __maybe_unused ak5558_runtime_resume(struct device *dev) } static const struct dev_pm_ops ak5558_pm = { - SET_RUNTIME_PM_OPS(ak5558_runtime_suspend, ak5558_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(ak5558_runtime_suspend, ak5558_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static const struct snd_soc_component_driver soc_codec_dev_ak5558 = { @@ -495,7 +494,7 @@ static struct i2c_driver ak5558_i2c_driver = { .driver = { .name = "ak5558", .of_match_table = of_match_ptr(ak5558_i2c_dt_ids), - .pm = &ak5558_pm, + .pm = pm_ptr(&ak5558_pm), }, .probe = ak5558_i2c_probe, .remove = ak5558_i2c_remove, From 5b73cae57a02ff461c260e68193ce973062cc0bb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:27 +0100 Subject: [PATCH 517/651] ASoC: cs35l32: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-6-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l32.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 6d78fa953c89..0bb4bdb3deec 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -504,7 +504,6 @@ static void cs35l32_i2c_remove(struct i2c_client *i2c_client) gpiod_set_value_cansleep(cs35l32->reset_gpio, 0); } -#ifdef CONFIG_PM static int cs35l32_runtime_suspend(struct device *dev) { struct cs35l32_private *cs35l32 = dev_get_drvdata(dev); @@ -543,11 +542,9 @@ static int cs35l32_runtime_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops cs35l32_runtime_pm = { - SET_RUNTIME_PM_OPS(cs35l32_runtime_suspend, cs35l32_runtime_resume, - NULL) + RUNTIME_PM_OPS(cs35l32_runtime_suspend, cs35l32_runtime_resume, NULL) }; static const struct of_device_id cs35l32_of_match[] = { @@ -567,7 +564,7 @@ MODULE_DEVICE_TABLE(i2c, cs35l32_id); static struct i2c_driver cs35l32_i2c_driver = { .driver = { .name = "cs35l32", - .pm = &cs35l32_runtime_pm, + .pm = pm_ptr(&cs35l32_runtime_pm), .of_match_table = cs35l32_of_match, }, .id_table = cs35l32_id, From 7d1d8f90e456e2945cd3a1a4a429fdb634ec6f42 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:28 +0100 Subject: [PATCH 518/651] ASoC: cs35l33: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-7-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l33.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 02a420659a33..c927592f90c9 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -853,7 +853,7 @@ static const struct regmap_config cs35l33_regmap = { .use_single_write = true, }; -static int __maybe_unused cs35l33_runtime_resume(struct device *dev) +static int cs35l33_runtime_resume(struct device *dev) { struct cs35l33_private *cs35l33 = dev_get_drvdata(dev); int ret; @@ -891,7 +891,7 @@ err: return ret; } -static int __maybe_unused cs35l33_runtime_suspend(struct device *dev) +static int cs35l33_runtime_suspend(struct device *dev) { struct cs35l33_private *cs35l33 = dev_get_drvdata(dev); @@ -909,9 +909,7 @@ static int __maybe_unused cs35l33_runtime_suspend(struct device *dev) } static const struct dev_pm_ops cs35l33_pm_ops = { - SET_RUNTIME_PM_OPS(cs35l33_runtime_suspend, - cs35l33_runtime_resume, - NULL) + RUNTIME_PM_OPS(cs35l33_runtime_suspend, cs35l33_runtime_resume, NULL) }; static int cs35l33_get_hg_data(const struct device_node *np, @@ -1273,7 +1271,7 @@ MODULE_DEVICE_TABLE(i2c, cs35l33_id); static struct i2c_driver cs35l33_i2c_driver = { .driver = { .name = "cs35l33", - .pm = &cs35l33_pm_ops, + .pm = pm_ptr(&cs35l33_pm_ops), .of_match_table = cs35l33_of_match, }, From 1d6128f56c01a417ee3c9d80b4c205da6399d661 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:29 +0100 Subject: [PATCH 519/651] ASoC: cs35l34: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-8-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l34.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 6d098bfd38f6..a5a8075598ff 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -1116,7 +1116,7 @@ static void cs35l34_i2c_remove(struct i2c_client *client) cs35l34->core_supplies); } -static int __maybe_unused cs35l34_runtime_resume(struct device *dev) +static int cs35l34_runtime_resume(struct device *dev) { struct cs35l34_private *cs35l34 = dev_get_drvdata(dev); int ret; @@ -1149,7 +1149,7 @@ err: return ret; } -static int __maybe_unused cs35l34_runtime_suspend(struct device *dev) +static int cs35l34_runtime_suspend(struct device *dev) { struct cs35l34_private *cs35l34 = dev_get_drvdata(dev); @@ -1165,9 +1165,7 @@ static int __maybe_unused cs35l34_runtime_suspend(struct device *dev) } static const struct dev_pm_ops cs35l34_pm_ops = { - SET_RUNTIME_PM_OPS(cs35l34_runtime_suspend, - cs35l34_runtime_resume, - NULL) + RUNTIME_PM_OPS(cs35l34_runtime_suspend, cs35l34_runtime_resume, NULL) }; static const struct of_device_id cs35l34_of_match[] = { @@ -1185,7 +1183,7 @@ MODULE_DEVICE_TABLE(i2c, cs35l34_id); static struct i2c_driver cs35l34_i2c_driver = { .driver = { .name = "cs35l34", - .pm = &cs35l34_pm_ops, + .pm = pm_ptr(&cs35l34_pm_ops), .of_match_table = cs35l34_of_match, }, From fd24b93ebaa1be78bf683a6a0599856eda367155 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:30 +0100 Subject: [PATCH 520/651] ASoC: cs4234: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-9-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs4234.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index df160db5bbb5..dda7f5b4f2fb 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -860,7 +860,7 @@ static void cs4234_i2c_remove(struct i2c_client *i2c_client) cs4234_shutdown(cs4234); } -static int __maybe_unused cs4234_runtime_resume(struct device *dev) +static int cs4234_runtime_resume(struct device *dev) { struct cs4234 *cs4234 = dev_get_drvdata(dev); int ret; @@ -881,7 +881,7 @@ static int __maybe_unused cs4234_runtime_resume(struct device *dev) return 0; } -static int __maybe_unused cs4234_runtime_suspend(struct device *dev) +static int cs4234_runtime_suspend(struct device *dev) { struct cs4234 *cs4234 = dev_get_drvdata(dev); @@ -891,7 +891,7 @@ static int __maybe_unused cs4234_runtime_suspend(struct device *dev) } static const struct dev_pm_ops cs4234_pm = { - SET_RUNTIME_PM_OPS(cs4234_runtime_suspend, cs4234_runtime_resume, NULL) + RUNTIME_PM_OPS(cs4234_runtime_suspend, cs4234_runtime_resume, NULL) }; static const struct of_device_id cs4234_of_match[] = { @@ -903,7 +903,7 @@ MODULE_DEVICE_TABLE(of, cs4234_of_match); static struct i2c_driver cs4234_i2c_driver = { .driver = { .name = "cs4234", - .pm = &cs4234_pm, + .pm = pm_ptr(&cs4234_pm), .of_match_table = cs4234_of_match, }, .probe = cs4234_i2c_probe, From 227b132349825b52ded464e71271751aceb4b4c9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:31 +0100 Subject: [PATCH 521/651] ASoC: cs42l42: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-10-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l42-i2c.c | 6 +++--- sound/soc/codecs/cs42l42-sdw.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/cs42l42-i2c.c b/sound/soc/codecs/cs42l42-i2c.c index 8a1d5c7a61d7..98b6718ccabf 100644 --- a/sound/soc/codecs/cs42l42-i2c.c +++ b/sound/soc/codecs/cs42l42-i2c.c @@ -48,7 +48,7 @@ static void cs42l42_i2c_remove(struct i2c_client *i2c_client) cs42l42_common_remove(cs42l42); } -static int __maybe_unused cs42l42_i2c_resume(struct device *dev) +static int cs42l42_i2c_resume(struct device *dev) { int ret; @@ -62,7 +62,7 @@ static int __maybe_unused cs42l42_i2c_resume(struct device *dev) } static const struct dev_pm_ops cs42l42_i2c_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_i2c_resume) + SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_i2c_resume) }; static const struct of_device_id __maybe_unused cs42l42_of_match[] = { @@ -87,7 +87,7 @@ MODULE_DEVICE_TABLE(i2c, cs42l42_id); static struct i2c_driver cs42l42_i2c_driver = { .driver = { .name = "cs42l42", - .pm = &cs42l42_i2c_pm_ops, + .pm = pm_ptr(&cs42l42_i2c_pm_ops), .of_match_table = of_match_ptr(cs42l42_of_match), .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), }, diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c index ae1401b250a3..f837c7eff10b 100644 --- a/sound/soc/codecs/cs42l42-sdw.c +++ b/sound/soc/codecs/cs42l42-sdw.c @@ -411,7 +411,7 @@ static const struct sdw_slave_ops cs42l42_sdw_ops = { .port_prep = cs42l42_sdw_port_prep, }; -static int __maybe_unused cs42l42_sdw_runtime_suspend(struct device *dev) +static int cs42l42_sdw_runtime_suspend(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); @@ -426,11 +426,11 @@ static int __maybe_unused cs42l42_sdw_runtime_suspend(struct device *dev) return 0; } -static const struct reg_sequence __maybe_unused cs42l42_soft_reboot_seq[] = { +static const struct reg_sequence cs42l42_soft_reboot_seq[] = { REG_SEQ0(CS42L42_SOFT_RESET_REBOOT, 0x1e), }; -static int __maybe_unused cs42l42_sdw_handle_unattach(struct cs42l42_private *cs42l42) +static int cs42l42_sdw_handle_unattach(struct cs42l42_private *cs42l42) { struct sdw_slave *peripheral = cs42l42->sdw_peripheral; @@ -460,7 +460,7 @@ static int __maybe_unused cs42l42_sdw_handle_unattach(struct cs42l42_private *cs return 0; } -static int __maybe_unused cs42l42_sdw_runtime_resume(struct device *dev) +static int cs42l42_sdw_runtime_resume(struct device *dev) { static const unsigned int ts_dbnce_ms[] = { 0, 125, 250, 500, 750, 1000, 1250, 1500}; struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); @@ -491,7 +491,7 @@ static int __maybe_unused cs42l42_sdw_runtime_resume(struct device *dev) return 0; } -static int __maybe_unused cs42l42_sdw_resume(struct device *dev) +static int cs42l42_sdw_resume(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); int ret; @@ -596,8 +596,8 @@ static int cs42l42_sdw_remove(struct sdw_slave *peripheral) } static const struct dev_pm_ops cs42l42_sdw_pm = { - SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_sdw_resume) - SET_RUNTIME_PM_OPS(cs42l42_sdw_runtime_suspend, cs42l42_sdw_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_sdw_resume) + RUNTIME_PM_OPS(cs42l42_sdw_runtime_suspend, cs42l42_sdw_runtime_resume, NULL) }; static const struct sdw_device_id cs42l42_sdw_id[] = { @@ -609,7 +609,7 @@ MODULE_DEVICE_TABLE(sdw, cs42l42_sdw_id); static struct sdw_driver cs42l42_sdw_driver = { .driver = { .name = "cs42l42-sdw", - .pm = &cs42l42_sdw_pm, + .pm = pm_ptr(&cs42l42_sdw_pm), }, .probe = cs42l42_sdw_probe, .remove = cs42l42_sdw_remove, From 92104ed88e7c2f1a10cb72f5372107136738c2c9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:32 +0100 Subject: [PATCH 522/651] ASoC: cs42l51: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS(). Also, drop superfluous __maybe_unused attributes to cs42l51_suspend() and _resume() functions. Merely a cleanup, there should be no actual code change. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-11-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l51-i2c.c | 2 +- sound/soc/codecs/cs42l51.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c index f171bd66fcac..ba7e237619f2 100644 --- a/sound/soc/codecs/cs42l51-i2c.c +++ b/sound/soc/codecs/cs42l51-i2c.c @@ -40,7 +40,7 @@ static void cs42l51_i2c_remove(struct i2c_client *i2c) } static const struct dev_pm_ops cs42l51_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(cs42l51_suspend, cs42l51_resume) + SYSTEM_SLEEP_PM_OPS(cs42l51_suspend, cs42l51_resume) }; static struct i2c_driver cs42l51_i2c_driver = { diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 0602d03095d6..8083a339dc7b 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -805,7 +805,7 @@ void cs42l51_remove(struct device *dev) } EXPORT_SYMBOL_GPL(cs42l51_remove); -int __maybe_unused cs42l51_suspend(struct device *dev) +int cs42l51_suspend(struct device *dev) { struct cs42l51_private *cs42l51 = dev_get_drvdata(dev); @@ -816,7 +816,7 @@ int __maybe_unused cs42l51_suspend(struct device *dev) } EXPORT_SYMBOL_GPL(cs42l51_suspend); -int __maybe_unused cs42l51_resume(struct device *dev) +int cs42l51_resume(struct device *dev) { struct cs42l51_private *cs42l51 = dev_get_drvdata(dev); From 850910df7a5ce514f4b4d4d7ba4020abf9254b6d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:33 +0100 Subject: [PATCH 523/651] ASoC: cs42l83: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-12-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l83-i2c.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/cs42l83-i2c.c b/sound/soc/codecs/cs42l83-i2c.c index 42c3e1efdc08..53a7fe1ab3dd 100644 --- a/sound/soc/codecs/cs42l83-i2c.c +++ b/sound/soc/codecs/cs42l83-i2c.c @@ -199,7 +199,7 @@ static void cs42l83_i2c_remove(struct i2c_client *i2c_client) cs42l42_common_remove(cs42l83); } -static int __maybe_unused cs42l83_i2c_resume(struct device *dev) +static int cs42l83_i2c_resume(struct device *dev) { int ret; @@ -213,7 +213,7 @@ static int __maybe_unused cs42l83_i2c_resume(struct device *dev) } static const struct dev_pm_ops cs42l83_i2c_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l83_i2c_resume) + SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l83_i2c_resume) }; static const struct of_device_id __maybe_unused cs42l83_of_match[] = { @@ -225,7 +225,7 @@ MODULE_DEVICE_TABLE(of, cs42l83_of_match); static struct i2c_driver cs42l83_i2c_driver = { .driver = { .name = "cs42l83", - .pm = &cs42l83_i2c_pm_ops, + .pm = pm_ptr(&cs42l83_i2c_pm_ops), .of_match_table = of_match_ptr(cs42l83_of_match), }, .probe = cs42l83_i2c_probe, From 7b7e2292e0ba84515e62147a47b79e1f81f47b1c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:34 +0100 Subject: [PATCH 524/651] ASoC: cs42xx8: Convert to EXPORT_GPL_DEV_PM_OPS() Use the newer EXPORT_GPL_DEV_PM_OPS() macro together with pm_ptr(), which allows us to drop superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-13-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs42xx8-i2c.c | 2 +- sound/soc/codecs/cs42xx8.c | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/cs42xx8-i2c.c b/sound/soc/codecs/cs42xx8-i2c.c index ecaebf8e1c8f..039b3ecb3b9b 100644 --- a/sound/soc/codecs/cs42xx8-i2c.c +++ b/sound/soc/codecs/cs42xx8-i2c.c @@ -61,7 +61,7 @@ MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id); static struct i2c_driver cs42xx8_i2c_driver = { .driver = { .name = "cs42xx8", - .pm = &cs42xx8_pm, + .pm = pm_ptr(&cs42xx8_pm), .of_match_table = cs42xx8_of_match, }, .probe = cs42xx8_i2c_probe, diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 8887db653dbf..6a925f3f7137 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c @@ -606,7 +606,6 @@ err_enable: } EXPORT_SYMBOL_GPL(cs42xx8_probe); -#ifdef CONFIG_PM static int cs42xx8_runtime_resume(struct device *dev) { struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev); @@ -665,14 +664,11 @@ static int cs42xx8_runtime_suspend(struct device *dev) return 0; } -#endif -const struct dev_pm_ops cs42xx8_pm = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) +EXPORT_GPL_DEV_PM_OPS(cs42xx8_pm) = { + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) }; -EXPORT_SYMBOL_GPL(cs42xx8_pm); MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver"); MODULE_AUTHOR("Freescale Semiconductor, Inc."); From 9a1d4a56565161a8bbf5b2a9d92665010303aeac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:35 +0100 Subject: [PATCH 525/651] ASoC: cs43130: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-14-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs43130.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index cd535be0b4ba..d9b3d73c8388 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -2672,7 +2672,7 @@ static void cs43130_i2c_remove(struct i2c_client *client) regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies); } -static int __maybe_unused cs43130_runtime_suspend(struct device *dev) +static int cs43130_runtime_suspend(struct device *dev) { struct cs43130_private *cs43130 = dev_get_drvdata(dev); @@ -2691,7 +2691,7 @@ static int __maybe_unused cs43130_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused cs43130_runtime_resume(struct device *dev) +static int cs43130_runtime_resume(struct device *dev) { struct cs43130_private *cs43130 = dev_get_drvdata(dev); int ret; @@ -2727,8 +2727,7 @@ err: } static const struct dev_pm_ops cs43130_runtime_pm = { - SET_RUNTIME_PM_OPS(cs43130_runtime_suspend, cs43130_runtime_resume, - NULL) + RUNTIME_PM_OPS(cs43130_runtime_suspend, cs43130_runtime_resume, NULL) }; #if IS_ENABLED(CONFIG_OF) @@ -2768,7 +2767,7 @@ static struct i2c_driver cs43130_i2c_driver = { .name = "cs43130", .of_match_table = of_match_ptr(cs43130_of_match), .acpi_match_table = ACPI_PTR(cs43130_acpi_match), - .pm = &cs43130_runtime_pm, + .pm = pm_ptr(&cs43130_runtime_pm), }, .id_table = cs43130_i2c_id, .probe = cs43130_i2c_probe, From 2492a736dd8959b8860ca7f7afcd395314c9c436 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:36 +0100 Subject: [PATCH 526/651] ASoC: cs4349: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-15-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs4349.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index a134ca722892..d9a9c34fffe3 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -312,7 +312,6 @@ static void cs4349_i2c_remove(struct i2c_client *client) gpiod_set_value_cansleep(cs4349->reset_gpio, 0); } -#ifdef CONFIG_PM static int cs4349_runtime_suspend(struct device *dev) { struct cs4349_private *cs4349 = dev_get_drvdata(dev); @@ -346,11 +345,9 @@ static int cs4349_runtime_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops cs4349_runtime_pm = { - SET_RUNTIME_PM_OPS(cs4349_runtime_suspend, cs4349_runtime_resume, - NULL) + RUNTIME_PM_OPS(cs4349_runtime_suspend, cs4349_runtime_resume, NULL) }; static const struct of_device_id cs4349_of_match[] = { @@ -371,7 +368,7 @@ static struct i2c_driver cs4349_i2c_driver = { .driver = { .name = "cs4349", .of_match_table = cs4349_of_match, - .pm = &cs4349_runtime_pm, + .pm = pm_ptr(&cs4349_runtime_pm), }, .id_table = cs4349_i2c_id, .probe = cs4349_i2c_probe, From 646443af4452793090d34da2c70d5ed126f174bd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:37 +0100 Subject: [PATCH 527/651] ASoC: cs53l30: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-16-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs53l30.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index aea4244fb275..61bf72681674 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -1031,7 +1031,6 @@ static void cs53l30_i2c_remove(struct i2c_client *client) cs53l30->supplies); } -#ifdef CONFIG_PM static int cs53l30_runtime_suspend(struct device *dev) { struct cs53l30_private *cs53l30 = dev_get_drvdata(dev); @@ -1070,11 +1069,9 @@ static int cs53l30_runtime_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops cs53l30_runtime_pm = { - SET_RUNTIME_PM_OPS(cs53l30_runtime_suspend, cs53l30_runtime_resume, - NULL) + RUNTIME_PM_OPS(cs53l30_runtime_suspend, cs53l30_runtime_resume, NULL) }; static const struct of_device_id cs53l30_of_match[] = { @@ -1095,7 +1092,7 @@ static struct i2c_driver cs53l30_i2c_driver = { .driver = { .name = "cs53l30", .of_match_table = cs53l30_of_match, - .pm = &cs53l30_runtime_pm, + .pm = pm_ptr(&cs53l30_runtime_pm), }, .id_table = cs53l30_id, .probe = cs53l30_i2c_probe, From 81f150d4b96d73feecda475f500f460565344255 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:38 +0100 Subject: [PATCH 528/651] ASoC: cx2072x: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-17-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/cx2072x.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/cx2072x.c b/sound/soc/codecs/cx2072x.c index 8cfec8dcf839..934526f8f292 100644 --- a/sound/soc/codecs/cx2072x.c +++ b/sound/soc/codecs/cx2072x.c @@ -1611,7 +1611,7 @@ static const struct regmap_config cx2072x_regmap = { .reg_write = cx2072x_reg_write, }; -static int __maybe_unused cx2072x_runtime_suspend(struct device *dev) +static int cx2072x_runtime_suspend(struct device *dev) { struct cx2072x_priv *cx2072x = dev_get_drvdata(dev); @@ -1619,7 +1619,7 @@ static int __maybe_unused cx2072x_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused cx2072x_runtime_resume(struct device *dev) +static int cx2072x_runtime_resume(struct device *dev) { struct cx2072x_priv *cx2072x = dev_get_drvdata(dev); @@ -1696,17 +1696,15 @@ MODULE_DEVICE_TABLE(acpi, cx2072x_acpi_match); #endif static const struct dev_pm_ops cx2072x_runtime_pm = { - SET_RUNTIME_PM_OPS(cx2072x_runtime_suspend, cx2072x_runtime_resume, - NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(cx2072x_runtime_suspend, cx2072x_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct i2c_driver cx2072x_i2c_driver = { .driver = { .name = "cx2072x", .acpi_match_table = ACPI_PTR(cx2072x_acpi_match), - .pm = &cx2072x_runtime_pm, + .pm = pm_ptr(&cx2072x_runtime_pm), }, .probe = cx2072x_i2c_probe, .remove = cx2072x_i2c_remove, From 948cf1681e2ee077969df1e672f4c4d856059937 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:39 +0100 Subject: [PATCH 529/651] ASoC: da7213: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: support.opensource@diasemi.com Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-18-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/da7213.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index eb97ac73ec06..a4496cc26902 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -2224,7 +2224,7 @@ static void da7213_i2c_remove(struct i2c_client *i2c) pm_runtime_disable(&i2c->dev); } -static int __maybe_unused da7213_runtime_suspend(struct device *dev) +static int da7213_runtime_suspend(struct device *dev) { struct da7213_priv *da7213 = dev_get_drvdata(dev); @@ -2235,7 +2235,7 @@ static int __maybe_unused da7213_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused da7213_runtime_resume(struct device *dev) +static int da7213_runtime_resume(struct device *dev) { struct da7213_priv *da7213 = dev_get_drvdata(dev); int ret; @@ -2248,8 +2248,8 @@ static int __maybe_unused da7213_runtime_resume(struct device *dev) } static const struct dev_pm_ops da7213_pm = { - SET_RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static const struct i2c_device_id da7213_i2c_id[] = { @@ -2264,7 +2264,7 @@ static struct i2c_driver da7213_i2c_driver = { .name = "da7213", .of_match_table = of_match_ptr(da7213_of_match), .acpi_match_table = ACPI_PTR(da7213_acpi_match), - .pm = &da7213_pm, + .pm = pm_ptr(&da7213_pm), }, .probe = da7213_i2c_probe, .remove = da7213_i2c_remove, From 218b32ca6c63db19ba0f4ad4fe83dc7c18e21bcb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:40 +0100 Subject: [PATCH 530/651] ASoC: hdac_hdmi: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-19-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 3bea5d09219a..1139a2754ca3 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2032,7 +2032,6 @@ static void hdmi_codec_remove(struct snd_soc_component *component) pm_runtime_disable(&hdev->dev); } -#ifdef CONFIG_PM_SLEEP static int hdmi_codec_resume(struct device *dev) { struct hdac_device *hdev = dev_to_hdac_dev(dev); @@ -2055,9 +2054,6 @@ static int hdmi_codec_resume(struct device *dev) hdac_hdmi_present_sense_all_pins(hdev, hdmi, false); return 0; } -#else -#define hdmi_codec_resume NULL -#endif static const struct snd_soc_component_driver hdmi_hda_codec = { .probe = hdmi_codec_probe, @@ -2227,7 +2223,6 @@ static int hdac_hdmi_dev_remove(struct hdac_device *hdev) return 0; } -#ifdef CONFIG_PM static int hdac_hdmi_runtime_suspend(struct device *dev) { struct hdac_device *hdev = dev_to_hdac_dev(dev); @@ -2296,14 +2291,10 @@ static int hdac_hdmi_runtime_resume(struct device *dev) return 0; } -#else -#define hdac_hdmi_runtime_suspend NULL -#define hdac_hdmi_runtime_resume NULL -#endif static const struct dev_pm_ops hdac_hdmi_pm = { - SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, hdmi_codec_resume) + RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, hdmi_codec_resume) }; static const struct hda_device_id hdmi_list[] = { @@ -2322,7 +2313,7 @@ MODULE_DEVICE_TABLE(hdaudio, hdmi_list); static struct hdac_driver hdmi_driver = { .driver = { .name = "HDMI HDA Codec", - .pm = &hdac_hdmi_pm, + .pm = pm_ptr(&hdac_hdmi_pm), }, .id_table = hdmi_list, .probe = hdac_hdmi_dev_probe, From efd74b16af66d3ab2e65a68d6ff171ae2b4ecf21 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:41 +0100 Subject: [PATCH 531/651] ASoC: lpass: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Srinivas Kandagatla Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-20-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/lpass-rx-macro.c | 8 ++++---- sound/soc/codecs/lpass-tx-macro.c | 8 ++++---- sound/soc/codecs/lpass-va-macro.c | 8 ++++---- sound/soc/codecs/lpass-wsa-macro.c | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index febbbe073962..45a6b83808b2 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -3963,7 +3963,7 @@ static const struct of_device_id rx_macro_dt_match[] = { }; MODULE_DEVICE_TABLE(of, rx_macro_dt_match); -static int __maybe_unused rx_macro_runtime_suspend(struct device *dev) +static int rx_macro_runtime_suspend(struct device *dev) { struct rx_macro *rx = dev_get_drvdata(dev); @@ -3977,7 +3977,7 @@ static int __maybe_unused rx_macro_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused rx_macro_runtime_resume(struct device *dev) +static int rx_macro_runtime_resume(struct device *dev) { struct rx_macro *rx = dev_get_drvdata(dev); int ret; @@ -4012,7 +4012,7 @@ err_npl: } static const struct dev_pm_ops rx_macro_pm_ops = { - SET_RUNTIME_PM_OPS(rx_macro_runtime_suspend, rx_macro_runtime_resume, NULL) + RUNTIME_PM_OPS(rx_macro_runtime_suspend, rx_macro_runtime_resume, NULL) }; static struct platform_driver rx_macro_driver = { @@ -4020,7 +4020,7 @@ static struct platform_driver rx_macro_driver = { .name = "rx_macro", .of_match_table = rx_macro_dt_match, .suppress_bind_attrs = true, - .pm = &rx_macro_pm_ops, + .pm = pm_ptr(&rx_macro_pm_ops), }, .probe = rx_macro_probe, .remove = rx_macro_remove, diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index a134584acf90..27bae58f4072 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -2400,7 +2400,7 @@ static void tx_macro_remove(struct platform_device *pdev) lpass_macro_pds_exit(tx->pds); } -static int __maybe_unused tx_macro_runtime_suspend(struct device *dev) +static int tx_macro_runtime_suspend(struct device *dev) { struct tx_macro *tx = dev_get_drvdata(dev); @@ -2414,7 +2414,7 @@ static int __maybe_unused tx_macro_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tx_macro_runtime_resume(struct device *dev) +static int tx_macro_runtime_resume(struct device *dev) { struct tx_macro *tx = dev_get_drvdata(dev); int ret; @@ -2450,7 +2450,7 @@ err_npl: } static const struct dev_pm_ops tx_macro_pm_ops = { - SET_RUNTIME_PM_OPS(tx_macro_runtime_suspend, tx_macro_runtime_resume, NULL) + RUNTIME_PM_OPS(tx_macro_runtime_suspend, tx_macro_runtime_resume, NULL) }; static const struct tx_macro_data lpass_ver_9 = { @@ -2531,7 +2531,7 @@ static struct platform_driver tx_macro_driver = { .name = "tx_macro", .of_match_table = tx_macro_dt_match, .suppress_bind_attrs = true, - .pm = &tx_macro_pm_ops, + .pm = pm_ptr(&tx_macro_pm_ops), }, .probe = tx_macro_probe, .remove = tx_macro_remove, diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c index c781da476240..74ada6e77526 100644 --- a/sound/soc/codecs/lpass-va-macro.c +++ b/sound/soc/codecs/lpass-va-macro.c @@ -1674,7 +1674,7 @@ static void va_macro_remove(struct platform_device *pdev) lpass_macro_pds_exit(va->pds); } -static int __maybe_unused va_macro_runtime_suspend(struct device *dev) +static int va_macro_runtime_suspend(struct device *dev) { struct va_macro *va = dev_get_drvdata(dev); @@ -1689,7 +1689,7 @@ static int __maybe_unused va_macro_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused va_macro_runtime_resume(struct device *dev) +static int va_macro_runtime_resume(struct device *dev) { struct va_macro *va = dev_get_drvdata(dev); int ret; @@ -1717,7 +1717,7 @@ static int __maybe_unused va_macro_runtime_resume(struct device *dev) static const struct dev_pm_ops va_macro_pm_ops = { - SET_RUNTIME_PM_OPS(va_macro_runtime_suspend, va_macro_runtime_resume, NULL) + RUNTIME_PM_OPS(va_macro_runtime_suspend, va_macro_runtime_resume, NULL) }; static const struct of_device_id va_macro_dt_match[] = { @@ -1735,7 +1735,7 @@ static struct platform_driver va_macro_driver = { .name = "va_macro", .of_match_table = va_macro_dt_match, .suppress_bind_attrs = true, - .pm = &va_macro_pm_ops, + .pm = pm_ptr(&va_macro_pm_ops), }, .probe = va_macro_probe, .remove = va_macro_remove, diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index c989d82d1d3c..b261fa373e65 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -2900,7 +2900,7 @@ static void wsa_macro_remove(struct platform_device *pdev) clk_disable_unprepare(wsa->fsgen); } -static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev) +static int wsa_macro_runtime_suspend(struct device *dev) { struct wsa_macro *wsa = dev_get_drvdata(dev); @@ -2914,7 +2914,7 @@ static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused wsa_macro_runtime_resume(struct device *dev) +static int wsa_macro_runtime_resume(struct device *dev) { struct wsa_macro *wsa = dev_get_drvdata(dev); int ret; @@ -2950,7 +2950,7 @@ err_npl: } static const struct dev_pm_ops wsa_macro_pm_ops = { - SET_RUNTIME_PM_OPS(wsa_macro_runtime_suspend, wsa_macro_runtime_resume, NULL) + RUNTIME_PM_OPS(wsa_macro_runtime_suspend, wsa_macro_runtime_resume, NULL) }; static const struct of_device_id wsa_macro_dt_match[] = { @@ -2977,7 +2977,7 @@ static struct platform_driver wsa_macro_driver = { .driver = { .name = "wsa_macro", .of_match_table = wsa_macro_dt_match, - .pm = &wsa_macro_pm_ops, + .pm = pm_ptr(&wsa_macro_pm_ops), }, .probe = wsa_macro_probe, .remove = wsa_macro_remove, From f744bcb575f7e25d871532e731398b99de32953d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:42 +0100 Subject: [PATCH 532/651] ASoC: max98090: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM and CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-21-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 790e2ae6dc18..22177c1ce160 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2604,7 +2604,6 @@ static void max98090_i2c_remove(struct i2c_client *client) max98090_i2c_shutdown(client); } -#ifdef CONFIG_PM static int max98090_runtime_resume(struct device *dev) { struct max98090_priv *max98090 = dev_get_drvdata(dev); @@ -2626,9 +2625,7 @@ static int max98090_runtime_suspend(struct device *dev) return 0; } -#endif -#ifdef CONFIG_PM_SLEEP static int max98090_resume(struct device *dev) { struct max98090_priv *max98090 = dev_get_drvdata(dev); @@ -2645,12 +2642,10 @@ static int max98090_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops max98090_pm = { - SET_RUNTIME_PM_OPS(max98090_runtime_suspend, - max98090_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(NULL, max98090_resume) + RUNTIME_PM_OPS(max98090_runtime_suspend, max98090_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(NULL, max98090_resume) }; #ifdef CONFIG_OF @@ -2673,7 +2668,7 @@ MODULE_DEVICE_TABLE(acpi, max98090_acpi_match); static struct i2c_driver max98090_i2c_driver = { .driver = { .name = "max98090", - .pm = &max98090_pm, + .pm = pm_ptr(&max98090_pm), .of_match_table = of_match_ptr(max98090_of_match), .acpi_match_table = ACPI_PTR(max98090_acpi_match), }, From db001865fdbc6ee446660a06f00437fbb72cfe9c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:43 +0100 Subject: [PATCH 533/651] ASoC: max98373: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM and CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-22-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/max98373-i2c.c | 6 ++---- sound/soc/codecs/max98373-sdw.c | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c index 1f7ff3dbcbbe..56c4ba1f3782 100644 --- a/sound/soc/codecs/max98373-i2c.c +++ b/sound/soc/codecs/max98373-i2c.c @@ -472,7 +472,6 @@ static struct snd_soc_dai_driver max98373_dai[] = { } }; -#ifdef CONFIG_PM_SLEEP static int max98373_suspend(struct device *dev) { struct max98373_priv *max98373 = dev_get_drvdata(dev); @@ -496,10 +495,9 @@ static int max98373_resume(struct device *dev) regcache_sync(max98373->regmap); return 0; } -#endif static const struct dev_pm_ops max98373_pm = { - SET_SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume) + SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume) }; static const struct regmap_config max98373_regmap = { @@ -605,7 +603,7 @@ static struct i2c_driver max98373_i2c_driver = { .name = "max98373", .of_match_table = of_match_ptr(max98373_of_match), .acpi_match_table = ACPI_PTR(max98373_acpi_match), - .pm = &max98373_pm, + .pm = pm_ptr(&max98373_pm), }, .probe = max98373_i2c_probe, .id_table = max98373_i2c_id, diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index 26860882fd91..6088278e6503 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -246,7 +246,7 @@ static const struct regmap_config max98373_sdw_regmap = { }; /* Power management functions and structure */ -static __maybe_unused int max98373_suspend(struct device *dev) +static int max98373_suspend(struct device *dev) { struct max98373_priv *max98373 = dev_get_drvdata(dev); int i; @@ -262,7 +262,7 @@ static __maybe_unused int max98373_suspend(struct device *dev) #define MAX98373_PROBE_TIMEOUT 5000 -static __maybe_unused int max98373_resume(struct device *dev) +static int max98373_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct max98373_priv *max98373 = dev_get_drvdata(dev); @@ -292,8 +292,8 @@ regmap_sync: } static const struct dev_pm_ops max98373_pm = { - SET_SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume) - SET_RUNTIME_PM_OPS(max98373_suspend, max98373_resume, NULL) + SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume) + RUNTIME_PM_OPS(max98373_suspend, max98373_resume, NULL) }; static int max98373_read_prop(struct sdw_slave *slave) @@ -874,7 +874,7 @@ static struct sdw_driver max98373_sdw_driver = { .name = "max98373", .of_match_table = of_match_ptr(max98373_of_match), .acpi_match_table = ACPI_PTR(max98373_acpi_match), - .pm = &max98373_pm, + .pm = pm_ptr(&max98373_pm), }, .probe = max98373_sdw_probe, .remove = max98373_sdw_remove, From 69b638e8d4347113183496684de5f3ac2a1db4b6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:44 +0100 Subject: [PATCH 534/651] ASoC: max98390: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-23-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/max98390.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index 1bae253618fd..76296176f948 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -943,7 +943,6 @@ static int max98390_probe(struct snd_soc_component *component) return 0; } -#ifdef CONFIG_PM_SLEEP static int max98390_suspend(struct device *dev) { struct max98390_priv *max98390 = dev_get_drvdata(dev); @@ -967,10 +966,9 @@ static int max98390_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops max98390_pm = { - SET_SYSTEM_SLEEP_PM_OPS(max98390_suspend, max98390_resume) + SYSTEM_SLEEP_PM_OPS(max98390_suspend, max98390_resume) }; static const struct snd_soc_component_driver soc_codec_dev_max98390 = { @@ -1130,7 +1128,7 @@ static struct i2c_driver max98390_i2c_driver = { .name = "max98390", .of_match_table = of_match_ptr(max98390_of_match), .acpi_match_table = ACPI_PTR(max98390_acpi_match), - .pm = &max98390_pm, + .pm = pm_ptr(&max98390_pm), }, .probe = max98390_i2c_probe, .id_table = max98390_i2c_id, From c009893bc5864d55b0b0cc349413a0eaa2bc17cc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:45 +0100 Subject: [PATCH 535/651] ASoC: max98396: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-24-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/max98396.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index e52bb2266fa1..c1888cd83dbc 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -1571,7 +1571,6 @@ static int max98396_probe(struct snd_soc_component *component) return 0; } -#ifdef CONFIG_PM_SLEEP static int max98396_suspend(struct device *dev) { struct max98396_priv *max98396 = dev_get_drvdata(dev); @@ -1616,10 +1615,9 @@ static int max98396_resume(struct device *dev) regcache_sync(max98396->regmap); return 0; } -#endif static const struct dev_pm_ops max98396_pm = { - SET_SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume) + SYSTEM_SLEEP_PM_OPS(max98396_suspend, max98396_resume) }; static const struct snd_soc_component_driver soc_codec_dev_max98396 = { @@ -1904,7 +1902,7 @@ static struct i2c_driver max98396_i2c_driver = { .name = "max98396", .of_match_table = of_match_ptr(max98396_of_match), .acpi_match_table = ACPI_PTR(max98396_acpi_match), - .pm = &max98396_pm, + .pm = pm_ptr(&max98396_pm), }, .probe = max98396_i2c_probe, .id_table = max98396_i2c_id, From b352343e448c45940116dc4a089a288fd820dee9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:46 +0100 Subject: [PATCH 536/651] ASoC: max98520: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unsed attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-25-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/max98520.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max98520.c b/sound/soc/codecs/max98520.c index 479ded22672e..adf5a898c6df 100644 --- a/sound/soc/codecs/max98520.c +++ b/sound/soc/codecs/max98520.c @@ -621,7 +621,7 @@ static int max98520_probe(struct snd_soc_component *component) return 0; } -static int __maybe_unused max98520_suspend(struct device *dev) +static int max98520_suspend(struct device *dev) { struct max98520_priv *max98520 = dev_get_drvdata(dev); @@ -630,7 +630,7 @@ static int __maybe_unused max98520_suspend(struct device *dev) return 0; } -static int __maybe_unused max98520_resume(struct device *dev) +static int max98520_resume(struct device *dev) { struct max98520_priv *max98520 = dev_get_drvdata(dev); @@ -641,7 +641,7 @@ static int __maybe_unused max98520_resume(struct device *dev) } static const struct dev_pm_ops max98520_pm = { - SET_SYSTEM_SLEEP_PM_OPS(max98520_suspend, max98520_resume) + SYSTEM_SLEEP_PM_OPS(max98520_suspend, max98520_resume) }; static const struct snd_soc_component_driver soc_codec_dev_max98520 = { @@ -752,7 +752,7 @@ static struct i2c_driver max98520_i2c_driver = { .driver = { .name = "max98520", .of_match_table = of_match_ptr(max98520_of_match), - .pm = &max98520_pm, + .pm = pm_ptr(&max98520_pm), }, .probe = max98520_i2c_probe, .id_table = max98520_i2c_id, From d0029e0a78672932367478e5b3479edfa2738ec0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:47 +0100 Subject: [PATCH 537/651] ASoC: max9860: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-26-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/max9860.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 4015ed2c47ec..716d16daf7d7 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -539,7 +539,6 @@ static const struct snd_soc_component_driver max9860_component_driver = { .endianness = 1, }; -#ifdef CONFIG_PM static int max9860_suspend(struct device *dev) { struct max9860_priv *max9860 = dev_get_drvdata(dev); @@ -584,10 +583,9 @@ static int max9860_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops max9860_pm_ops = { - SET_RUNTIME_PM_OPS(max9860_suspend, max9860_resume, NULL) + RUNTIME_PM_OPS(max9860_suspend, max9860_resume, NULL) }; static int max9860_probe(struct i2c_client *i2c) @@ -729,7 +727,7 @@ static struct i2c_driver max9860_i2c_driver = { .driver = { .name = "max9860", .of_match_table = max9860_of_match, - .pm = &max9860_pm_ops, + .pm = pm_ptr(&max9860_pm_ops), }, }; From 113d29a94410ff292be090949c43911b11c4d32a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:48 +0100 Subject: [PATCH 538/651] ASoC: max98927: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-27-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/max98927.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index 747aa6f1d54f..55cc18451a2d 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -731,7 +731,6 @@ static int max98927_probe(struct snd_soc_component *component) return 0; } -#ifdef CONFIG_PM_SLEEP static int max98927_suspend(struct device *dev) { struct max98927_priv *max98927 = dev_get_drvdata(dev); @@ -750,10 +749,9 @@ static int max98927_resume(struct device *dev) regcache_sync(max98927->regmap); return 0; } -#endif static const struct dev_pm_ops max98927_pm = { - SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume) + SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume) }; static const struct snd_soc_component_driver soc_component_dev_max98927 = { @@ -902,7 +900,7 @@ static struct i2c_driver max98927_i2c_driver = { .name = "max98927", .of_match_table = of_match_ptr(max98927_of_match), .acpi_match_table = ACPI_PTR(max98927_acpi_match), - .pm = &max98927_pm, + .pm = pm_ptr(&max98927_pm), }, .probe = max98927_i2c_probe, .remove = max98927_i2c_remove, From aa912611c43006e628d14e9319402a77ab0bf97c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:49 +0100 Subject: [PATCH 539/651] ASoC: mt6660: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-28-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/mt6660.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c index 39a57f643d81..d16bccebae52 100644 --- a/sound/soc/codecs/mt6660.c +++ b/sound/soc/codecs/mt6660.c @@ -529,7 +529,7 @@ static void mt6660_i2c_remove(struct i2c_client *client) mutex_destroy(&chip->io_lock); } -static int __maybe_unused mt6660_i2c_runtime_suspend(struct device *dev) +static int mt6660_i2c_runtime_suspend(struct device *dev) { struct mt6660_chip *chip = dev_get_drvdata(dev); @@ -538,7 +538,7 @@ static int __maybe_unused mt6660_i2c_runtime_suspend(struct device *dev) MT6660_REG_SYSTEM_CTRL, 0x01, 0x01); } -static int __maybe_unused mt6660_i2c_runtime_resume(struct device *dev) +static int mt6660_i2c_runtime_resume(struct device *dev) { struct mt6660_chip *chip = dev_get_drvdata(dev); @@ -548,8 +548,7 @@ static int __maybe_unused mt6660_i2c_runtime_resume(struct device *dev) } static const struct dev_pm_ops mt6660_dev_pm_ops = { - SET_RUNTIME_PM_OPS(mt6660_i2c_runtime_suspend, - mt6660_i2c_runtime_resume, NULL) + RUNTIME_PM_OPS(mt6660_i2c_runtime_suspend, mt6660_i2c_runtime_resume, NULL) }; static const struct of_device_id __maybe_unused mt6660_of_id[] = { @@ -568,7 +567,7 @@ static struct i2c_driver mt6660_i2c_driver = { .driver = { .name = "mt6660", .of_match_table = of_match_ptr(mt6660_of_id), - .pm = &mt6660_dev_pm_ops, + .pm = pm_ptr(&mt6660_dev_pm_ops), }, .probe = mt6660_i2c_probe, .remove = mt6660_i2c_remove, From 85e8d0f37879f8761dbd137dbdad720fbe7929ca Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:50 +0100 Subject: [PATCH 540/651] ASoC: pcm512x: Convert to EXPORT_GPL_DEV_PM_OPS() Use the newer EXPORT_GPL_DEV_PM_OPS() macro together with pm_ptr(), which allows us to drop superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Shenghao Ding Cc: Kevin Lu Cc: Baojun Xu Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-29-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/pcm512x-i2c.c | 2 +- sound/soc/codecs/pcm512x-spi.c | 2 +- sound/soc/codecs/pcm512x.c | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c index 92bcf5179779..a1d849b0c50f 100644 --- a/sound/soc/codecs/pcm512x-i2c.c +++ b/sound/soc/codecs/pcm512x-i2c.c @@ -79,7 +79,7 @@ static struct i2c_driver pcm512x_i2c_driver = { .name = "pcm512x", .of_match_table = of_match_ptr(pcm512x_of_match), .acpi_match_table = ACPI_PTR(pcm512x_acpi_match), - .pm = &pcm512x_pm_ops, + .pm = pm_ptr(&pcm512x_pm_ops), }, }; diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c index 6629b862f47d..92f7f78a4e20 100644 --- a/sound/soc/codecs/pcm512x-spi.c +++ b/sound/soc/codecs/pcm512x-spi.c @@ -58,7 +58,7 @@ static struct spi_driver pcm512x_spi_driver = { .driver = { .name = "pcm512x", .of_match_table = pcm512x_of_match, - .pm = &pcm512x_pm_ops, + .pm = pm_ptr(&pcm512x_pm_ops), }, }; diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index aa8edf87b743..007dfc0fa224 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -1725,7 +1725,6 @@ void pcm512x_remove(struct device *dev) } EXPORT_SYMBOL_GPL(pcm512x_remove); -#ifdef CONFIG_PM static int pcm512x_suspend(struct device *dev) { struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); @@ -1787,12 +1786,10 @@ static int pcm512x_resume(struct device *dev) return 0; } -#endif -const struct dev_pm_ops pcm512x_pm_ops = { - SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) +EXPORT_GPL_DEV_PM_OPS(pcm512x_pm_ops) = { + RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) }; -EXPORT_SYMBOL_GPL(pcm512x_pm_ops); MODULE_DESCRIPTION("ASoC PCM512x codec driver"); MODULE_AUTHOR("Mark Brown "); From b83ab4fb2c6e7c15f769653118243b0974f4c885 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:51 +0100 Subject: [PATCH 541/651] ASoC: rt1017-sdca-sdw: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-30-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt1017-sdca-sdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt1017-sdca-sdw.c b/sound/soc/codecs/rt1017-sdca-sdw.c index 7c8103a0d562..88fc23a4999f 100644 --- a/sound/soc/codecs/rt1017-sdca-sdw.c +++ b/sound/soc/codecs/rt1017-sdca-sdw.c @@ -758,7 +758,7 @@ static const struct sdw_device_id rt1017_sdca_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt1017_sdca_id); -static int __maybe_unused rt1017_sdca_dev_suspend(struct device *dev) +static int rt1017_sdca_dev_suspend(struct device *dev) { struct rt1017_sdca_priv *rt1017 = dev_get_drvdata(dev); @@ -772,7 +772,7 @@ static int __maybe_unused rt1017_sdca_dev_suspend(struct device *dev) #define RT1017_PROBE_TIMEOUT 5000 -static int __maybe_unused rt1017_sdca_dev_resume(struct device *dev) +static int rt1017_sdca_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt1017_sdca_priv *rt1017 = dev_get_drvdata(dev); @@ -802,14 +802,14 @@ regmap_sync: } static const struct dev_pm_ops rt1017_sdca_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt1017_sdca_dev_suspend, rt1017_sdca_dev_resume) - SET_RUNTIME_PM_OPS(rt1017_sdca_dev_suspend, rt1017_sdca_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt1017_sdca_dev_suspend, rt1017_sdca_dev_resume) + RUNTIME_PM_OPS(rt1017_sdca_dev_suspend, rt1017_sdca_dev_resume, NULL) }; static struct sdw_driver rt1017_sdca_sdw_driver = { .driver = { .name = "rt1017-sdca", - .pm = &rt1017_sdca_pm, + .pm = pm_ptr(&rt1017_sdca_pm), }, .probe = rt1017_sdca_sdw_probe, .remove = rt1017_sdca_sdw_remove, From 7130c4302b9229dda655235321c34bd5e6dde82e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:52 +0100 Subject: [PATCH 542/651] ASoC: rt1308-sdw: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-31-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt1308-sdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index 563df483a466..ea708068f0e8 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -753,7 +753,7 @@ static const struct sdw_device_id rt1308_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt1308_id); -static int __maybe_unused rt1308_dev_suspend(struct device *dev) +static int rt1308_dev_suspend(struct device *dev) { struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev); @@ -767,7 +767,7 @@ static int __maybe_unused rt1308_dev_suspend(struct device *dev) #define RT1308_PROBE_TIMEOUT 5000 -static int __maybe_unused rt1308_dev_resume(struct device *dev) +static int rt1308_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev); @@ -797,14 +797,14 @@ regmap_sync: } static const struct dev_pm_ops rt1308_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt1308_dev_suspend, rt1308_dev_resume) - SET_RUNTIME_PM_OPS(rt1308_dev_suspend, rt1308_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt1308_dev_suspend, rt1308_dev_resume) + RUNTIME_PM_OPS(rt1308_dev_suspend, rt1308_dev_resume, NULL) }; static struct sdw_driver rt1308_sdw_driver = { .driver = { .name = "rt1308", - .pm = &rt1308_pm, + .pm = pm_ptr(&rt1308_pm), }, .probe = rt1308_sdw_probe, .remove = rt1308_sdw_remove, From dfe8999a4f5ca8f8c67751310d0421e1bfbbae6d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:53 +0100 Subject: [PATCH 543/651] ASoC: rt1316-sdw: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-32-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt1316-sdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 22f1ed4e03f1..960b6c4f5a66 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -730,7 +730,7 @@ static const struct sdw_device_id rt1316_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt1316_id); -static int __maybe_unused rt1316_dev_suspend(struct device *dev) +static int rt1316_dev_suspend(struct device *dev) { struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(dev); @@ -744,7 +744,7 @@ static int __maybe_unused rt1316_dev_suspend(struct device *dev) #define RT1316_PROBE_TIMEOUT 5000 -static int __maybe_unused rt1316_dev_resume(struct device *dev) +static int rt1316_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(dev); @@ -774,14 +774,14 @@ regmap_sync: } static const struct dev_pm_ops rt1316_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt1316_dev_suspend, rt1316_dev_resume) - SET_RUNTIME_PM_OPS(rt1316_dev_suspend, rt1316_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt1316_dev_suspend, rt1316_dev_resume) + RUNTIME_PM_OPS(rt1316_dev_suspend, rt1316_dev_resume, NULL) }; static struct sdw_driver rt1316_sdw_driver = { .driver = { .name = "rt1316-sdca", - .pm = &rt1316_pm, + .pm = pm_ptr(&rt1316_pm), }, .probe = rt1316_sdw_probe, .remove = rt1316_sdw_remove, From d0bb681f8e9a418e396e6b471866197ecc30bd00 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:54 +0100 Subject: [PATCH 544/651] ASoC: rt1318-sdw: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-33-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt1318-sdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt1318-sdw.c b/sound/soc/codecs/rt1318-sdw.c index 319f71f5e60d..4eb636e0c9ed 100644 --- a/sound/soc/codecs/rt1318-sdw.c +++ b/sound/soc/codecs/rt1318-sdw.c @@ -807,7 +807,7 @@ static const struct sdw_device_id rt1318_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt1318_id); -static int __maybe_unused rt1318_dev_suspend(struct device *dev) +static int rt1318_dev_suspend(struct device *dev) { struct rt1318_sdw_priv *rt1318 = dev_get_drvdata(dev); @@ -820,7 +820,7 @@ static int __maybe_unused rt1318_dev_suspend(struct device *dev) #define RT1318_PROBE_TIMEOUT 5000 -static int __maybe_unused rt1318_dev_resume(struct device *dev) +static int rt1318_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt1318_sdw_priv *rt1318 = dev_get_drvdata(dev); @@ -848,14 +848,14 @@ regmap_sync: } static const struct dev_pm_ops rt1318_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt1318_dev_suspend, rt1318_dev_resume) - SET_RUNTIME_PM_OPS(rt1318_dev_suspend, rt1318_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt1318_dev_suspend, rt1318_dev_resume) + RUNTIME_PM_OPS(rt1318_dev_suspend, rt1318_dev_resume, NULL) }; static struct sdw_driver rt1318_sdw_driver = { .driver = { .name = "rt1318-sdca", - .pm = &rt1318_pm, + .pm = pm_ptr(&rt1318_pm), }, .probe = rt1318_sdw_probe, .remove = rt1318_sdw_remove, From 3eedadf3d7049e3ab2c49cf7f444e8f296327ba0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:55 +0100 Subject: [PATCH 545/651] ASoC: rt1320-sdw: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-34-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt1320-sdw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c index d83b236a0450..f51ba345a16e 100644 --- a/sound/soc/codecs/rt1320-sdw.c +++ b/sound/soc/codecs/rt1320-sdw.c @@ -1458,7 +1458,7 @@ static const struct sdw_device_id rt1320_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt1320_id); -static int __maybe_unused rt1320_dev_suspend(struct device *dev) +static int rt1320_dev_suspend(struct device *dev) { struct rt1320_sdw_priv *rt1320 = dev_get_drvdata(dev); @@ -1472,7 +1472,7 @@ static int __maybe_unused rt1320_dev_suspend(struct device *dev) #define RT1320_PROBE_TIMEOUT 5000 -static int __maybe_unused rt1320_dev_resume(struct device *dev) +static int rt1320_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt1320_sdw_priv *rt1320 = dev_get_drvdata(dev); @@ -1501,14 +1501,14 @@ regmap_sync: } static const struct dev_pm_ops rt1320_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt1320_dev_suspend, rt1320_dev_resume) - SET_RUNTIME_PM_OPS(rt1320_dev_suspend, rt1320_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt1320_dev_suspend, rt1320_dev_resume) + RUNTIME_PM_OPS(rt1320_dev_suspend, rt1320_dev_resume, NULL) }; static struct sdw_driver rt1320_sdw_driver = { .driver = { .name = "rt1320-sdca", - .pm = &rt1320_pm, + .pm = pm_ptr(&rt1320_pm), }, .probe = rt1320_sdw_probe, .remove = rt1320_sdw_remove, From fdf698fa3ff22e504505a7c32f9671c5fbbd5513 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:56 +0100 Subject: [PATCH 546/651] ASoC: rt5514: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-35-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt5514-spi.c | 8 ++++---- sound/soc/codecs/rt5514.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index f475c8cfadae..54d84581ec47 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c @@ -458,7 +458,7 @@ static int rt5514_spi_probe(struct spi_device *spi) return 0; } -static int __maybe_unused rt5514_suspend(struct device *dev) +static int rt5514_suspend(struct device *dev) { int irq = to_spi_device(dev)->irq; @@ -468,7 +468,7 @@ static int __maybe_unused rt5514_suspend(struct device *dev) return 0; } -static int __maybe_unused rt5514_resume(struct device *dev) +static int rt5514_resume(struct device *dev) { struct rt5514_dsp *rt5514_dsp = dev_get_drvdata(dev); int irq = to_spi_device(dev)->irq; @@ -490,7 +490,7 @@ static int __maybe_unused rt5514_resume(struct device *dev) } static const struct dev_pm_ops rt5514_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(rt5514_suspend, rt5514_resume) + SYSTEM_SLEEP_PM_OPS(rt5514_suspend, rt5514_resume) }; static const struct of_device_id rt5514_of_match[] = { @@ -502,7 +502,7 @@ MODULE_DEVICE_TABLE(of, rt5514_of_match); static struct spi_driver rt5514_spi_driver = { .driver = { .name = "rt5514", - .pm = &rt5514_pm_ops, + .pm = pm_ptr(&rt5514_pm_ops), .of_match_table = of_match_ptr(rt5514_of_match), }, .probe = rt5514_spi_probe, diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index a7f984b5d80f..ab9d81c32be8 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -1231,7 +1231,7 @@ static int rt5514_parse_dp(struct rt5514_priv *rt5514, struct device *dev) return 0; } -static __maybe_unused int rt5514_i2c_resume(struct device *dev) +static int rt5514_i2c_resume(struct device *dev) { struct rt5514_priv *rt5514 = dev_get_drvdata(dev); unsigned int val; @@ -1313,7 +1313,7 @@ static int rt5514_i2c_probe(struct i2c_client *i2c) } static const struct dev_pm_ops rt5514_i2_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume) + SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume) }; static struct i2c_driver rt5514_i2c_driver = { @@ -1321,7 +1321,7 @@ static struct i2c_driver rt5514_i2c_driver = { .name = "rt5514", .acpi_match_table = ACPI_PTR(rt5514_acpi_match), .of_match_table = of_match_ptr(rt5514_of_match), - .pm = &rt5514_i2_pm_ops, + .pm = pm_ptr(&rt5514_i2_pm_ops), }, .probe = rt5514_i2c_probe, .id_table = rt5514_i2c_id, From 71ba303a04ed5b314c88ed0c2eb771cf1df5d215 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:57 +0100 Subject: [PATCH 547/651] ASoC: rt5645: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-36-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt5645.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 2680bcce4c95..343e3bcef0ca 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -4314,7 +4314,7 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c) gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0); } -static int __maybe_unused rt5645_sys_suspend(struct device *dev) +static int rt5645_sys_suspend(struct device *dev) { struct rt5645_priv *rt5645 = dev_get_drvdata(dev); @@ -4327,7 +4327,7 @@ static int __maybe_unused rt5645_sys_suspend(struct device *dev) return 0; } -static int __maybe_unused rt5645_sys_resume(struct device *dev) +static int rt5645_sys_resume(struct device *dev) { struct rt5645_priv *rt5645 = dev_get_drvdata(dev); @@ -4342,7 +4342,7 @@ static int __maybe_unused rt5645_sys_resume(struct device *dev) } static const struct dev_pm_ops rt5645_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt5645_sys_suspend, rt5645_sys_resume) + SYSTEM_SLEEP_PM_OPS(rt5645_sys_suspend, rt5645_sys_resume) }; static struct i2c_driver rt5645_i2c_driver = { @@ -4350,7 +4350,7 @@ static struct i2c_driver rt5645_i2c_driver = { .name = "rt5645", .of_match_table = of_match_ptr(rt5645_of_match), .acpi_match_table = ACPI_PTR(rt5645_acpi_match), - .pm = &rt5645_pm, + .pm = pm_ptr(&rt5645_pm), }, .probe = rt5645_i2c_probe, .remove = rt5645_i2c_remove, From ef57148d2cea0c267504642eaff36da3df953496 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:58 +0100 Subject: [PATCH 548/651] ASoC: rt5682-sdw: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-37-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682-sdw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index 5edf11e136b4..aa229894129b 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -709,7 +709,7 @@ static const struct sdw_device_id rt5682_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt5682_id); -static int __maybe_unused rt5682_dev_suspend(struct device *dev) +static int rt5682_dev_suspend(struct device *dev) { struct rt5682_priv *rt5682 = dev_get_drvdata(dev); @@ -725,7 +725,7 @@ static int __maybe_unused rt5682_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt5682_dev_system_suspend(struct device *dev) +static int rt5682_dev_system_suspend(struct device *dev) { struct rt5682_priv *rt5682 = dev_get_drvdata(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev); @@ -753,7 +753,7 @@ static int __maybe_unused rt5682_dev_system_suspend(struct device *dev) return rt5682_dev_suspend(dev); } -static int __maybe_unused rt5682_dev_resume(struct device *dev) +static int rt5682_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt5682_priv *rt5682 = dev_get_drvdata(dev); @@ -791,14 +791,14 @@ regmap_sync: } static const struct dev_pm_ops rt5682_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt5682_dev_system_suspend, rt5682_dev_resume) - SET_RUNTIME_PM_OPS(rt5682_dev_suspend, rt5682_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt5682_dev_system_suspend, rt5682_dev_resume) + RUNTIME_PM_OPS(rt5682_dev_suspend, rt5682_dev_resume, NULL) }; static struct sdw_driver rt5682_sdw_driver = { .driver = { .name = "rt5682", - .pm = &rt5682_pm, + .pm = pm_ptr(&rt5682_pm), }, .probe = rt5682_sdw_probe, .remove = rt5682_sdw_remove, From 569f75535df2d2cdc5197033c9955bedcd2f50e6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:54:59 +0100 Subject: [PATCH 549/651] ASoC: rt700-sdw: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-38-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt700-sdw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index 24cb895b759f..44543c0da177 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -475,7 +475,7 @@ static const struct sdw_device_id rt700_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt700_id); -static int __maybe_unused rt700_dev_suspend(struct device *dev) +static int rt700_dev_suspend(struct device *dev) { struct rt700_priv *rt700 = dev_get_drvdata(dev); @@ -490,7 +490,7 @@ static int __maybe_unused rt700_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt700_dev_system_suspend(struct device *dev) +static int rt700_dev_system_suspend(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt700_priv *rt700 = dev_get_drvdata(dev); @@ -520,7 +520,7 @@ static int __maybe_unused rt700_dev_system_suspend(struct device *dev) #define RT700_PROBE_TIMEOUT 5000 -static int __maybe_unused rt700_dev_resume(struct device *dev) +static int rt700_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt700_priv *rt700 = dev_get_drvdata(dev); @@ -551,14 +551,14 @@ regmap_sync: } static const struct dev_pm_ops rt700_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt700_dev_system_suspend, rt700_dev_resume) - SET_RUNTIME_PM_OPS(rt700_dev_suspend, rt700_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt700_dev_system_suspend, rt700_dev_resume) + RUNTIME_PM_OPS(rt700_dev_suspend, rt700_dev_resume, NULL) }; static struct sdw_driver rt700_sdw_driver = { .driver = { .name = "rt700", - .pm = &rt700_pm, + .pm = pm_ptr(&rt700_pm), }, .probe = rt700_sdw_probe, .remove = rt700_sdw_remove, From 98cdea5b7acd06e7b188ce40c7450a6240d1d0a8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:00 +0100 Subject: [PATCH 550/651] ASoC: rt711: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-39-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdca-sdw.c | 12 ++++++------ sound/soc/codecs/rt711-sdw.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c index f5933d2e085e..adf05f64259b 100644 --- a/sound/soc/codecs/rt711-sdca-sdw.c +++ b/sound/soc/codecs/rt711-sdca-sdw.c @@ -380,7 +380,7 @@ static const struct sdw_device_id rt711_sdca_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt711_sdca_id); -static int __maybe_unused rt711_sdca_dev_suspend(struct device *dev) +static int rt711_sdca_dev_suspend(struct device *dev) { struct rt711_sdca_priv *rt711 = dev_get_drvdata(dev); @@ -396,7 +396,7 @@ static int __maybe_unused rt711_sdca_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt711_sdca_dev_system_suspend(struct device *dev) +static int rt711_sdca_dev_system_suspend(struct device *dev) { struct rt711_sdca_priv *rt711_sdca = dev_get_drvdata(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev); @@ -428,7 +428,7 @@ static int __maybe_unused rt711_sdca_dev_system_suspend(struct device *dev) #define RT711_PROBE_TIMEOUT 5000 -static int __maybe_unused rt711_sdca_dev_resume(struct device *dev) +static int rt711_sdca_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt711_sdca_priv *rt711 = dev_get_drvdata(dev); @@ -467,14 +467,14 @@ regmap_sync: } static const struct dev_pm_ops rt711_sdca_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt711_sdca_dev_system_suspend, rt711_sdca_dev_resume) - SET_RUNTIME_PM_OPS(rt711_sdca_dev_suspend, rt711_sdca_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt711_sdca_dev_system_suspend, rt711_sdca_dev_resume) + RUNTIME_PM_OPS(rt711_sdca_dev_suspend, rt711_sdca_dev_resume, NULL) }; static struct sdw_driver rt711_sdca_sdw_driver = { .driver = { .name = "rt711-sdca", - .pm = &rt711_sdca_pm, + .pm = pm_ptr(&rt711_sdca_pm), }, .probe = rt711_sdca_sdw_probe, .remove = rt711_sdca_sdw_remove, diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index dfda6bb5c6f8..93a5a89a96b1 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -482,7 +482,7 @@ static const struct sdw_device_id rt711_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt711_id); -static int __maybe_unused rt711_dev_suspend(struct device *dev) +static int rt711_dev_suspend(struct device *dev) { struct rt711_priv *rt711 = dev_get_drvdata(dev); @@ -498,7 +498,7 @@ static int __maybe_unused rt711_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt711_dev_system_suspend(struct device *dev) +static int rt711_dev_system_suspend(struct device *dev) { struct rt711_priv *rt711 = dev_get_drvdata(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev); @@ -528,7 +528,7 @@ static int __maybe_unused rt711_dev_system_suspend(struct device *dev) #define RT711_PROBE_TIMEOUT 5000 -static int __maybe_unused rt711_dev_resume(struct device *dev) +static int rt711_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt711_priv *rt711 = dev_get_drvdata(dev); @@ -564,14 +564,14 @@ regmap_sync: } static const struct dev_pm_ops rt711_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt711_dev_system_suspend, rt711_dev_resume) - SET_RUNTIME_PM_OPS(rt711_dev_suspend, rt711_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt711_dev_system_suspend, rt711_dev_resume) + RUNTIME_PM_OPS(rt711_dev_suspend, rt711_dev_resume, NULL) }; static struct sdw_driver rt711_sdw_driver = { .driver = { .name = "rt711", - .pm = &rt711_pm, + .pm = pm_ptr(&rt711_pm), }, .probe = rt711_sdw_probe, .remove = rt711_sdw_remove, From e4efc3694d8ab8cd7c0f230556d8457ad8d34899 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:01 +0100 Subject: [PATCH 551/651] ASoC: rt712: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-40-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt712-sdca-dmic.c | 12 ++++++------ sound/soc/codecs/rt712-sdca-sdw.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/rt712-sdca-dmic.c b/sound/soc/codecs/rt712-sdca-dmic.c index ee5435f3a80a..db011da63bd9 100644 --- a/sound/soc/codecs/rt712-sdca-dmic.c +++ b/sound/soc/codecs/rt712-sdca-dmic.c @@ -884,7 +884,7 @@ static const struct sdw_device_id rt712_sdca_dmic_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt712_sdca_dmic_id); -static int __maybe_unused rt712_sdca_dmic_dev_suspend(struct device *dev) +static int rt712_sdca_dmic_dev_suspend(struct device *dev) { struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(dev); @@ -897,7 +897,7 @@ static int __maybe_unused rt712_sdca_dmic_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt712_sdca_dmic_dev_system_suspend(struct device *dev) +static int rt712_sdca_dmic_dev_system_suspend(struct device *dev) { struct rt712_sdca_dmic_priv *rt712_sdca = dev_get_drvdata(dev); @@ -909,7 +909,7 @@ static int __maybe_unused rt712_sdca_dmic_dev_system_suspend(struct device *dev) #define RT712_PROBE_TIMEOUT 5000 -static int __maybe_unused rt712_sdca_dmic_dev_resume(struct device *dev) +static int rt712_sdca_dmic_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(dev); @@ -941,8 +941,8 @@ regmap_sync: } static const struct dev_pm_ops rt712_sdca_dmic_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt712_sdca_dmic_dev_system_suspend, rt712_sdca_dmic_dev_resume) - SET_RUNTIME_PM_OPS(rt712_sdca_dmic_dev_suspend, rt712_sdca_dmic_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt712_sdca_dmic_dev_system_suspend, rt712_sdca_dmic_dev_resume) + RUNTIME_PM_OPS(rt712_sdca_dmic_dev_suspend, rt712_sdca_dmic_dev_resume, NULL) }; @@ -978,7 +978,7 @@ static int rt712_sdca_dmic_sdw_remove(struct sdw_slave *slave) static struct sdw_driver rt712_sdca_dmic_sdw_driver = { .driver = { .name = "rt712-sdca-dmic", - .pm = &rt712_sdca_dmic_pm, + .pm = pm_ptr(&rt712_sdca_dmic_pm), }, .probe = rt712_sdca_dmic_sdw_probe, .remove = rt712_sdca_dmic_sdw_remove, diff --git a/sound/soc/codecs/rt712-sdca-sdw.c b/sound/soc/codecs/rt712-sdca-sdw.c index b584a3f854b8..ea07131edfa2 100644 --- a/sound/soc/codecs/rt712-sdca-sdw.c +++ b/sound/soc/codecs/rt712-sdca-sdw.c @@ -400,7 +400,7 @@ static const struct sdw_device_id rt712_sdca_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt712_sdca_id); -static int __maybe_unused rt712_sdca_dev_suspend(struct device *dev) +static int rt712_sdca_dev_suspend(struct device *dev) { struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev); @@ -416,7 +416,7 @@ static int __maybe_unused rt712_sdca_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt712_sdca_dev_system_suspend(struct device *dev) +static int rt712_sdca_dev_system_suspend(struct device *dev) { struct rt712_sdca_priv *rt712_sdca = dev_get_drvdata(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev); @@ -448,7 +448,7 @@ static int __maybe_unused rt712_sdca_dev_system_suspend(struct device *dev) #define RT712_PROBE_TIMEOUT 5000 -static int __maybe_unused rt712_sdca_dev_resume(struct device *dev) +static int rt712_sdca_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev); @@ -488,14 +488,14 @@ regmap_sync: } static const struct dev_pm_ops rt712_sdca_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt712_sdca_dev_system_suspend, rt712_sdca_dev_resume) - SET_RUNTIME_PM_OPS(rt712_sdca_dev_suspend, rt712_sdca_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt712_sdca_dev_system_suspend, rt712_sdca_dev_resume) + RUNTIME_PM_OPS(rt712_sdca_dev_suspend, rt712_sdca_dev_resume, NULL) }; static struct sdw_driver rt712_sdca_sdw_driver = { .driver = { .name = "rt712-sdca", - .pm = &rt712_sdca_pm, + .pm = pm_ptr(&rt712_sdca_pm), }, .probe = rt712_sdca_sdw_probe, .remove = rt712_sdca_sdw_remove, From a83d01d19ef285f279331ffb7d4c6f9a37201c15 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:02 +0100 Subject: [PATCH 552/651] ASoC: rt715: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-41-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt715-sdca-sdw.c | 10 +++++----- sound/soc/codecs/rt715-sdw.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c index c8dabb9b16b5..ce7d8955efc3 100644 --- a/sound/soc/codecs/rt715-sdca-sdw.c +++ b/sound/soc/codecs/rt715-sdca-sdw.c @@ -205,7 +205,7 @@ static const struct sdw_device_id rt715_sdca_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt715_sdca_id); -static int __maybe_unused rt715_dev_suspend(struct device *dev) +static int rt715_dev_suspend(struct device *dev) { struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev); @@ -222,7 +222,7 @@ static int __maybe_unused rt715_dev_suspend(struct device *dev) #define RT715_PROBE_TIMEOUT 5000 -static int __maybe_unused rt715_dev_resume(struct device *dev) +static int rt715_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev); @@ -263,14 +263,14 @@ regmap_sync: } static const struct dev_pm_ops rt715_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt715_dev_suspend, rt715_dev_resume) - SET_RUNTIME_PM_OPS(rt715_dev_suspend, rt715_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt715_dev_suspend, rt715_dev_resume) + RUNTIME_PM_OPS(rt715_dev_suspend, rt715_dev_resume, NULL) }; static struct sdw_driver rt715_sdw_driver = { .driver = { .name = "rt715-sdca", - .pm = &rt715_pm, + .pm = pm_ptr(&rt715_pm), }, .probe = rt715_sdca_sdw_probe, .remove = rt715_sdca_sdw_remove, diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c index cd702574c84b..a3df4bbedf86 100644 --- a/sound/soc/codecs/rt715-sdw.c +++ b/sound/soc/codecs/rt715-sdw.c @@ -485,7 +485,7 @@ static const struct sdw_device_id rt715_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt715_id); -static int __maybe_unused rt715_dev_suspend(struct device *dev) +static int rt715_dev_suspend(struct device *dev) { struct rt715_priv *rt715 = dev_get_drvdata(dev); @@ -499,7 +499,7 @@ static int __maybe_unused rt715_dev_suspend(struct device *dev) #define RT715_PROBE_TIMEOUT 5000 -static int __maybe_unused rt715_dev_resume(struct device *dev) +static int rt715_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt715_priv *rt715 = dev_get_drvdata(dev); @@ -530,14 +530,14 @@ regmap_sync: } static const struct dev_pm_ops rt715_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt715_dev_suspend, rt715_dev_resume) - SET_RUNTIME_PM_OPS(rt715_dev_suspend, rt715_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt715_dev_suspend, rt715_dev_resume) + RUNTIME_PM_OPS(rt715_dev_suspend, rt715_dev_resume, NULL) }; static struct sdw_driver rt715_sdw_driver = { .driver = { .name = "rt715", - .pm = &rt715_pm, + .pm = pm_ptr(&rt715_pm), }, .probe = rt715_sdw_probe, .remove = rt715_sdw_remove, From 8798eaedd6d756ea58832e222840b2e387707ede Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:03 +0100 Subject: [PATCH 553/651] ASoC: rt721: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-42-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt721-sdca-sdw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/rt721-sdca-sdw.c b/sound/soc/codecs/rt721-sdca-sdw.c index c71453da088a..582b47d69278 100644 --- a/sound/soc/codecs/rt721-sdca-sdw.c +++ b/sound/soc/codecs/rt721-sdca-sdw.c @@ -437,7 +437,7 @@ static const struct sdw_device_id rt721_sdca_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt721_sdca_id); -static int __maybe_unused rt721_sdca_dev_suspend(struct device *dev) +static int rt721_sdca_dev_suspend(struct device *dev) { struct rt721_sdca_priv *rt721 = dev_get_drvdata(dev); @@ -453,7 +453,7 @@ static int __maybe_unused rt721_sdca_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt721_sdca_dev_system_suspend(struct device *dev) +static int rt721_sdca_dev_system_suspend(struct device *dev) { struct rt721_sdca_priv *rt721_sdca = dev_get_drvdata(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev); @@ -485,7 +485,7 @@ static int __maybe_unused rt721_sdca_dev_system_suspend(struct device *dev) #define RT721_PROBE_TIMEOUT 5000 -static int __maybe_unused rt721_sdca_dev_resume(struct device *dev) +static int rt721_sdca_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt721_sdca_priv *rt721 = dev_get_drvdata(dev); @@ -524,15 +524,15 @@ regmap_sync: } static const struct dev_pm_ops rt721_sdca_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt721_sdca_dev_system_suspend, rt721_sdca_dev_resume) - SET_RUNTIME_PM_OPS(rt721_sdca_dev_suspend, rt721_sdca_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt721_sdca_dev_system_suspend, rt721_sdca_dev_resume) + RUNTIME_PM_OPS(rt721_sdca_dev_suspend, rt721_sdca_dev_resume, NULL) }; static struct sdw_driver rt721_sdca_sdw_driver = { .driver = { .name = "rt721-sdca", .owner = THIS_MODULE, - .pm = &rt721_sdca_pm, + .pm = pm_ptr(&rt721_sdca_pm), }, .probe = rt721_sdca_sdw_probe, .remove = rt721_sdca_sdw_remove, From 957e8cb375e60699c7acf52c771fad5979cef359 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:04 +0100 Subject: [PATCH 554/651] ASoC: rt722: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-43-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt722-sdca-sdw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c index 543cb32c2463..11e2e8f68a98 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.c +++ b/sound/soc/codecs/rt722-sdca-sdw.c @@ -430,7 +430,7 @@ static const struct sdw_device_id rt722_sdca_id[] = { }; MODULE_DEVICE_TABLE(sdw, rt722_sdca_id); -static int __maybe_unused rt722_sdca_dev_suspend(struct device *dev) +static int rt722_sdca_dev_suspend(struct device *dev) { struct rt722_sdca_priv *rt722 = dev_get_drvdata(dev); @@ -445,7 +445,7 @@ static int __maybe_unused rt722_sdca_dev_suspend(struct device *dev) return 0; } -static int __maybe_unused rt722_sdca_dev_system_suspend(struct device *dev) +static int rt722_sdca_dev_system_suspend(struct device *dev) { struct rt722_sdca_priv *rt722_sdca = dev_get_drvdata(dev); struct sdw_slave *slave = dev_to_sdw_dev(dev); @@ -477,7 +477,7 @@ static int __maybe_unused rt722_sdca_dev_system_suspend(struct device *dev) #define RT722_PROBE_TIMEOUT 5000 -static int __maybe_unused rt722_sdca_dev_resume(struct device *dev) +static int rt722_sdca_dev_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct rt722_sdca_priv *rt722 = dev_get_drvdata(dev); @@ -514,14 +514,14 @@ regmap_sync: } static const struct dev_pm_ops rt722_sdca_pm = { - SET_SYSTEM_SLEEP_PM_OPS(rt722_sdca_dev_system_suspend, rt722_sdca_dev_resume) - SET_RUNTIME_PM_OPS(rt722_sdca_dev_suspend, rt722_sdca_dev_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rt722_sdca_dev_system_suspend, rt722_sdca_dev_resume) + RUNTIME_PM_OPS(rt722_sdca_dev_suspend, rt722_sdca_dev_resume, NULL) }; static struct sdw_driver rt722_sdca_sdw_driver = { .driver = { .name = "rt722-sdca", - .pm = &rt722_sdca_pm, + .pm = pm_ptr(&rt722_sdca_pm), }, .probe = rt722_sdca_sdw_probe, .remove = rt722_sdca_sdw_remove, From 9aaa57d36f387df01762ced4e362bcb89872d80b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:05 +0100 Subject: [PATCH 555/651] ASoC: rt9120: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-44-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rt9120.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rt9120.c b/sound/soc/codecs/rt9120.c index 733a7d130a95..97f56af25577 100644 --- a/sound/soc/codecs/rt9120.c +++ b/sound/soc/codecs/rt9120.c @@ -590,7 +590,7 @@ static void rt9120_remove(struct i2c_client *i2c) pm_runtime_set_suspended(&i2c->dev); } -static int __maybe_unused rt9120_runtime_suspend(struct device *dev) +static int rt9120_runtime_suspend(struct device *dev) { struct rt9120_data *data = dev_get_drvdata(dev); @@ -603,7 +603,7 @@ static int __maybe_unused rt9120_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused rt9120_runtime_resume(struct device *dev) +static int rt9120_runtime_resume(struct device *dev) { struct rt9120_data *data = dev_get_drvdata(dev); @@ -618,7 +618,7 @@ static int __maybe_unused rt9120_runtime_resume(struct device *dev) } static const struct dev_pm_ops rt9120_pm_ops = { - SET_RUNTIME_PM_OPS(rt9120_runtime_suspend, rt9120_runtime_resume, NULL) + RUNTIME_PM_OPS(rt9120_runtime_suspend, rt9120_runtime_resume, NULL) }; static const struct of_device_id __maybe_unused rt9120_device_table[] = { @@ -631,7 +631,7 @@ static struct i2c_driver rt9120_driver = { .driver = { .name = "rt9120", .of_match_table = rt9120_device_table, - .pm = &rt9120_pm_ops, + .pm = pm_ptr(&rt9120_pm_ops), }, .probe = rt9120_probe, .remove = rt9120_remove, From 9eb264d115a55eb40b55c7481c113e6c56560700 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:06 +0100 Subject: [PATCH 556/651] ASoC: rtq9128: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS(), which allows us dropping ugly __maybe_unsed attributes. Merely a cleanup, there should be no actual code change. Cc: Oder Chiou Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-45-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/rtq9128.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/rtq9128.c b/sound/soc/codecs/rtq9128.c index aa3eadecd974..391cc03d687f 100644 --- a/sound/soc/codecs/rtq9128.c +++ b/sound/soc/codecs/rtq9128.c @@ -729,7 +729,7 @@ static int rtq9128_probe(struct i2c_client *i2c) return devm_snd_soc_register_component(dev, &rtq9128_comp_driver, &rtq9128_dai, 1); } -static int __maybe_unused rtq9128_pm_runtime_suspend(struct device *dev) +static int rtq9128_pm_runtime_suspend(struct device *dev) { struct rtq9128_data *data = dev_get_drvdata(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); @@ -746,7 +746,7 @@ static int __maybe_unused rtq9128_pm_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused rtq9128_pm_runtime_resume(struct device *dev) +static int rtq9128_pm_runtime_resume(struct device *dev) { struct rtq9128_data *data = dev_get_drvdata(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); @@ -764,8 +764,8 @@ static int __maybe_unused rtq9128_pm_runtime_resume(struct device *dev) return regcache_sync(regmap); } -static const struct dev_pm_ops __maybe_unused rtq9128_pm_ops = { - SET_RUNTIME_PM_OPS(rtq9128_pm_runtime_suspend, rtq9128_pm_runtime_resume, NULL) +static const struct dev_pm_ops rtq9128_pm_ops = { + RUNTIME_PM_OPS(rtq9128_pm_runtime_suspend, rtq9128_pm_runtime_resume, NULL) }; static const struct of_device_id rtq9128_device_table[] = { From 1570c33f2f38b6dff04ee1c7d7b38d1702e81b5f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:07 +0100 Subject: [PATCH 557/651] ASoC: tas2552: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Shenghao Ding Cc: Kevin Lu Cc: Baojun Xu Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-46-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/tas2552.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 684d52ec6600..b56dd279d90a 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -138,7 +138,6 @@ static const struct snd_soc_dapm_route tas2552_audio_map[] = { {"ASI OUT", NULL, "DMIC"} }; -#ifdef CONFIG_PM static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown) { u8 cfg1_reg = 0; @@ -152,7 +151,6 @@ static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown) snd_soc_component_update_bits(tas2552->component, TAS2552_CFG_1, TAS2552_SWS, cfg1_reg); } -#endif static int tas2552_setup_pll(struct snd_soc_component *component, struct snd_pcm_hw_params *params) @@ -480,7 +478,6 @@ static int tas2552_mute(struct snd_soc_dai *dai, int mute, int direction) return 0; } -#ifdef CONFIG_PM static int tas2552_runtime_suspend(struct device *dev) { struct tas2552_data *tas2552 = dev_get_drvdata(dev); @@ -508,11 +505,9 @@ static int tas2552_runtime_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops tas2552_pm = { - SET_RUNTIME_PM_OPS(tas2552_runtime_suspend, tas2552_runtime_resume, - NULL) + RUNTIME_PM_OPS(tas2552_runtime_suspend, tas2552_runtime_resume, NULL) }; static const struct snd_soc_dai_ops tas2552_speaker_dai_ops = { @@ -768,7 +763,7 @@ static struct i2c_driver tas2552_i2c_driver = { .driver = { .name = "tas2552", .of_match_table = of_match_ptr(tas2552_of_match), - .pm = &tas2552_pm, + .pm = pm_ptr(&tas2552_pm), }, .probe = tas2552_probe, .remove = tas2552_i2c_remove, From 2db8e2c7c6f9cccfdcb1c710b9b3008b73eb5505 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:08 +0100 Subject: [PATCH 558/651] ASoC: ts3a227e: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-47-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/ts3a227e.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c index b9eb59e3bfa0..5ce0db9326fd 100644 --- a/sound/soc/codecs/ts3a227e.c +++ b/sound/soc/codecs/ts3a227e.c @@ -399,7 +399,6 @@ static int ts3a227e_i2c_probe(struct i2c_client *i2c) return 0; } -#ifdef CONFIG_PM_SLEEP static int ts3a227e_suspend(struct device *dev) { struct ts3a227e *ts3a227e = dev_get_drvdata(dev); @@ -419,10 +418,9 @@ static int ts3a227e_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops ts3a227e_pm = { - SET_SYSTEM_SLEEP_PM_OPS(ts3a227e_suspend, ts3a227e_resume) + SYSTEM_SLEEP_PM_OPS(ts3a227e_suspend, ts3a227e_resume) }; static const struct i2c_device_id ts3a227e_i2c_ids[] = { @@ -450,7 +448,7 @@ MODULE_DEVICE_TABLE(acpi, ts3a227e_acpi_match); static struct i2c_driver ts3a227e_driver = { .driver = { .name = "ts3a227e", - .pm = &ts3a227e_pm, + .pm = pm_ptr(&ts3a227e_pm), .of_match_table = of_match_ptr(ts3a227e_of_match), .acpi_match_table = ACPI_PTR(ts3a227e_acpi_match), }, From 40a3111b8f18640885ad2041d52dc1d429cf60b1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:09 +0100 Subject: [PATCH 559/651] ASoC: wcd937x: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-48-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wcd937x-sdw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wcd937x-sdw.c b/sound/soc/codecs/wcd937x-sdw.c index 4891fa0c963f..1bfe7383b311 100644 --- a/sound/soc/codecs/wcd937x-sdw.c +++ b/sound/soc/codecs/wcd937x-sdw.c @@ -1124,7 +1124,7 @@ static const struct sdw_device_id wcd9370_slave_id[] = { }; MODULE_DEVICE_TABLE(sdw, wcd9370_slave_id); -static int __maybe_unused wcd937x_sdw_runtime_suspend(struct device *dev) +static int wcd937x_sdw_runtime_suspend(struct device *dev) { struct wcd937x_sdw_priv *wcd = dev_get_drvdata(dev); @@ -1136,7 +1136,7 @@ static int __maybe_unused wcd937x_sdw_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused wcd937x_sdw_runtime_resume(struct device *dev) +static int wcd937x_sdw_runtime_resume(struct device *dev) { struct wcd937x_sdw_priv *wcd = dev_get_drvdata(dev); @@ -1149,7 +1149,7 @@ static int __maybe_unused wcd937x_sdw_runtime_resume(struct device *dev) } static const struct dev_pm_ops wcd937x_sdw_pm_ops = { - SET_RUNTIME_PM_OPS(wcd937x_sdw_runtime_suspend, wcd937x_sdw_runtime_resume, NULL) + RUNTIME_PM_OPS(wcd937x_sdw_runtime_suspend, wcd937x_sdw_runtime_resume, NULL) }; static struct sdw_driver wcd9370_codec_driver = { @@ -1159,7 +1159,7 @@ static struct sdw_driver wcd9370_codec_driver = { .id_table = wcd9370_slave_id, .driver = { .name = "wcd9370-codec", - .pm = &wcd937x_sdw_pm_ops, + .pm = pm_ptr(&wcd937x_sdw_pm_ops), } }; module_sdw_driver(wcd9370_codec_driver); From a0f0a8814ab4167992f958e804051ea4791b8603 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:10 +0100 Subject: [PATCH 560/651] ASoC: wcd938x: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-49-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x-sdw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c index 4e2ae542cee3..cabddadc90ef 100644 --- a/sound/soc/codecs/wcd938x-sdw.c +++ b/sound/soc/codecs/wcd938x-sdw.c @@ -1311,7 +1311,7 @@ static const struct sdw_device_id wcd9380_slave_id[] = { }; MODULE_DEVICE_TABLE(sdw, wcd9380_slave_id); -static int __maybe_unused wcd938x_sdw_runtime_suspend(struct device *dev) +static int wcd938x_sdw_runtime_suspend(struct device *dev) { struct wcd938x_sdw_priv *wcd = dev_get_drvdata(dev); @@ -1323,7 +1323,7 @@ static int __maybe_unused wcd938x_sdw_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused wcd938x_sdw_runtime_resume(struct device *dev) +static int wcd938x_sdw_runtime_resume(struct device *dev) { struct wcd938x_sdw_priv *wcd = dev_get_drvdata(dev); @@ -1338,7 +1338,7 @@ static int __maybe_unused wcd938x_sdw_runtime_resume(struct device *dev) } static const struct dev_pm_ops wcd938x_sdw_pm_ops = { - SET_RUNTIME_PM_OPS(wcd938x_sdw_runtime_suspend, wcd938x_sdw_runtime_resume, NULL) + RUNTIME_PM_OPS(wcd938x_sdw_runtime_suspend, wcd938x_sdw_runtime_resume, NULL) }; @@ -1349,7 +1349,7 @@ static struct sdw_driver wcd9380_codec_driver = { .id_table = wcd9380_slave_id, .driver = { .name = "wcd9380-codec", - .pm = &wcd938x_sdw_pm_ops, + .pm = pm_ptr(&wcd938x_sdw_pm_ops), } }; module_sdw_driver(wcd9380_codec_driver); From 6714a569c839c658f882b2f38bbe430a8778f261 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:11 +0100 Subject: [PATCH 561/651] ASoC: wcd939x: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-50-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wcd939x-sdw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wcd939x-sdw.c b/sound/soc/codecs/wcd939x-sdw.c index 36868fad3e8b..f7a9323a9fea 100644 --- a/sound/soc/codecs/wcd939x-sdw.c +++ b/sound/soc/codecs/wcd939x-sdw.c @@ -1507,7 +1507,7 @@ static const struct sdw_device_id wcd9390_slave_id[] = { }; MODULE_DEVICE_TABLE(sdw, wcd9390_slave_id); -static int __maybe_unused wcd939x_sdw_runtime_suspend(struct device *dev) +static int wcd939x_sdw_runtime_suspend(struct device *dev) { struct wcd939x_sdw_priv *wcd = dev_get_drvdata(dev); @@ -1519,7 +1519,7 @@ static int __maybe_unused wcd939x_sdw_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused wcd939x_sdw_runtime_resume(struct device *dev) +static int wcd939x_sdw_runtime_resume(struct device *dev) { struct wcd939x_sdw_priv *wcd = dev_get_drvdata(dev); @@ -1532,7 +1532,7 @@ static int __maybe_unused wcd939x_sdw_runtime_resume(struct device *dev) } static const struct dev_pm_ops wcd939x_sdw_pm_ops = { - SET_RUNTIME_PM_OPS(wcd939x_sdw_runtime_suspend, wcd939x_sdw_runtime_resume, NULL) + RUNTIME_PM_OPS(wcd939x_sdw_runtime_suspend, wcd939x_sdw_runtime_resume, NULL) }; static struct sdw_driver wcd9390_codec_driver = { @@ -1542,7 +1542,7 @@ static struct sdw_driver wcd9390_codec_driver = { .id_table = wcd9390_slave_id, .driver = { .name = "wcd9390-codec", - .pm = &wcd939x_sdw_pm_ops, + .pm = pm_ptr(&wcd939x_sdw_pm_ops), } }; module_sdw_driver(wcd9390_codec_driver); From 208a479d039202681f1b80a5ccbb2c72a494b55b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:12 +0100 Subject: [PATCH 562/651] ASoC: wm2200: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes and superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-51-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wm2200.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 7ed4ac5cce3c..87418c838ca0 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -2429,7 +2429,6 @@ static void wm2200_i2c_remove(struct i2c_client *i2c) wm2200->core_supplies); } -#ifdef CONFIG_PM static int wm2200_runtime_suspend(struct device *dev) { struct wm2200_priv *wm2200 = dev_get_drvdata(dev); @@ -2466,11 +2465,9 @@ static int wm2200_runtime_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops wm2200_pm = { - SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume, - NULL) + RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume, NULL) }; static const struct i2c_device_id wm2200_i2c_id[] = { @@ -2482,7 +2479,7 @@ MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id); static struct i2c_driver wm2200_i2c_driver = { .driver = { .name = "wm2200", - .pm = &wm2200_pm, + .pm = pm_ptr(&wm2200_pm), }, .probe = wm2200_i2c_probe, .remove = wm2200_i2c_remove, From adcb5d32f7318b21d2a94d9542307801cb5e08c0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:13 +0100 Subject: [PATCH 563/651] ASoC: wm5100: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-52-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wm5100.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index dfeec55159a6..d9e5762324df 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2625,7 +2625,6 @@ static void wm5100_i2c_remove(struct i2c_client *i2c) gpiod_set_value_cansleep(wm5100->ldo_ena, 0); } -#ifdef CONFIG_PM static int wm5100_runtime_suspend(struct device *dev) { struct wm5100_priv *wm5100 = dev_get_drvdata(dev); @@ -2662,11 +2661,9 @@ static int wm5100_runtime_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops wm5100_pm = { - SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume, - NULL) + RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume, NULL) }; static const struct i2c_device_id wm5100_i2c_id[] = { @@ -2678,7 +2675,7 @@ MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id); static struct i2c_driver wm5100_i2c_driver = { .driver = { .name = "wm5100", - .pm = &wm5100_pm, + .pm = pm_ptr(&wm5100_pm), }, .probe = wm5100_i2c_probe, .remove = wm5100_i2c_remove, From 30200e61f8b8a72cf87f7ccd407c54049288f7be Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:14 +0100 Subject: [PATCH 564/651] ASoC: wm8804: Convert to EXPORT_GPL_DEV_PM_OPS() Use the newer EXPORT_GPL_DEV_PM_OPS() macro together with pm_ptr(), which allows us to drop superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-53-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wm8804-i2c.c | 2 +- sound/soc/codecs/wm8804-spi.c | 2 +- sound/soc/codecs/wm8804.c | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/wm8804-i2c.c b/sound/soc/codecs/wm8804-i2c.c index e80dad87219b..3380d7301b17 100644 --- a/sound/soc/codecs/wm8804-i2c.c +++ b/sound/soc/codecs/wm8804-i2c.c @@ -56,7 +56,7 @@ MODULE_DEVICE_TABLE(acpi, wm8804_acpi_match); static struct i2c_driver wm8804_i2c_driver = { .driver = { .name = "wm8804", - .pm = &wm8804_pm, + .pm = pm_ptr(&wm8804_pm), .of_match_table = of_match_ptr(wm8804_of_match), .acpi_match_table = ACPI_PTR(wm8804_acpi_match), }, diff --git a/sound/soc/codecs/wm8804-spi.c b/sound/soc/codecs/wm8804-spi.c index 628568724c20..cf74abfb1a2c 100644 --- a/sound/soc/codecs/wm8804-spi.c +++ b/sound/soc/codecs/wm8804-spi.c @@ -38,7 +38,7 @@ MODULE_DEVICE_TABLE(of, wm8804_of_match); static struct spi_driver wm8804_spi_driver = { .driver = { .name = "wm8804", - .pm = &wm8804_pm, + .pm = pm_ptr(&wm8804_pm), .of_match_table = wm8804_of_match, }, .probe = wm8804_spi_probe, diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 0a879c29eb04..48700cc25cb0 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -680,7 +680,6 @@ void wm8804_remove(struct device *dev) } EXPORT_SYMBOL_GPL(wm8804_remove); -#if IS_ENABLED(CONFIG_PM) static int wm8804_runtime_resume(struct device *dev) { struct wm8804_priv *wm8804 = dev_get_drvdata(dev); @@ -713,12 +712,10 @@ static int wm8804_runtime_suspend(struct device *dev) return 0; } -#endif -const struct dev_pm_ops wm8804_pm = { - SET_RUNTIME_PM_OPS(wm8804_runtime_suspend, wm8804_runtime_resume, NULL) +EXPORT_GPL_DEV_PM_OPS(wm8804_pm) = { + RUNTIME_PM_OPS(wm8804_runtime_suspend, wm8804_runtime_resume, NULL) }; -EXPORT_SYMBOL_GPL(wm8804_pm); MODULE_DESCRIPTION("ASoC WM8804 driver"); MODULE_AUTHOR("Dimitris Papastamos "); From 327e7dd45cea34e7a1334fcc35b9e122c05b181f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:15 +0100 Subject: [PATCH 565/651] ASoC: wm8962: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-54-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 0aaac24eeb5a..68f746626c33 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3850,7 +3850,6 @@ static void wm8962_i2c_remove(struct i2c_client *client) pm_runtime_disable(&client->dev); } -#ifdef CONFIG_PM static int wm8962_runtime_resume(struct device *dev) { struct wm8962_priv *wm8962 = dev_get_drvdata(dev); @@ -3930,11 +3929,10 @@ static int wm8962_runtime_suspend(struct device *dev) return 0; } -#endif static const struct dev_pm_ops wm8962_pm = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL) }; static const struct i2c_device_id wm8962_i2c_id[] = { @@ -3953,7 +3951,7 @@ static struct i2c_driver wm8962_i2c_driver = { .driver = { .name = "wm8962", .of_match_table = wm8962_of_match, - .pm = &wm8962_pm, + .pm = pm_ptr(&wm8962_pm), }, .probe = wm8962_i2c_probe, .remove = wm8962_i2c_remove, From ae5ad50b9fead07c8336a606ac36fbca9c73790d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:16 +0100 Subject: [PATCH 566/651] ASoC: wm8994: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us superfluous CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: patches@opensource.cirrus.com Reviewed-by: Charles Keepax Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-55-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 69a22992c281..240ec1bed234 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4662,7 +4662,6 @@ static void wm8994_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static int wm8994_suspend(struct device *dev) { struct wm8994_priv *wm8994 = dev_get_drvdata(dev); @@ -4687,16 +4686,15 @@ static int wm8994_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops wm8994_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume) + SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume) }; static struct platform_driver wm8994_codec_driver = { .driver = { .name = "wm8994-codec", - .pm = &wm8994_pm_ops, + .pm = pm_ptr(&wm8994_pm_ops), }, .probe = wm8994_probe, .remove = wm8994_remove, From 6fb2ff498d5a2a06998e1bd61b0954fd71e6d718 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:17 +0100 Subject: [PATCH 567/651] ASoC: wsa881x: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Srinivas Kandagatla Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-56-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wsa881x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index a3999bb6d5e2..6627d2da3722 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1169,7 +1169,7 @@ static int wsa881x_probe(struct sdw_slave *pdev, ARRAY_SIZE(wsa881x_dais)); } -static int __maybe_unused wsa881x_runtime_suspend(struct device *dev) +static int wsa881x_runtime_suspend(struct device *dev) { struct regmap *regmap = dev_get_regmap(dev, NULL); struct wsa881x_priv *wsa881x = dev_get_drvdata(dev); @@ -1182,7 +1182,7 @@ static int __maybe_unused wsa881x_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused wsa881x_runtime_resume(struct device *dev) +static int wsa881x_runtime_resume(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); @@ -1206,7 +1206,7 @@ static int __maybe_unused wsa881x_runtime_resume(struct device *dev) } static const struct dev_pm_ops wsa881x_pm_ops = { - SET_RUNTIME_PM_OPS(wsa881x_runtime_suspend, wsa881x_runtime_resume, NULL) + RUNTIME_PM_OPS(wsa881x_runtime_suspend, wsa881x_runtime_resume, NULL) }; static const struct sdw_device_id wsa881x_slave_id[] = { @@ -1222,7 +1222,7 @@ static struct sdw_driver wsa881x_codec_driver = { .id_table = wsa881x_slave_id, .driver = { .name = "wsa881x-codec", - .pm = &wsa881x_pm_ops, + .pm = pm_ptr(&wsa881x_pm_ops), } }; module_sdw_driver(wsa881x_codec_driver); From d09125c2c68cc95c300e2a63a04b9a3d37ba64ad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:18 +0100 Subject: [PATCH 568/651] ASoC: wsa883x: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Srinivas Kandagatla Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-57-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index a5a6cb90bb43..d259e1d4d83d 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1636,7 +1636,7 @@ err: } -static int __maybe_unused wsa883x_runtime_suspend(struct device *dev) +static int wsa883x_runtime_suspend(struct device *dev) { struct regmap *regmap = dev_get_regmap(dev, NULL); @@ -1646,7 +1646,7 @@ static int __maybe_unused wsa883x_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused wsa883x_runtime_resume(struct device *dev) +static int wsa883x_runtime_resume(struct device *dev) { struct regmap *regmap = dev_get_regmap(dev, NULL); @@ -1657,7 +1657,7 @@ static int __maybe_unused wsa883x_runtime_resume(struct device *dev) } static const struct dev_pm_ops wsa883x_pm_ops = { - SET_RUNTIME_PM_OPS(wsa883x_runtime_suspend, wsa883x_runtime_resume, NULL) + RUNTIME_PM_OPS(wsa883x_runtime_suspend, wsa883x_runtime_resume, NULL) }; static const struct sdw_device_id wsa883x_swr_id[] = { @@ -1670,7 +1670,7 @@ MODULE_DEVICE_TABLE(sdw, wsa883x_swr_id); static struct sdw_driver wsa883x_codec_driver = { .driver = { .name = "wsa883x-codec", - .pm = &wsa883x_pm_ops, + .pm = pm_ptr(&wsa883x_pm_ops), .suppress_bind_attrs = true, }, .probe = wsa883x_probe, From 60c1c181139e2ebe138faafa4f5e4e695236c1f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:19 +0100 Subject: [PATCH 569/651] ASoC: wsa884x: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Srinivas Kandagatla Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-58-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/wsa884x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c index 560a2c04b695..8051483aa1ac 100644 --- a/sound/soc/codecs/wsa884x.c +++ b/sound/soc/codecs/wsa884x.c @@ -2136,7 +2136,7 @@ static int wsa884x_probe(struct sdw_slave *pdev, ARRAY_SIZE(wsa884x_dais)); } -static int __maybe_unused wsa884x_runtime_suspend(struct device *dev) +static int wsa884x_runtime_suspend(struct device *dev) { struct regmap *regmap = dev_get_regmap(dev, NULL); @@ -2146,7 +2146,7 @@ static int __maybe_unused wsa884x_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused wsa884x_runtime_resume(struct device *dev) +static int wsa884x_runtime_resume(struct device *dev) { struct regmap *regmap = dev_get_regmap(dev, NULL); @@ -2157,7 +2157,7 @@ static int __maybe_unused wsa884x_runtime_resume(struct device *dev) } static const struct dev_pm_ops wsa884x_pm_ops = { - SET_RUNTIME_PM_OPS(wsa884x_runtime_suspend, wsa884x_runtime_resume, NULL) + RUNTIME_PM_OPS(wsa884x_runtime_suspend, wsa884x_runtime_resume, NULL) }; static const struct sdw_device_id wsa884x_swr_id[] = { @@ -2169,7 +2169,7 @@ MODULE_DEVICE_TABLE(sdw, wsa884x_swr_id); static struct sdw_driver wsa884x_codec_driver = { .driver = { .name = "wsa884x-codec", - .pm = &wsa884x_pm_ops, + .pm = pm_ptr(&wsa884x_pm_ops), }, .probe = wsa884x_probe, .ops = &wsa884x_slave_ops, From fc12699cda764ea807db0b22db7f06d1acbabe8e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:20 +0100 Subject: [PATCH 570/651] ASoC: dwc: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-59-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/dwc/dwc-i2s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index 57b789d7fbed..4c4171bb3fbb 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -478,7 +478,6 @@ static const struct snd_soc_dai_ops dw_i2s_dai_ops = { .set_tdm_slot = dw_i2s_set_tdm_slot, }; -#ifdef CONFIG_PM static int dw_i2s_runtime_suspend(struct device *dev) { struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev); @@ -501,6 +500,7 @@ static int dw_i2s_runtime_resume(struct device *dev) return 0; } +#ifdef CONFIG_PM static int dw_i2s_suspend(struct snd_soc_component *component) { struct dw_i2s_dev *dev = snd_soc_component_get_drvdata(component); @@ -1084,7 +1084,7 @@ MODULE_DEVICE_TABLE(of, dw_i2s_of_match); #endif static const struct dev_pm_ops dwc_pm_ops = { - SET_RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL) + RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL) }; static struct platform_driver dw_i2s_driver = { @@ -1093,7 +1093,7 @@ static struct platform_driver dw_i2s_driver = { .driver = { .name = "designware-i2s", .of_match_table = of_match_ptr(dw_i2s_of_match), - .pm = &dwc_pm_ops, + .pm = pm_ptr(&dwc_pm_ops), }, }; From d1baa8193fd8cb8d0088851b468c9b0c5874ff42 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:21 +0100 Subject: [PATCH 571/651] ASoC: fsl: Convert to RUNTIME_PM_OPS() and co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr() This optimizes slightly when CONFIG_PM is disabled, too. Cc: Shengjiu Wang Cc: Xiubo Li Cc: Fabio Estevam Cc: Nicolin Chen Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-60-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_aud2htx.c | 3 +-- sound/soc/fsl/fsl_esai.c | 9 +++------ sound/soc/fsl/fsl_micfil.c | 9 +++------ sound/soc/fsl/fsl_sai.c | 8 +++----- sound/soc/fsl/fsl_xcvr.c | 3 +-- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/sound/soc/fsl/fsl_aud2htx.c b/sound/soc/fsl/fsl_aud2htx.c index bde642318835..da401561e2de 100644 --- a/sound/soc/fsl/fsl_aud2htx.c +++ b/sound/soc/fsl/fsl_aud2htx.c @@ -290,8 +290,7 @@ static int fsl_aud2htx_runtime_resume(struct device *dev) static const struct dev_pm_ops fsl_aud2htx_pm_ops = { RUNTIME_PM_OPS(fsl_aud2htx_runtime_suspend, fsl_aud2htx_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver fsl_aud2htx_driver = { diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 0b247f16a163..cde0b0c6c1ef 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -1189,11 +1189,8 @@ static int fsl_esai_runtime_suspend(struct device *dev) } static const struct dev_pm_ops fsl_esai_pm_ops = { - SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend, - fsl_esai_runtime_resume, - NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(fsl_esai_runtime_suspend, fsl_esai_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver fsl_esai_driver = { @@ -1201,7 +1198,7 @@ static struct platform_driver fsl_esai_driver = { .remove = fsl_esai_remove, .driver = { .name = "fsl-esai-dai", - .pm = &fsl_esai_pm_ops, + .pm = pm_ptr(&fsl_esai_pm_ops), .of_match_table = fsl_esai_dt_ids, }, }; diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 73d8910a6188..aabd90a8b3ec 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -1512,11 +1512,8 @@ static int fsl_micfil_runtime_resume(struct device *dev) } static const struct dev_pm_ops fsl_micfil_pm_ops = { - SET_RUNTIME_PM_OPS(fsl_micfil_runtime_suspend, - fsl_micfil_runtime_resume, - NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(fsl_micfil_runtime_suspend, fsl_micfil_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver fsl_micfil_driver = { @@ -1524,7 +1521,7 @@ static struct platform_driver fsl_micfil_driver = { .remove = fsl_micfil_remove, .driver = { .name = "fsl-micfil-dai", - .pm = &fsl_micfil_pm_ops, + .pm = pm_ptr(&fsl_micfil_pm_ops), .of_match_table = fsl_micfil_dt_ids, }, }; diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 9f33dd11d47f..ed2b4780c470 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1817,10 +1817,8 @@ disable_bus_clk: } static const struct dev_pm_ops fsl_sai_pm_ops = { - SET_RUNTIME_PM_OPS(fsl_sai_runtime_suspend, - fsl_sai_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(fsl_sai_runtime_suspend, fsl_sai_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver fsl_sai_driver = { @@ -1828,7 +1826,7 @@ static struct platform_driver fsl_sai_driver = { .remove = fsl_sai_remove, .driver = { .name = "fsl-sai", - .pm = &fsl_sai_pm_ops, + .pm = pm_ptr(&fsl_sai_pm_ops), .of_match_table = fsl_sai_ids, }, }; diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index c59c1af5a98a..83aea341c1b6 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -1821,8 +1821,7 @@ stop_ipg_clk: static const struct dev_pm_ops fsl_xcvr_pm_ops = { RUNTIME_PM_OPS(fsl_xcvr_runtime_suspend, fsl_xcvr_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver fsl_xcvr_driver = { From 5580e82d222668dd0a484af5612f1d9ae938f075 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:22 +0100 Subject: [PATCH 572/651] ASoC: img: Convert to RUNTIME_PM_OPS() and co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-61-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/img/img-i2s-in.c | 9 +++------ sound/soc/img/img-i2s-out.c | 9 +++------ sound/soc/img/img-parallel-out.c | 5 ++--- sound/soc/img/img-spdif-in.c | 9 +++------ sound/soc/img/img-spdif-out.c | 10 ++++------ sound/soc/img/pistachio-internal-dac.c | 8 +++----- 6 files changed, 18 insertions(+), 32 deletions(-) diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c index 6a988976fb0d..98d2ab68883a 100644 --- a/sound/soc/img/img-i2s-in.c +++ b/sound/soc/img/img-i2s-in.c @@ -539,7 +539,6 @@ static void img_i2s_in_dev_remove(struct platform_device *pdev) img_i2s_in_runtime_suspend(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static int img_i2s_in_suspend(struct device *dev) { struct img_i2s_in *i2s = dev_get_drvdata(dev); @@ -586,7 +585,6 @@ static int img_i2s_in_resume(struct device *dev) return 0; } -#endif static const struct of_device_id img_i2s_in_of_match[] = { { .compatible = "img,i2s-in" }, @@ -595,16 +593,15 @@ static const struct of_device_id img_i2s_in_of_match[] = { MODULE_DEVICE_TABLE(of, img_i2s_in_of_match); static const struct dev_pm_ops img_i2s_in_pm_ops = { - SET_RUNTIME_PM_OPS(img_i2s_in_runtime_suspend, - img_i2s_in_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(img_i2s_in_suspend, img_i2s_in_resume) + RUNTIME_PM_OPS(img_i2s_in_runtime_suspend, img_i2s_in_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(img_i2s_in_suspend, img_i2s_in_resume) }; static struct platform_driver img_i2s_in_driver = { .driver = { .name = "img-i2s-in", .of_match_table = img_i2s_in_of_match, - .pm = &img_i2s_in_pm_ops + .pm = pm_ptr(&img_i2s_in_pm_ops) }, .probe = img_i2s_in_probe, .remove = img_i2s_in_dev_remove diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index 1211e6184d97..aedcf56a5359 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -539,7 +539,6 @@ static void img_i2s_out_dev_remove(struct platform_device *pdev) img_i2s_out_runtime_suspend(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static int img_i2s_out_suspend(struct device *dev) { struct img_i2s_out *i2s = dev_get_drvdata(dev); @@ -586,7 +585,6 @@ static int img_i2s_out_resume(struct device *dev) return 0; } -#endif static const struct of_device_id img_i2s_out_of_match[] = { { .compatible = "img,i2s-out" }, @@ -595,16 +593,15 @@ static const struct of_device_id img_i2s_out_of_match[] = { MODULE_DEVICE_TABLE(of, img_i2s_out_of_match); static const struct dev_pm_ops img_i2s_out_pm_ops = { - SET_RUNTIME_PM_OPS(img_i2s_out_runtime_suspend, - img_i2s_out_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(img_i2s_out_suspend, img_i2s_out_resume) + RUNTIME_PM_OPS(img_i2s_out_runtime_suspend, img_i2s_out_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(img_i2s_out_suspend, img_i2s_out_resume) }; static struct platform_driver img_i2s_out_driver = { .driver = { .name = "img-i2s-out", .of_match_table = img_i2s_out_of_match, - .pm = &img_i2s_out_pm_ops + .pm = pm_ptr(&img_i2s_out_pm_ops) }, .probe = img_i2s_out_probe, .remove = img_i2s_out_dev_remove diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c index 4ec63119d67c..86b60e6dab38 100644 --- a/sound/soc/img/img-parallel-out.c +++ b/sound/soc/img/img-parallel-out.c @@ -300,15 +300,14 @@ static const struct of_device_id img_prl_out_of_match[] = { MODULE_DEVICE_TABLE(of, img_prl_out_of_match); static const struct dev_pm_ops img_prl_out_pm_ops = { - SET_RUNTIME_PM_OPS(img_prl_out_suspend, - img_prl_out_resume, NULL) + RUNTIME_PM_OPS(img_prl_out_suspend, img_prl_out_resume, NULL) }; static struct platform_driver img_prl_out_driver = { .driver = { .name = "img-parallel-out", .of_match_table = img_prl_out_of_match, - .pm = &img_prl_out_pm_ops + .pm = pm_ptr(&img_prl_out_pm_ops) }, .probe = img_prl_out_probe, .remove = img_prl_out_dev_remove diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c index 3c513f5b8c54..82295e2508fa 100644 --- a/sound/soc/img/img-spdif-in.c +++ b/sound/soc/img/img-spdif-in.c @@ -817,7 +817,6 @@ static void img_spdif_in_dev_remove(struct platform_device *pdev) img_spdif_in_runtime_suspend(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static int img_spdif_in_suspend(struct device *dev) { struct img_spdif_in *spdif = dev_get_drvdata(dev); @@ -857,7 +856,6 @@ static int img_spdif_in_resume(struct device *dev) return 0; } -#endif static const struct of_device_id img_spdif_in_of_match[] = { { .compatible = "img,spdif-in" }, @@ -866,16 +864,15 @@ static const struct of_device_id img_spdif_in_of_match[] = { MODULE_DEVICE_TABLE(of, img_spdif_in_of_match); static const struct dev_pm_ops img_spdif_in_pm_ops = { - SET_RUNTIME_PM_OPS(img_spdif_in_runtime_suspend, - img_spdif_in_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(img_spdif_in_suspend, img_spdif_in_resume) + RUNTIME_PM_OPS(img_spdif_in_runtime_suspend, img_spdif_in_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(img_spdif_in_suspend, img_spdif_in_resume) }; static struct platform_driver img_spdif_in_driver = { .driver = { .name = "img-spdif-in", .of_match_table = img_spdif_in_of_match, - .pm = &img_spdif_in_pm_ops + .pm = pm_ptr(&img_spdif_in_pm_ops) }, .probe = img_spdif_in_probe, .remove = img_spdif_in_dev_remove diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c index 402695b5fc41..52f696219ef4 100644 --- a/sound/soc/img/img-spdif-out.c +++ b/sound/soc/img/img-spdif-out.c @@ -409,7 +409,6 @@ static void img_spdif_out_dev_remove(struct platform_device *pdev) img_spdif_out_runtime_suspend(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static int img_spdif_out_suspend(struct device *dev) { struct img_spdif_out *spdif = dev_get_drvdata(dev); @@ -448,7 +447,7 @@ static int img_spdif_out_resume(struct device *dev) return 0; } -#endif + static const struct of_device_id img_spdif_out_of_match[] = { { .compatible = "img,spdif-out" }, {} @@ -456,16 +455,15 @@ static const struct of_device_id img_spdif_out_of_match[] = { MODULE_DEVICE_TABLE(of, img_spdif_out_of_match); static const struct dev_pm_ops img_spdif_out_pm_ops = { - SET_RUNTIME_PM_OPS(img_spdif_out_runtime_suspend, - img_spdif_out_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(img_spdif_out_suspend, img_spdif_out_resume) + RUNTIME_PM_OPS(img_spdif_out_runtime_suspend, img_spdif_out_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(img_spdif_out_suspend, img_spdif_out_resume) }; static struct platform_driver img_spdif_out_driver = { .driver = { .name = "img-spdif-out", .of_match_table = img_spdif_out_of_match, - .pm = &img_spdif_out_pm_ops + .pm = pm_ptr(&img_spdif_out_pm_ops) }, .probe = img_spdif_out_probe, .remove = img_spdif_out_dev_remove diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c index fdeceb271e7f..ec4f891295c9 100644 --- a/sound/soc/img/pistachio-internal-dac.c +++ b/sound/soc/img/pistachio-internal-dac.c @@ -224,7 +224,6 @@ static void pistachio_internal_dac_remove(struct platform_device *pdev) regulator_disable(dac->supply); } -#ifdef CONFIG_PM static int pistachio_internal_dac_rt_resume(struct device *dev) { struct pistachio_internal_dac *dac = dev_get_drvdata(dev); @@ -251,11 +250,10 @@ static int pistachio_internal_dac_rt_suspend(struct device *dev) return 0; } -#endif static const struct dev_pm_ops pistachio_internal_dac_pm_ops = { - SET_RUNTIME_PM_OPS(pistachio_internal_dac_rt_suspend, - pistachio_internal_dac_rt_resume, NULL) + RUNTIME_PM_OPS(pistachio_internal_dac_rt_suspend, + pistachio_internal_dac_rt_resume, NULL) }; static const struct of_device_id pistachio_internal_dac_of_match[] = { @@ -268,7 +266,7 @@ static struct platform_driver pistachio_internal_dac_plat_driver = { .driver = { .name = "img-pistachio-internal-dac", .of_match_table = pistachio_internal_dac_of_match, - .pm = &pistachio_internal_dac_pm_ops + .pm = pm_ptr(&pistachio_internal_dac_pm_ops) }, .probe = pistachio_internal_dac_probe, .remove = pistachio_internal_dac_remove From 72954863350eff04a4961acb49bfce11416f7856 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:23 +0100 Subject: [PATCH 573/651] ASoC: intel: avs: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Cezary Rojewski Signed-off-by: Takashi Iwai Reviewed-by: Cezary Rojewski Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-62-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 0e750e9e01d9..8fbf33e30dfc 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -612,7 +612,7 @@ static int avs_suspend_standby(struct avs_dev *adev) return 0; } -static int __maybe_unused avs_suspend_common(struct avs_dev *adev, bool low_power) +static int avs_suspend_common(struct avs_dev *adev, bool low_power) { struct hdac_bus *bus = &adev->base.core; int ret; @@ -673,7 +673,7 @@ static int avs_resume_standby(struct avs_dev *adev) return 0; } -static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool low_power, bool purge) +static int avs_resume_common(struct avs_dev *adev, bool low_power, bool purge) { struct hdac_bus *bus = &adev->base.core; int ret; @@ -696,41 +696,41 @@ static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool low_power return 0; } -static int __maybe_unused avs_suspend(struct device *dev) +static int avs_suspend(struct device *dev) { return avs_suspend_common(to_avs_dev(dev), true); } -static int __maybe_unused avs_resume(struct device *dev) +static int avs_resume(struct device *dev) { return avs_resume_common(to_avs_dev(dev), true, true); } -static int __maybe_unused avs_runtime_suspend(struct device *dev) +static int avs_runtime_suspend(struct device *dev) { return avs_suspend_common(to_avs_dev(dev), true); } -static int __maybe_unused avs_runtime_resume(struct device *dev) +static int avs_runtime_resume(struct device *dev) { return avs_resume_common(to_avs_dev(dev), true, false); } -static int __maybe_unused avs_freeze(struct device *dev) +static int avs_freeze(struct device *dev) { return avs_suspend_common(to_avs_dev(dev), false); } -static int __maybe_unused avs_thaw(struct device *dev) +static int avs_thaw(struct device *dev) { return avs_resume_common(to_avs_dev(dev), false, true); } -static int __maybe_unused avs_poweroff(struct device *dev) +static int avs_poweroff(struct device *dev) { return avs_suspend_common(to_avs_dev(dev), false); } -static int __maybe_unused avs_restore(struct device *dev) +static int avs_restore(struct device *dev) { return avs_resume_common(to_avs_dev(dev), false, true); } @@ -742,7 +742,7 @@ static const struct dev_pm_ops avs_dev_pm = { .thaw = avs_thaw, .poweroff = avs_poweroff, .restore = avs_restore, - SET_RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL) + RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL) }; static const struct avs_sram_spec skl_sram_spec = { @@ -893,7 +893,7 @@ static struct pci_driver avs_pci_driver = { .shutdown = avs_pci_shutdown, .dev_groups = avs_attr_groups, .driver = { - .pm = &avs_dev_pm, + .pm = pm_ptr(&avs_dev_pm), }, }; module_pci_driver(avs_pci_driver); From 2c498d9a3a5ad28d2cfbdffde8496626f1b89c82 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:24 +0100 Subject: [PATCH 574/651] ASoC: intel: catpt: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Cezary Rojewski Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-63-tiwai@suse.de Reviewed-by: Cezary Rojewski Signed-off-by: Mark Brown --- sound/soc/intel/catpt/device.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c index 2aa637124bec..faa916f40069 100644 --- a/sound/soc/intel/catpt/device.c +++ b/sound/soc/intel/catpt/device.c @@ -28,7 +28,7 @@ #define CREATE_TRACE_POINTS #include "trace.h" -static int __maybe_unused catpt_suspend(struct device *dev) +static int catpt_suspend(struct device *dev) { struct catpt_dev *cdev = dev_get_drvdata(dev); struct dma_chan *chan; @@ -72,7 +72,7 @@ release_dma_chan: return catpt_dsp_power_down(cdev); } -static int __maybe_unused catpt_resume(struct device *dev) +static int catpt_resume(struct device *dev) { struct catpt_dev *cdev = dev_get_drvdata(dev); int ret, i; @@ -106,7 +106,7 @@ static int __maybe_unused catpt_resume(struct device *dev) return 0; } -static int __maybe_unused catpt_runtime_suspend(struct device *dev) +static int catpt_runtime_suspend(struct device *dev) { if (!try_module_get(dev->driver->owner)) { dev_info(dev, "module unloading, skipping suspend\n"); @@ -117,14 +117,14 @@ static int __maybe_unused catpt_runtime_suspend(struct device *dev) return catpt_suspend(dev); } -static int __maybe_unused catpt_runtime_resume(struct device *dev) +static int catpt_runtime_resume(struct device *dev) { return catpt_resume(dev); } static const struct dev_pm_ops catpt_dev_pm = { - SET_SYSTEM_SLEEP_PM_OPS(catpt_suspend, catpt_resume) - SET_RUNTIME_PM_OPS(catpt_runtime_suspend, catpt_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(catpt_suspend, catpt_resume) + RUNTIME_PM_OPS(catpt_runtime_suspend, catpt_runtime_resume, NULL) }; /* machine board owned by CATPT is removed with this hook */ @@ -378,7 +378,7 @@ static struct platform_driver catpt_acpi_driver = { .driver = { .name = "intel_catpt", .acpi_match_table = catpt_ids, - .pm = &catpt_dev_pm, + .pm = pm_ptr(&catpt_dev_pm), .dev_groups = catpt_attr_groups, }, }; From 50ffa9e4d22db71ce370a8cde3bd2d706138df8b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:25 +0100 Subject: [PATCH 575/651] ASoC: mediatek: mt2701: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-64-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c index 5f11bc5438bd..fcae38135d93 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c @@ -1462,15 +1462,15 @@ static const struct of_device_id mt2701_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match); static const struct dev_pm_ops mt2701_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend, - mt2701_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt2701_afe_runtime_suspend, + mt2701_afe_runtime_resume, NULL) }; static struct platform_driver mt2701_afe_pcm_driver = { .driver = { .name = "mt2701-audio", .of_match_table = mt2701_afe_pcm_dt_match, - .pm = &mt2701_afe_pm_ops, + .pm = pm_ptr(&mt2701_afe_pm_ops), }, .probe = mt2701_afe_pcm_dev_probe, .remove = mt2701_afe_pcm_dev_remove, From 6afabcdad370f117588dfd7203a803f050503c91 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:26 +0100 Subject: [PATCH 576/651] ASoC: mediatek: mt6797: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-65-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt6797/mt6797-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c index 9159b42adf6a..f62a32f2f2b6 100644 --- a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c +++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c @@ -879,15 +879,15 @@ static const struct of_device_id mt6797_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt6797_afe_pcm_dt_match); static const struct dev_pm_ops mt6797_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt6797_afe_runtime_suspend, - mt6797_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt6797_afe_runtime_suspend, + mt6797_afe_runtime_resume, NULL) }; static struct platform_driver mt6797_afe_pcm_driver = { .driver = { .name = "mt6797-audio", .of_match_table = mt6797_afe_pcm_dt_match, - .pm = &mt6797_afe_pm_ops, + .pm = pm_ptr(&mt6797_afe_pm_ops), }, .probe = mt6797_afe_pcm_dev_probe, .remove = mt6797_afe_pcm_dev_remove, From 0d7c63bc74a8fdcfc37e093efaeb8657b0e21022 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:27 +0100 Subject: [PATCH 577/651] ASoC: mediatek: mt7986: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-66-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c index 7db090414d59..7a6ad9116e55 100644 --- a/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c +++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c @@ -589,15 +589,15 @@ static const struct of_device_id mt7986_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt7986_afe_pcm_dt_match); static const struct dev_pm_ops mt7986_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt7986_afe_runtime_suspend, - mt7986_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt7986_afe_runtime_suspend, + mt7986_afe_runtime_resume, NULL) }; static struct platform_driver mt7986_afe_pcm_driver = { .driver = { .name = "mt7986-audio", .of_match_table = mt7986_afe_pcm_dt_match, - .pm = &mt7986_afe_pm_ops, + .pm = pm_ptr(&mt7986_afe_pm_ops), }, .probe = mt7986_afe_pcm_dev_probe, .remove = mt7986_afe_pcm_dev_remove, From 09b926f215df0206f1f3d8f4a2b4f4e28c68168e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:28 +0100 Subject: [PATCH 578/651] ASoC: mediatek: mt8173: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-67-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c index 03250273ea9c..04ed0cfec174 100644 --- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c @@ -1212,15 +1212,15 @@ static const struct of_device_id mt8173_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt8173_afe_pcm_dt_match); static const struct dev_pm_ops mt8173_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt8173_afe_runtime_suspend, - mt8173_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt8173_afe_runtime_suspend, + mt8173_afe_runtime_resume, NULL) }; static struct platform_driver mt8173_afe_pcm_driver = { .driver = { .name = "mt8173-afe-pcm", .of_match_table = mt8173_afe_pcm_dt_match, - .pm = &mt8173_afe_pm_ops, + .pm = pm_ptr(&mt8173_afe_pm_ops), }, .probe = mt8173_afe_pcm_dev_probe, .remove = mt8173_afe_pcm_dev_remove, From 564cb5ebb488a11708e63eb7cd8037accea7120d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:29 +0100 Subject: [PATCH 579/651] ASoC: mediatek: mt8183: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-68-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c index 3f377ba4ad53..d083b4bf0f95 100644 --- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c +++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c @@ -1257,15 +1257,15 @@ static const struct of_device_id mt8183_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt8183_afe_pcm_dt_match); static const struct dev_pm_ops mt8183_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt8183_afe_runtime_suspend, - mt8183_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt8183_afe_runtime_suspend, + mt8183_afe_runtime_resume, NULL) }; static struct platform_driver mt8183_afe_pcm_driver = { .driver = { .name = "mt8183-audio", .of_match_table = mt8183_afe_pcm_dt_match, - .pm = &mt8183_afe_pm_ops, + .pm = pm_ptr(&mt8183_afe_pm_ops), }, .probe = mt8183_afe_pcm_dev_probe, .remove = mt8183_afe_pcm_dev_remove, From 26d342b04f5e9190487cd2e6fdce75c52cee4a86 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:30 +0100 Subject: [PATCH 580/651] ASoC: mediatek: mt8186: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-69-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c index bafbef96a42d..db7c93401bee 100644 --- a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c +++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c @@ -2978,15 +2978,15 @@ static const struct of_device_id mt8186_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt8186_afe_pcm_dt_match); static const struct dev_pm_ops mt8186_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt8186_afe_runtime_suspend, - mt8186_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt8186_afe_runtime_suspend, + mt8186_afe_runtime_resume, NULL) }; static struct platform_driver mt8186_afe_pcm_driver = { .driver = { .name = "mt8186-audio", .of_match_table = mt8186_afe_pcm_dt_match, - .pm = &mt8186_afe_pm_ops, + .pm = pm_ptr(&mt8186_afe_pm_ops), }, .probe = mt8186_afe_pcm_dev_probe, }; From 49a70f2ed0a2a65aaf099dc45d73ba6b4f0c9c94 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:31 +0100 Subject: [PATCH 581/651] ASoC: mediatek: mt8188: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-70-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c index a2b57e00ff4e..ac4fdf8ba78f 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c @@ -3381,15 +3381,15 @@ static const struct of_device_id mt8188_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt8188_afe_pcm_dt_match); static const struct dev_pm_ops mt8188_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt8188_afe_runtime_suspend, - mt8188_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt8188_afe_runtime_suspend, + mt8188_afe_runtime_resume, NULL) }; static struct platform_driver mt8188_afe_pcm_driver = { .driver = { .name = "mt8188-audio", .of_match_table = mt8188_afe_pcm_dt_match, - .pm = &mt8188_afe_pm_ops, + .pm = pm_ptr(&mt8188_afe_pm_ops), }, .probe = mt8188_afe_pcm_dev_probe, }; From ecd140a2063d618e1239351d3ae146cfdaa9a13f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:32 +0100 Subject: [PATCH 582/651] ASoC: mediatek: mt8192: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-71-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c index 80cda7bf5ccc..fd6af74d7995 100644 --- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c +++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c @@ -2313,15 +2313,15 @@ static const struct of_device_id mt8192_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt8192_afe_pcm_dt_match); static const struct dev_pm_ops mt8192_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt8192_afe_runtime_suspend, - mt8192_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt8192_afe_runtime_suspend, + mt8192_afe_runtime_resume, NULL) }; static struct platform_driver mt8192_afe_pcm_driver = { .driver = { .name = "mt8192-audio", .of_match_table = mt8192_afe_pcm_dt_match, - .pm = &mt8192_afe_pm_ops, + .pm = pm_ptr(&mt8192_afe_pm_ops), }, .probe = mt8192_afe_pcm_dev_probe, .remove = mt8192_afe_pcm_dev_remove, From 951f082eb09b50d68b8271257777f206ee3001a8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:33 +0100 Subject: [PATCH 583/651] ASoC: mediatek: mt8195: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-72-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c index 8016bfb35015..5d025ad72263 100644 --- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c +++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c @@ -3188,15 +3188,15 @@ static const struct of_device_id mt8195_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt8195_afe_pcm_dt_match); static const struct dev_pm_ops mt8195_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt8195_afe_runtime_suspend, - mt8195_afe_runtime_resume, NULL) + RUNTIME_PM_OPS(mt8195_afe_runtime_suspend, + mt8195_afe_runtime_resume, NULL) }; static struct platform_driver mt8195_afe_pcm_driver = { .driver = { .name = "mt8195-audio", .of_match_table = mt8195_afe_pcm_dt_match, - .pm = &mt8195_afe_pm_ops, + .pm = pm_ptr(&mt8195_afe_pm_ops), }, .probe = mt8195_afe_pcm_dev_probe, .remove = mt8195_afe_pcm_dev_remove, From bd8540105e88581bdf27a9a92231907a9168d0b6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:34 +0100 Subject: [PATCH 584/651] ASoC: mediatek: mt8365: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us to drop ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-73-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8365/mt8365-afe-pcm.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c b/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c index 743b46572144..10793bbe9275 100644 --- a/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c +++ b/sound/soc/mediatek/mt8365/mt8365-afe-pcm.c @@ -1957,7 +1957,7 @@ err_irq: return IRQ_HANDLED; } -static int __maybe_unused mt8365_afe_runtime_suspend(struct device *dev) +static int mt8365_afe_runtime_suspend(struct device *dev) { return 0; } @@ -1967,7 +1967,7 @@ static int mt8365_afe_runtime_resume(struct device *dev) return 0; } -static int __maybe_unused mt8365_afe_suspend(struct device *dev) +static int mt8365_afe_suspend(struct device *dev) { struct mtk_base_afe *afe = dev_get_drvdata(dev); struct regmap *regmap = afe->regmap; @@ -1989,7 +1989,7 @@ static int __maybe_unused mt8365_afe_suspend(struct device *dev) return 0; } -static int __maybe_unused mt8365_afe_resume(struct device *dev) +static int mt8365_afe_resume(struct device *dev) { struct mtk_base_afe *afe = dev_get_drvdata(dev); struct regmap *regmap = afe->regmap; @@ -2009,7 +2009,7 @@ static int __maybe_unused mt8365_afe_resume(struct device *dev) return 0; } -static int __maybe_unused mt8365_afe_dev_runtime_suspend(struct device *dev) +static int mt8365_afe_dev_runtime_suspend(struct device *dev) { struct mtk_base_afe *afe = dev_get_drvdata(dev); @@ -2021,7 +2021,7 @@ static int __maybe_unused mt8365_afe_dev_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused mt8365_afe_dev_runtime_resume(struct device *dev) +static int mt8365_afe_dev_runtime_resume(struct device *dev) { struct mtk_base_afe *afe = dev_get_drvdata(dev); @@ -2250,17 +2250,16 @@ static const struct of_device_id mt8365_afe_pcm_dt_match[] = { MODULE_DEVICE_TABLE(of, mt8365_afe_pcm_dt_match); static const struct dev_pm_ops mt8365_afe_pm_ops = { - SET_RUNTIME_PM_OPS(mt8365_afe_dev_runtime_suspend, - mt8365_afe_dev_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(mt8365_afe_suspend, - mt8365_afe_resume) + RUNTIME_PM_OPS(mt8365_afe_dev_runtime_suspend, + mt8365_afe_dev_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(mt8365_afe_suspend, mt8365_afe_resume) }; static struct platform_driver mt8365_afe_pcm_driver = { .driver = { .name = "mt8365-afe-pcm", .of_match_table = mt8365_afe_pcm_dt_match, - .pm = &mt8365_afe_pm_ops, + .pm = pm_ptr(&mt8365_afe_pm_ops), }, .probe = mt8365_afe_pcm_dev_probe, .remove = mt8365_afe_pcm_dev_remove, From 23a6b07ceff59eabb45543091416951711f0963e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:35 +0100 Subject: [PATCH 585/651] ASoC: qcom: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us to drop ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Srinivas Kandagatla Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-74-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-sc7180.c | 8 ++++---- sound/soc/qcom/lpass-sc7280.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c index fbead6af3d95..7c6a9b0fda89 100644 --- a/sound/soc/qcom/lpass-sc7180.c +++ b/sound/soc/qcom/lpass-sc7180.c @@ -160,14 +160,14 @@ static int sc7180_lpass_exit(struct platform_device *pdev) return 0; } -static int __maybe_unused sc7180_lpass_dev_resume(struct device *dev) +static int sc7180_lpass_dev_resume(struct device *dev) { struct lpass_data *drvdata = dev_get_drvdata(dev); return clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks); } -static int __maybe_unused sc7180_lpass_dev_suspend(struct device *dev) +static int sc7180_lpass_dev_suspend(struct device *dev) { struct lpass_data *drvdata = dev_get_drvdata(dev); @@ -176,7 +176,7 @@ static int __maybe_unused sc7180_lpass_dev_suspend(struct device *dev) } static const struct dev_pm_ops sc7180_lpass_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(sc7180_lpass_dev_suspend, sc7180_lpass_dev_resume) + SYSTEM_SLEEP_PM_OPS(sc7180_lpass_dev_suspend, sc7180_lpass_dev_resume) }; static const struct lpass_variant sc7180_data = { @@ -312,7 +312,7 @@ static struct platform_driver sc7180_lpass_cpu_platform_driver = { .driver = { .name = "sc7180-lpass-cpu", .of_match_table = of_match_ptr(sc7180_lpass_cpu_device_id), - .pm = &sc7180_lpass_pm_ops, + .pm = pm_ptr(&sc7180_lpass_pm_ops), }, .probe = asoc_qcom_lpass_cpu_platform_probe, .remove = asoc_qcom_lpass_cpu_platform_remove, diff --git a/sound/soc/qcom/lpass-sc7280.c b/sound/soc/qcom/lpass-sc7280.c index 7cd3e291382a..817c824f9179 100644 --- a/sound/soc/qcom/lpass-sc7280.c +++ b/sound/soc/qcom/lpass-sc7280.c @@ -233,14 +233,14 @@ static int sc7280_lpass_exit(struct platform_device *pdev) return 0; } -static int __maybe_unused sc7280_lpass_dev_resume(struct device *dev) +static int sc7280_lpass_dev_resume(struct device *dev) { struct lpass_data *drvdata = dev_get_drvdata(dev); return clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks); } -static int __maybe_unused sc7280_lpass_dev_suspend(struct device *dev) +static int sc7280_lpass_dev_suspend(struct device *dev) { struct lpass_data *drvdata = dev_get_drvdata(dev); @@ -249,7 +249,7 @@ static int __maybe_unused sc7280_lpass_dev_suspend(struct device *dev) } static const struct dev_pm_ops sc7280_lpass_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(sc7280_lpass_dev_suspend, sc7280_lpass_dev_resume) + SYSTEM_SLEEP_PM_OPS(sc7280_lpass_dev_suspend, sc7280_lpass_dev_resume) }; static const struct lpass_variant sc7280_data = { @@ -442,7 +442,7 @@ static struct platform_driver sc7280_lpass_cpu_platform_driver = { .driver = { .name = "sc7280-lpass-cpu", .of_match_table = of_match_ptr(sc7280_lpass_cpu_device_id), - .pm = &sc7280_lpass_pm_ops, + .pm = pm_ptr(&sc7280_lpass_pm_ops), }, .probe = asoc_qcom_lpass_cpu_platform_probe, .remove = asoc_qcom_lpass_cpu_platform_remove, From 4330d33f04ea71c9cfb193a0ae60fb40f6080a19 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:36 +0100 Subject: [PATCH 586/651] ASoC: rcar: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead of SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us to drop ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Acked-by: Kuninori Morimoto Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-75-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/renesas/rcar/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c index f3f0c3f0bb9f..30afc942d381 100644 --- a/sound/soc/renesas/rcar/core.c +++ b/sound/soc/renesas/rcar/core.c @@ -2059,7 +2059,7 @@ static void rsnd_remove(struct platform_device *pdev) remove_func[i](priv); } -static int __maybe_unused rsnd_suspend(struct device *dev) +static int rsnd_suspend(struct device *dev) { struct rsnd_priv *priv = dev_get_drvdata(dev); @@ -2068,7 +2068,7 @@ static int __maybe_unused rsnd_suspend(struct device *dev) return 0; } -static int __maybe_unused rsnd_resume(struct device *dev) +static int rsnd_resume(struct device *dev) { struct rsnd_priv *priv = dev_get_drvdata(dev); @@ -2076,13 +2076,13 @@ static int __maybe_unused rsnd_resume(struct device *dev) } static const struct dev_pm_ops rsnd_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(rsnd_suspend, rsnd_resume) + SYSTEM_SLEEP_PM_OPS(rsnd_suspend, rsnd_resume) }; static struct platform_driver rsnd_driver = { .driver = { .name = "rcar_sound", - .pm = &rsnd_pm_ops, + .pm = pm_ptr(&rsnd_pm_ops), .of_match_table = rsnd_of_match, }, .probe = rsnd_probe, From 43a2930348040b3a7ad3b809e211dea233267f28 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:37 +0100 Subject: [PATCH 587/651] ASoC: rockchip: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us to drop ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-76-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 5 ++--- sound/soc/rockchip/rockchip_i2s_tdm.c | 16 +++++++--------- sound/soc/rockchip/rockchip_pdm.c | 10 ++++------ sound/soc/rockchip/rockchip_spdif.c | 9 ++++----- 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 4315da4a47c1..0a0a95b4f520 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -860,8 +860,7 @@ static void rockchip_i2s_remove(struct platform_device *pdev) } static const struct dev_pm_ops rockchip_i2s_pm_ops = { - SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, - NULL) + RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, NULL) }; static struct platform_driver rockchip_i2s_driver = { @@ -870,7 +869,7 @@ static struct platform_driver rockchip_i2s_driver = { .driver = { .name = DRV_NAME, .of_match_table = of_match_ptr(rockchip_i2s_match), - .pm = &rockchip_i2s_pm_ops, + .pm = pm_ptr(&rockchip_i2s_pm_ops), }, }; module_platform_driver(rockchip_i2s_driver); diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 78ab88843f86..d9a1fab7f403 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -122,7 +122,7 @@ err_mclk_tx: return ret; } -static int __maybe_unused i2s_tdm_runtime_suspend(struct device *dev) +static int i2s_tdm_runtime_suspend(struct device *dev) { struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); @@ -134,7 +134,7 @@ static int __maybe_unused i2s_tdm_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused i2s_tdm_runtime_resume(struct device *dev) +static int i2s_tdm_runtime_resume(struct device *dev) { struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); int ret; @@ -1390,7 +1390,7 @@ static void rockchip_i2s_tdm_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused rockchip_i2s_tdm_suspend(struct device *dev) +static int rockchip_i2s_tdm_suspend(struct device *dev) { struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); @@ -1399,7 +1399,7 @@ static int __maybe_unused rockchip_i2s_tdm_suspend(struct device *dev) return 0; } -static int __maybe_unused rockchip_i2s_tdm_resume(struct device *dev) +static int rockchip_i2s_tdm_resume(struct device *dev) { struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); int ret; @@ -1414,10 +1414,8 @@ static int __maybe_unused rockchip_i2s_tdm_resume(struct device *dev) } static const struct dev_pm_ops rockchip_i2s_tdm_pm_ops = { - SET_RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume, - NULL) - SET_SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend, - rockchip_i2s_tdm_resume) + RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend, rockchip_i2s_tdm_resume) }; static struct platform_driver rockchip_i2s_tdm_driver = { @@ -1426,7 +1424,7 @@ static struct platform_driver rockchip_i2s_tdm_driver = { .driver = { .name = DRV_NAME, .of_match_table = rockchip_i2s_tdm_match, - .pm = &rockchip_i2s_tdm_pm_ops, + .pm = pm_ptr(&rockchip_i2s_tdm_pm_ops), }, }; module_platform_driver(rockchip_i2s_tdm_driver); diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index cae91108f7a8..c1ee470ec607 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -668,7 +668,6 @@ static void rockchip_pdm_remove(struct platform_device *pdev) clk_disable_unprepare(pdm->hclk); } -#ifdef CONFIG_PM_SLEEP static int rockchip_pdm_suspend(struct device *dev) { struct rk_pdm_dev *pdm = dev_get_drvdata(dev); @@ -693,12 +692,11 @@ static int rockchip_pdm_resume(struct device *dev) return ret; } -#endif static const struct dev_pm_ops rockchip_pdm_pm_ops = { - SET_RUNTIME_PM_OPS(rockchip_pdm_runtime_suspend, - rockchip_pdm_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(rockchip_pdm_suspend, rockchip_pdm_resume) + RUNTIME_PM_OPS(rockchip_pdm_runtime_suspend, + rockchip_pdm_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(rockchip_pdm_suspend, rockchip_pdm_resume) }; static struct platform_driver rockchip_pdm_driver = { @@ -707,7 +705,7 @@ static struct platform_driver rockchip_pdm_driver = { .driver = { .name = "rockchip-pdm", .of_match_table = of_match_ptr(rockchip_pdm_match), - .pm = &rockchip_pdm_pm_ops, + .pm = pm_ptr(&rockchip_pdm_pm_ops), }, }; diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index d87c0e4f6f91..d365168934dc 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -63,7 +63,7 @@ static const struct of_device_id rk_spdif_match[] __maybe_unused = { }; MODULE_DEVICE_TABLE(of, rk_spdif_match); -static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev) +static int rk_spdif_runtime_suspend(struct device *dev) { struct rk_spdif_dev *spdif = dev_get_drvdata(dev); @@ -74,7 +74,7 @@ static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused rk_spdif_runtime_resume(struct device *dev) +static int rk_spdif_runtime_resume(struct device *dev) { struct rk_spdif_dev *spdif = dev_get_drvdata(dev); int ret; @@ -374,8 +374,7 @@ static void rk_spdif_remove(struct platform_device *pdev) } static const struct dev_pm_ops rk_spdif_pm_ops = { - SET_RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume, - NULL) + RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume, NULL) }; static struct platform_driver rk_spdif_driver = { @@ -384,7 +383,7 @@ static struct platform_driver rk_spdif_driver = { .driver = { .name = "rockchip-spdif", .of_match_table = of_match_ptr(rk_spdif_match), - .pm = &rk_spdif_pm_ops, + .pm = pm_ptr(&rk_spdif_pm_ops), }, }; module_platform_driver(rk_spdif_driver); From 692fc8ac774adb9ac86b607b9c8a59b4ddc53484 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:38 +0100 Subject: [PATCH 588/651] ASoC: samsung: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us to drop superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Sylwester Nawrocki Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-77-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 8f6deb06e234..e9964f0e010a 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1216,7 +1216,6 @@ static int i2s_alloc_dais(struct samsung_i2s_priv *priv, return 0; } -#ifdef CONFIG_PM static int i2s_runtime_suspend(struct device *dev) { struct samsung_i2s_priv *priv = dev_get_drvdata(dev); @@ -1254,7 +1253,6 @@ static int i2s_runtime_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM */ static void i2s_unregister_clocks(struct samsung_i2s_priv *priv) { @@ -1733,10 +1731,8 @@ MODULE_DEVICE_TABLE(of, exynos_i2s_match); #endif static const struct dev_pm_ops samsung_i2s_pm = { - SET_RUNTIME_PM_OPS(i2s_runtime_suspend, - i2s_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver samsung_i2s_driver = { @@ -1746,7 +1742,7 @@ static struct platform_driver samsung_i2s_driver = { .driver = { .name = "samsung-i2s", .of_match_table = of_match_ptr(exynos_i2s_match), - .pm = &samsung_i2s_pm, + .pm = pm_ptr(&samsung_i2s_pm), }, }; From 40456c8e7b9401d76363aebaae71763072b2e281 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:39 +0100 Subject: [PATCH 589/651] ASoC: SOF: acpi: Convert to EXPORT_NS_DEV_PM_OPS() Use the newer EXPORT_NS_DEV_PM_OPS() macro together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Cc: sound-open-firmware@alsa-project.org Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-78-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/sof/intel/bdw.c | 2 +- sound/soc/sof/intel/byt.c | 2 +- sound/soc/sof/sof-acpi-dev.c | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 79374dcde89f..f1287d509835 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -686,7 +686,7 @@ static struct platform_driver snd_sof_acpi_intel_bdw_driver = { .remove = sof_acpi_remove, .driver = { .name = "sof-audio-acpi-intel-bdw", - .pm = &sof_acpi_pm, + .pm = pm_ptr(&sof_acpi_pm), .acpi_match_table = sof_broadwell_match, }, }; diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 900cc10a3b7f..18208f77b84d 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -467,7 +467,7 @@ static struct platform_driver snd_sof_acpi_intel_byt_driver = { .remove = sof_acpi_remove, .driver = { .name = "sof-audio-acpi-intel-byt", - .pm = &sof_acpi_pm, + .pm = pm_ptr(&sof_acpi_pm), .acpi_match_table = sof_baytrail_match, }, }; diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index 58fd5f7c7905..68bf1b57093e 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -36,12 +36,11 @@ MODULE_PARM_DESC(sof_acpi_debug, "SOF ACPI debug options (0x0 all off)"); #define SOF_ACPI_DISABLE_PM_RUNTIME BIT(0) -const struct dev_pm_ops sof_acpi_pm = { - SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) - SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, - snd_sof_runtime_idle) +EXPORT_NS_DEV_PM_OPS(sof_acpi_pm, SND_SOC_SOF_ACPI_DEV) = { + SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) + RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, + snd_sof_runtime_idle) }; -EXPORT_SYMBOL_NS(sof_acpi_pm, "SND_SOC_SOF_ACPI_DEV"); static void sof_acpi_probe_complete(struct device *dev) { From 24df03e2b43c8a66c0f235320177f7199dca47a9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:40 +0100 Subject: [PATCH 590/651] ASoC: SOF: pci: Convert to EXPORT_NS_DEV_PM_OPS() Use the newer EXPORT_NS_DEV_PM_OPS() macro together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Cc: sound-open-firmware@alsa-project.org Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250317095603.20073-79-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/sof/amd/pci-acp63.c | 2 +- sound/soc/sof/amd/pci-acp70.c | 2 +- sound/soc/sof/amd/pci-rn.c | 2 +- sound/soc/sof/amd/pci-vangogh.c | 2 +- sound/soc/sof/intel/pci-apl.c | 2 +- sound/soc/sof/intel/pci-cnl.c | 2 +- sound/soc/sof/intel/pci-icl.c | 2 +- sound/soc/sof/intel/pci-lnl.c | 2 +- sound/soc/sof/intel/pci-mtl.c | 2 +- sound/soc/sof/intel/pci-ptl.c | 2 +- sound/soc/sof/intel/pci-skl.c | 2 +- sound/soc/sof/intel/pci-tgl.c | 2 +- sound/soc/sof/intel/pci-tng.c | 2 +- sound/soc/sof/sof-pci-dev.c | 9 ++++----- 14 files changed, 17 insertions(+), 18 deletions(-) diff --git a/sound/soc/sof/amd/pci-acp63.c b/sound/soc/sof/amd/pci-acp63.c index 13aa87cdeeac..21ffdfdcf03d 100644 --- a/sound/soc/sof/amd/pci-acp63.c +++ b/sound/soc/sof/amd/pci-acp63.c @@ -104,7 +104,7 @@ static struct pci_driver snd_sof_pci_amd_acp63_driver = { .probe = acp63_pci_probe, .remove = acp63_pci_remove, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_amd_acp63_driver); diff --git a/sound/soc/sof/amd/pci-acp70.c b/sound/soc/sof/amd/pci-acp70.c index d886bdf3a112..8fa1170a2161 100644 --- a/sound/soc/sof/amd/pci-acp70.c +++ b/sound/soc/sof/amd/pci-acp70.c @@ -100,7 +100,7 @@ static struct pci_driver snd_sof_pci_amd_acp70_driver = { .probe = acp70_pci_probe, .remove = acp70_pci_remove, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_amd_acp70_driver); diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c index 4a36029a00de..2b7fbcf11b55 100644 --- a/sound/soc/sof/amd/pci-rn.c +++ b/sound/soc/sof/amd/pci-rn.c @@ -97,7 +97,7 @@ static struct pci_driver snd_sof_pci_amd_rn_driver = { .probe = acp_pci_rn_probe, .remove = acp_pci_rn_remove, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_amd_rn_driver); diff --git a/sound/soc/sof/amd/pci-vangogh.c b/sound/soc/sof/amd/pci-vangogh.c index caf9e2b2e463..6ef692becfb9 100644 --- a/sound/soc/sof/amd/pci-vangogh.c +++ b/sound/soc/sof/amd/pci-vangogh.c @@ -90,7 +90,7 @@ static struct pci_driver snd_sof_pci_amd_vgh_driver = { .probe = acp_pci_vgh_probe, .remove = acp_pci_vgh_remove, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_amd_vgh_driver); diff --git a/sound/soc/sof/intel/pci-apl.c b/sound/soc/sof/intel/pci-apl.c index 94ab3c61e3f7..0bf7ee753bc3 100644 --- a/sound/soc/sof/intel/pci-apl.c +++ b/sound/soc/sof/intel/pci-apl.c @@ -99,7 +99,7 @@ static struct pci_driver snd_sof_pci_intel_apl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_apl_driver); diff --git a/sound/soc/sof/intel/pci-cnl.c b/sound/soc/sof/intel/pci-cnl.c index 739c352c3860..de48640024e4 100644 --- a/sound/soc/sof/intel/pci-cnl.c +++ b/sound/soc/sof/intel/pci-cnl.c @@ -137,7 +137,7 @@ static struct pci_driver snd_sof_pci_intel_cnl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_cnl_driver); diff --git a/sound/soc/sof/intel/pci-icl.c b/sound/soc/sof/intel/pci-icl.c index 8545ab95eac8..fd219e654844 100644 --- a/sound/soc/sof/intel/pci-icl.c +++ b/sound/soc/sof/intel/pci-icl.c @@ -102,7 +102,7 @@ static struct pci_driver snd_sof_pci_intel_icl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_icl_driver); diff --git a/sound/soc/sof/intel/pci-lnl.c b/sound/soc/sof/intel/pci-lnl.c index 91b9cff8c4ca..ae379c23f008 100644 --- a/sound/soc/sof/intel/pci-lnl.c +++ b/sound/soc/sof/intel/pci-lnl.c @@ -72,7 +72,7 @@ static struct pci_driver snd_sof_pci_intel_lnl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_lnl_driver); diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c index c5048a4a56be..7b2533999195 100644 --- a/sound/soc/sof/intel/pci-mtl.c +++ b/sound/soc/sof/intel/pci-mtl.c @@ -135,7 +135,7 @@ static struct pci_driver snd_sof_pci_intel_mtl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_mtl_driver); diff --git a/sound/soc/sof/intel/pci-ptl.c b/sound/soc/sof/intel/pci-ptl.c index 3812ab6d99c0..7d4c46f56931 100644 --- a/sound/soc/sof/intel/pci-ptl.c +++ b/sound/soc/sof/intel/pci-ptl.c @@ -71,7 +71,7 @@ static struct pci_driver snd_sof_pci_intel_ptl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_ptl_driver); diff --git a/sound/soc/sof/intel/pci-skl.c b/sound/soc/sof/intel/pci-skl.c index bd9daae51e4c..a16945dc35f7 100644 --- a/sound/soc/sof/intel/pci-skl.c +++ b/sound/soc/sof/intel/pci-skl.c @@ -83,7 +83,7 @@ static struct pci_driver snd_sof_pci_intel_skl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_skl_driver); diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c index f76a7197f6ca..437c43819825 100644 --- a/sound/soc/sof/intel/pci-tgl.c +++ b/sound/soc/sof/intel/pci-tgl.c @@ -311,7 +311,7 @@ static struct pci_driver snd_sof_pci_intel_tgl_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_tgl_driver); diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c index 3eb7400942dd..0c11cc1fd820 100644 --- a/sound/soc/sof/intel/pci-tng.c +++ b/sound/soc/sof/intel/pci-tng.c @@ -238,7 +238,7 @@ static struct pci_driver snd_sof_pci_intel_tng_driver = { .remove = sof_pci_remove, .shutdown = sof_pci_shutdown, .driver = { - .pm = &sof_pci_pm, + .pm = pm_ptr(&sof_pci_pm), }, }; module_pci_driver(snd_sof_pci_intel_tng_driver); diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 103377e2caaf..2fc14b9a33d4 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -155,14 +155,13 @@ static const struct dmi_system_id community_key_platforms[] = { {}, }; -const struct dev_pm_ops sof_pci_pm = { +EXPORT_NS_DEV_PM_OPS(sof_pci_pm, SND_SOC_SOF_PCI_DEV) = { .prepare = snd_sof_prepare, .complete = snd_sof_complete, - SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) - SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, - snd_sof_runtime_idle) + SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) + RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, + snd_sof_runtime_idle) }; -EXPORT_SYMBOL_NS(sof_pci_pm, "SND_SOC_SOF_PCI_DEV"); static void sof_pci_probe_complete(struct device *dev) { From f8d952c5f77fb8c2791d0978a2f4d6c72965cbe0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:41 +0100 Subject: [PATCH 591/651] ASoC: SOF: of: Convert to EXPORT_DEV_PM_OPS() Use the newer EXPORT_DEV_PM_OPS() macro together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Cc: sound-open-firmware@alsa-project.org Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-80-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/sof/imx/imx8.c | 2 +- sound/soc/sof/imx/imx9.c | 2 +- sound/soc/sof/mediatek/mt8186/mt8186.c | 2 +- sound/soc/sof/mediatek/mt8195/mt8195.c | 2 +- sound/soc/sof/sof-of-dev.c | 8 +++----- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c index 4be4c569b583..ab07512e511d 100644 --- a/sound/soc/sof/imx/imx8.c +++ b/sound/soc/sof/imx/imx8.c @@ -456,7 +456,7 @@ static struct platform_driver snd_sof_of_imx8_driver = { .remove = sof_of_remove, .driver = { .name = "sof-audio-of-imx8", - .pm = &sof_of_pm, + .pm = pm_ptr(&sof_of_pm), .of_match_table = sof_of_imx8_ids, }, }; diff --git a/sound/soc/sof/imx/imx9.c b/sound/soc/sof/imx/imx9.c index 598675d4350a..853155d5990a 100644 --- a/sound/soc/sof/imx/imx9.c +++ b/sound/soc/sof/imx/imx9.c @@ -126,7 +126,7 @@ static struct platform_driver snd_sof_of_imx9_driver = { .remove = sof_of_remove, .driver = { .name = "sof-audio-of-imx9", - .pm = &sof_of_pm, + .pm = pm_ptr(&sof_of_pm), .of_match_table = sof_of_imx9_ids, }, }; diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c index 31437fdd4e92..18144d9504e1 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186.c @@ -660,7 +660,7 @@ static struct platform_driver snd_sof_of_mt8186_driver = { .shutdown = sof_of_shutdown, .driver = { .name = "sof-audio-of-mt8186", - .pm = &sof_of_pm, + .pm = pm_ptr(&sof_of_pm), .of_match_table = sof_of_mt8186_ids, }, }; diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 371563d7ce79..821f43a3974a 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -616,7 +616,7 @@ static struct platform_driver snd_sof_of_mt8195_driver = { .shutdown = sof_of_shutdown, .driver = { .name = "sof-audio-of-mt8195", - .pm = &sof_of_pm, + .pm = pm_ptr(&sof_of_pm), .of_match_table = sof_of_mt8195_ids, }, }; diff --git a/sound/soc/sof/sof-of-dev.c b/sound/soc/sof/sof-of-dev.c index fb8c8a14d885..3ccfcfb142b7 100644 --- a/sound/soc/sof/sof-of-dev.c +++ b/sound/soc/sof/sof-of-dev.c @@ -30,14 +30,12 @@ static char *tplg_filename; module_param(tplg_filename, charp, 0444); MODULE_PARM_DESC(tplg_filename, "deprecated - moved to snd-sof module."); -const struct dev_pm_ops sof_of_pm = { +EXPORT_DEV_PM_OPS(sof_of_pm) = { .prepare = snd_sof_prepare, .complete = snd_sof_complete, - SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) - SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, - NULL) + SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) + RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, NULL) }; -EXPORT_SYMBOL(sof_of_pm); static void sof_of_probe_complete(struct device *dev) { From 7369a2d95878f427959980539549d0eb9ec4958c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:42 +0100 Subject: [PATCH 592/651] ASoC: stm: Convert to SYSTEM_SLEEP_PM_OPS() Use the newer SYSTEM_SLEEP_PM_OPS() macro instead SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping superfluous CONFIG_PM_SLEEP ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Olivier Moysan Cc: Arnaud Pouliquen Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-81-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/stm/stm32_i2s.c | 6 ++---- sound/soc/stm/stm32_sai.c | 6 ++---- sound/soc/stm/stm32_sai_sub.c | 6 ++---- sound/soc/stm/stm32_spdifrx.c | 6 ++---- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 19dc61008a75..6037b7a9c97b 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -1352,7 +1352,6 @@ error: MODULE_DEVICE_TABLE(of, stm32_i2s_ids); -#ifdef CONFIG_PM_SLEEP static int stm32_i2s_suspend(struct device *dev) { struct stm32_i2s_data *i2s = dev_get_drvdata(dev); @@ -1370,17 +1369,16 @@ static int stm32_i2s_resume(struct device *dev) regcache_cache_only(i2s->regmap, false); return regcache_sync(i2s->regmap); } -#endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops stm32_i2s_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(stm32_i2s_suspend, stm32_i2s_resume) + SYSTEM_SLEEP_PM_OPS(stm32_i2s_suspend, stm32_i2s_resume) }; static struct platform_driver stm32_i2s_driver = { .driver = { .name = "st,stm32-i2s", .of_match_table = stm32_i2s_ids, - .pm = &stm32_i2s_pm_ops, + .pm = pm_ptr(&stm32_i2s_pm_ops), }, .probe = stm32_i2s_probe, .remove = stm32_i2s_remove, diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index bc8180fc8462..504a14584765 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -270,7 +270,6 @@ static int stm32_sai_probe(struct platform_device *pdev) return devm_of_platform_populate(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP /* * When pins are shared by two sai sub instances, pins have to be defined * in sai parent node. In this case, pins state is not managed by alsa fw. @@ -305,10 +304,9 @@ static int stm32_sai_resume(struct device *dev) return pinctrl_pm_select_default_state(dev); } -#endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops stm32_sai_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(stm32_sai_suspend, stm32_sai_resume) + SYSTEM_SLEEP_PM_OPS(stm32_sai_suspend, stm32_sai_resume) }; MODULE_DEVICE_TABLE(of, stm32_sai_ids); @@ -317,7 +315,7 @@ static struct platform_driver stm32_sai_driver = { .driver = { .name = "st,stm32-sai", .of_match_table = stm32_sai_ids, - .pm = &stm32_sai_pm_ops, + .pm = pm_ptr(&stm32_sai_pm_ops), }, .probe = stm32_sai_probe, }; diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index 3efbf4aaf965..e8c1abf1ae0a 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -1704,7 +1704,6 @@ static void stm32_sai_sub_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -#ifdef CONFIG_PM_SLEEP static int stm32_sai_sub_suspend(struct device *dev) { struct stm32_sai_sub_data *sai = dev_get_drvdata(dev); @@ -1738,17 +1737,16 @@ static int stm32_sai_sub_resume(struct device *dev) return ret; } -#endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops stm32_sai_sub_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(stm32_sai_sub_suspend, stm32_sai_sub_resume) + SYSTEM_SLEEP_PM_OPS(stm32_sai_sub_suspend, stm32_sai_sub_resume) }; static struct platform_driver stm32_sai_sub_driver = { .driver = { .name = "st,stm32-sai-sub", .of_match_table = stm32_sai_sub_ids, - .pm = &stm32_sai_sub_pm_ops, + .pm = pm_ptr(&stm32_sai_sub_pm_ops), }, .probe = stm32_sai_sub_probe, .remove = stm32_sai_sub_remove, diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c index 9e30852de93c..57b711c44278 100644 --- a/sound/soc/stm/stm32_spdifrx.c +++ b/sound/soc/stm/stm32_spdifrx.c @@ -1040,7 +1040,6 @@ error: MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids); -#ifdef CONFIG_PM_SLEEP static int stm32_spdifrx_suspend(struct device *dev) { struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(dev); @@ -1059,17 +1058,16 @@ static int stm32_spdifrx_resume(struct device *dev) return regcache_sync(spdifrx->regmap); } -#endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops stm32_spdifrx_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(stm32_spdifrx_suspend, stm32_spdifrx_resume) + SYSTEM_SLEEP_PM_OPS(stm32_spdifrx_suspend, stm32_spdifrx_resume) }; static struct platform_driver stm32_spdifrx_driver = { .driver = { .name = "st,stm32-spdifrx", .of_match_table = stm32_spdifrx_ids, - .pm = &stm32_spdifrx_pm_ops, + .pm = pm_ptr(&stm32_spdifrx_pm_ops), }, .probe = stm32_spdifrx_probe, .remove = stm32_spdifrx_remove, From 723b690723287c39b386dbf8dad8834c4acbc0ef Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:43 +0100 Subject: [PATCH 593/651] ASoC: sunxi: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-82-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-spdif.c | 6 +++--- sound/soc/sunxi/sun50i-dmic.c | 6 +++--- sound/soc/sunxi/sun8i-codec.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c index 41caf1795d09..34e5bd94e9af 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c @@ -727,15 +727,15 @@ static void sun4i_spdif_remove(struct platform_device *pdev) } static const struct dev_pm_ops sun4i_spdif_pm = { - SET_RUNTIME_PM_OPS(sun4i_spdif_runtime_suspend, - sun4i_spdif_runtime_resume, NULL) + RUNTIME_PM_OPS(sun4i_spdif_runtime_suspend, + sun4i_spdif_runtime_resume, NULL) }; static struct platform_driver sun4i_spdif_driver = { .driver = { .name = "sun4i-spdif", .of_match_table = sun4i_spdif_of_match, - .pm = &sun4i_spdif_pm, + .pm = pm_ptr(&sun4i_spdif_pm), }, .probe = sun4i_spdif_probe, .remove = sun4i_spdif_remove, diff --git a/sound/soc/sunxi/sun50i-dmic.c b/sound/soc/sunxi/sun50i-dmic.c index 3e751b5694fe..bab1e29c9988 100644 --- a/sound/soc/sunxi/sun50i-dmic.c +++ b/sound/soc/sunxi/sun50i-dmic.c @@ -415,15 +415,15 @@ static void sun50i_dmic_remove(struct platform_device *pdev) } static const struct dev_pm_ops sun50i_dmic_pm = { - SET_RUNTIME_PM_OPS(sun50i_dmic_runtime_suspend, - sun50i_dmic_runtime_resume, NULL) + RUNTIME_PM_OPS(sun50i_dmic_runtime_suspend, + sun50i_dmic_runtime_resume, NULL) }; static struct platform_driver sun50i_dmic_driver = { .driver = { .name = "sun50i-dmic", .of_match_table = sun50i_dmic_of_match, - .pm = &sun50i_dmic_pm, + .pm = pm_ptr(&sun50i_dmic_pm), }, .probe = sun50i_dmic_probe, .remove = sun50i_dmic_remove, diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 8c645e04d571..8b9eb1a202f7 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -1702,15 +1702,15 @@ static const struct of_device_id sun8i_codec_of_match[] = { MODULE_DEVICE_TABLE(of, sun8i_codec_of_match); static const struct dev_pm_ops sun8i_codec_pm_ops = { - SET_RUNTIME_PM_OPS(sun8i_codec_runtime_suspend, - sun8i_codec_runtime_resume, NULL) + RUNTIME_PM_OPS(sun8i_codec_runtime_suspend, + sun8i_codec_runtime_resume, NULL) }; static struct platform_driver sun8i_codec_driver = { .driver = { .name = "sun8i-codec", .of_match_table = sun8i_codec_of_match, - .pm = &sun8i_codec_pm_ops, + .pm = pm_ptr(&sun8i_codec_pm_ops), }, .probe = sun8i_codec_probe, .remove = sun8i_codec_remove, From 5f6e34c575b86becafbee0051b2eb47145b5af57 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:44 +0100 Subject: [PATCH 594/651] ASoC: tegra186: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: linux-tegra@vger.kernel.org Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-83-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra186_asrc.c | 13 ++++++------- sound/soc/tegra/tegra186_dspk.c | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/sound/soc/tegra/tegra186_asrc.c b/sound/soc/tegra/tegra186_asrc.c index d914dba56013..5c67e1f01d9b 100644 --- a/sound/soc/tegra/tegra186_asrc.c +++ b/sound/soc/tegra/tegra186_asrc.c @@ -76,7 +76,7 @@ static void tegra186_asrc_lock_stream(struct tegra186_asrc *asrc, 1); } -static int __maybe_unused tegra186_asrc_runtime_suspend(struct device *dev) +static int tegra186_asrc_runtime_suspend(struct device *dev) { struct tegra186_asrc *asrc = dev_get_drvdata(dev); @@ -86,7 +86,7 @@ static int __maybe_unused tegra186_asrc_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra186_asrc_runtime_resume(struct device *dev) +static int tegra186_asrc_runtime_resume(struct device *dev) { struct tegra186_asrc *asrc = dev_get_drvdata(dev); int id; @@ -1021,17 +1021,16 @@ static void tegra186_asrc_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra186_asrc_pm_ops = { - SET_RUNTIME_PM_OPS(tegra186_asrc_runtime_suspend, - tegra186_asrc_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra186_asrc_runtime_suspend, + tegra186_asrc_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra186_asrc_driver = { .driver = { .name = "tegra186-asrc", .of_match_table = tegra186_asrc_of_match, - .pm = &tegra186_asrc_pm_ops, + .pm = pm_ptr(&tegra186_asrc_pm_ops), }, .probe = tegra186_asrc_platform_probe, .remove = tegra186_asrc_platform_remove, diff --git a/sound/soc/tegra/tegra186_dspk.c b/sound/soc/tegra/tegra186_dspk.c index 1be6c09cbe1a..21fdab2a1977 100644 --- a/sound/soc/tegra/tegra186_dspk.c +++ b/sound/soc/tegra/tegra186_dspk.c @@ -181,7 +181,7 @@ static int tegra186_dspk_put_stereo_to_mono(struct snd_kcontrol *kcontrol, return 1; } -static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev) +static int tegra186_dspk_runtime_suspend(struct device *dev) { struct tegra186_dspk *dspk = dev_get_drvdata(dev); @@ -193,7 +193,7 @@ static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra186_dspk_runtime_resume(struct device *dev) +static int tegra186_dspk_runtime_resume(struct device *dev) { struct tegra186_dspk *dspk = dev_get_drvdata(dev); int err; @@ -532,17 +532,16 @@ static void tegra186_dspk_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra186_dspk_pm_ops = { - SET_RUNTIME_PM_OPS(tegra186_dspk_runtime_suspend, - tegra186_dspk_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra186_dspk_runtime_suspend, + tegra186_dspk_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra186_dspk_driver = { .driver = { .name = "tegra186-dspk", .of_match_table = tegra186_dspk_of_match, - .pm = &tegra186_dspk_pm_ops, + .pm = pm_ptr(&tegra186_dspk_pm_ops), }, .probe = tegra186_dspk_platform_probe, .remove = tegra186_dspk_platform_remove, From 083c6a6f79e724ff89394d6ab900028a2e99ff7b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:45 +0100 Subject: [PATCH 595/651] ASoC: tegra210: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: linux-tegra@vger.kernel.org Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-84-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_admaif.c | 13 ++++++------- sound/soc/tegra/tegra210_adx.c | 13 ++++++------- sound/soc/tegra/tegra210_ahub.c | 13 ++++++------- sound/soc/tegra/tegra210_amx.c | 13 ++++++------- sound/soc/tegra/tegra210_dmic.c | 13 ++++++------- sound/soc/tegra/tegra210_i2s.c | 13 ++++++------- sound/soc/tegra/tegra210_mixer.c | 13 ++++++------- sound/soc/tegra/tegra210_mvc.c | 13 ++++++------- sound/soc/tegra/tegra210_ope.c | 13 ++++++------- sound/soc/tegra/tegra210_sfc.c | 13 ++++++------- 10 files changed, 60 insertions(+), 70 deletions(-) diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c index f56d1e03239d..76ff4fe40f65 100644 --- a/sound/soc/tegra/tegra210_admaif.c +++ b/sound/soc/tegra/tegra210_admaif.c @@ -220,7 +220,7 @@ static const struct regmap_config tegra186_admaif_regmap_config = { .cache_type = REGCACHE_FLAT, }; -static int __maybe_unused tegra_admaif_runtime_suspend(struct device *dev) +static int tegra_admaif_runtime_suspend(struct device *dev) { struct tegra_admaif *admaif = dev_get_drvdata(dev); @@ -230,7 +230,7 @@ static int __maybe_unused tegra_admaif_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra_admaif_runtime_resume(struct device *dev) +static int tegra_admaif_runtime_resume(struct device *dev) { struct tegra_admaif *admaif = dev_get_drvdata(dev); @@ -877,10 +877,9 @@ static void tegra_admaif_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra_admaif_pm_ops = { - SET_RUNTIME_PM_OPS(tegra_admaif_runtime_suspend, - tegra_admaif_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra_admaif_runtime_suspend, + tegra_admaif_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra_admaif_driver = { @@ -889,7 +888,7 @@ static struct platform_driver tegra_admaif_driver = { .driver = { .name = "tegra210-admaif", .of_match_table = tegra_admaif_of_match, - .pm = &tegra_admaif_pm_ops, + .pm = pm_ptr(&tegra_admaif_pm_ops), }, }; module_platform_driver(tegra_admaif_driver); diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c index 0aa93b948378..ff34682ebb15 100644 --- a/sound/soc/tegra/tegra210_adx.c +++ b/sound/soc/tegra/tegra210_adx.c @@ -84,7 +84,7 @@ static int tegra210_adx_startup(struct snd_pcm_substream *substream, return 0; } -static int __maybe_unused tegra210_adx_runtime_suspend(struct device *dev) +static int tegra210_adx_runtime_suspend(struct device *dev) { struct tegra210_adx *adx = dev_get_drvdata(dev); @@ -94,7 +94,7 @@ static int __maybe_unused tegra210_adx_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_adx_runtime_resume(struct device *dev) +static int tegra210_adx_runtime_resume(struct device *dev) { struct tegra210_adx *adx = dev_get_drvdata(dev); @@ -524,17 +524,16 @@ static void tegra210_adx_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra210_adx_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_adx_runtime_suspend, - tegra210_adx_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_adx_runtime_suspend, + tegra210_adx_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra210_adx_driver = { .driver = { .name = "tegra210-adx", .of_match_table = tegra210_adx_of_match, - .pm = &tegra210_adx_pm_ops, + .pm = pm_ptr(&tegra210_adx_pm_ops), }, .probe = tegra210_adx_platform_probe, .remove = tegra210_adx_platform_remove, diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c index 1920b996e9aa..99683f292b5d 100644 --- a/sound/soc/tegra/tegra210_ahub.c +++ b/sound/soc/tegra/tegra210_ahub.c @@ -1319,7 +1319,7 @@ static const struct of_device_id tegra_ahub_of_match[] = { }; MODULE_DEVICE_TABLE(of, tegra_ahub_of_match); -static int __maybe_unused tegra_ahub_runtime_suspend(struct device *dev) +static int tegra_ahub_runtime_suspend(struct device *dev) { struct tegra_ahub *ahub = dev_get_drvdata(dev); @@ -1331,7 +1331,7 @@ static int __maybe_unused tegra_ahub_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra_ahub_runtime_resume(struct device *dev) +static int tegra_ahub_runtime_resume(struct device *dev) { struct tegra_ahub *ahub = dev_get_drvdata(dev); int err; @@ -1408,10 +1408,9 @@ static void tegra_ahub_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra_ahub_pm_ops = { - SET_RUNTIME_PM_OPS(tegra_ahub_runtime_suspend, - tegra_ahub_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra_ahub_runtime_suspend, + tegra_ahub_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra_ahub_driver = { @@ -1420,7 +1419,7 @@ static struct platform_driver tegra_ahub_driver = { .driver = { .name = "tegra210-ahub", .of_match_table = tegra_ahub_of_match, - .pm = &tegra_ahub_pm_ops, + .pm = pm_ptr(&tegra_ahub_pm_ops), }, }; module_platform_driver(tegra_ahub_driver); diff --git a/sound/soc/tegra/tegra210_amx.c b/sound/soc/tegra/tegra210_amx.c index a9ef22c19e81..1981b94009cf 100644 --- a/sound/soc/tegra/tegra210_amx.c +++ b/sound/soc/tegra/tegra210_amx.c @@ -98,7 +98,7 @@ static int tegra210_amx_startup(struct snd_pcm_substream *substream, return 0; } -static int __maybe_unused tegra210_amx_runtime_suspend(struct device *dev) +static int tegra210_amx_runtime_suspend(struct device *dev) { struct tegra210_amx *amx = dev_get_drvdata(dev); @@ -108,7 +108,7 @@ static int __maybe_unused tegra210_amx_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_amx_runtime_resume(struct device *dev) +static int tegra210_amx_runtime_resume(struct device *dev) { struct tegra210_amx *amx = dev_get_drvdata(dev); @@ -581,17 +581,16 @@ static void tegra210_amx_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra210_amx_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_amx_runtime_suspend, - tegra210_amx_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_amx_runtime_suspend, + tegra210_amx_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra210_amx_driver = { .driver = { .name = "tegra210-amx", .of_match_table = tegra210_amx_of_match, - .pm = &tegra210_amx_pm_ops, + .pm = pm_ptr(&tegra210_amx_pm_ops), }, .probe = tegra210_amx_platform_probe, .remove = tegra210_amx_platform_remove, diff --git a/sound/soc/tegra/tegra210_dmic.c b/sound/soc/tegra/tegra210_dmic.c index 7986be71f43d..e4a144571265 100644 --- a/sound/soc/tegra/tegra210_dmic.c +++ b/sound/soc/tegra/tegra210_dmic.c @@ -40,7 +40,7 @@ static const struct reg_default tegra210_dmic_reg_defaults[] = { { TEGRA210_DMIC_LP_BIQUAD_1_COEF_4, 0x0 }, }; -static int __maybe_unused tegra210_dmic_runtime_suspend(struct device *dev) +static int tegra210_dmic_runtime_suspend(struct device *dev) { struct tegra210_dmic *dmic = dev_get_drvdata(dev); @@ -52,7 +52,7 @@ static int __maybe_unused tegra210_dmic_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_dmic_runtime_resume(struct device *dev) +static int tegra210_dmic_runtime_resume(struct device *dev) { struct tegra210_dmic *dmic = dev_get_drvdata(dev); int err; @@ -543,10 +543,9 @@ static void tegra210_dmic_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra210_dmic_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_dmic_runtime_suspend, - tegra210_dmic_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_dmic_runtime_suspend, + tegra210_dmic_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static const struct of_device_id tegra210_dmic_of_match[] = { @@ -559,7 +558,7 @@ static struct platform_driver tegra210_dmic_driver = { .driver = { .name = "tegra210-dmic", .of_match_table = tegra210_dmic_of_match, - .pm = &tegra210_dmic_pm_ops, + .pm = pm_ptr(&tegra210_dmic_pm_ops), }, .probe = tegra210_dmic_probe, .remove = tegra210_dmic_remove, diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index 07ce2dbe6c00..766cddebd5f6 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -166,7 +166,7 @@ static int tegra210_i2s_init(struct snd_soc_dapm_widget *w, return tegra210_i2s_sw_reset(compnt, stream); } -static int __maybe_unused tegra210_i2s_runtime_suspend(struct device *dev) +static int tegra210_i2s_runtime_suspend(struct device *dev) { struct tegra210_i2s *i2s = dev_get_drvdata(dev); @@ -178,7 +178,7 @@ static int __maybe_unused tegra210_i2s_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_i2s_runtime_resume(struct device *dev) +static int tegra210_i2s_runtime_resume(struct device *dev) { struct tegra210_i2s *i2s = dev_get_drvdata(dev); int err; @@ -1010,10 +1010,9 @@ static void tegra210_i2s_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra210_i2s_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_i2s_runtime_suspend, - tegra210_i2s_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_i2s_runtime_suspend, + tegra210_i2s_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static const struct of_device_id tegra210_i2s_of_match[] = { @@ -1026,7 +1025,7 @@ static struct platform_driver tegra210_i2s_driver = { .driver = { .name = "tegra210-i2s", .of_match_table = tegra210_i2s_of_match, - .pm = &tegra210_i2s_pm_ops, + .pm = pm_ptr(&tegra210_i2s_pm_ops), }, .probe = tegra210_i2s_probe, .remove = tegra210_i2s_remove, diff --git a/sound/soc/tegra/tegra210_mixer.c b/sound/soc/tegra/tegra210_mixer.c index 410259d98dfb..95d69a7e027f 100644 --- a/sound/soc/tegra/tegra210_mixer.c +++ b/sound/soc/tegra/tegra210_mixer.c @@ -73,7 +73,7 @@ static const struct tegra210_mixer_gain_params gain_params = { { 0, 0, 0x400, 0x8000000 }, }; -static int __maybe_unused tegra210_mixer_runtime_suspend(struct device *dev) +static int tegra210_mixer_runtime_suspend(struct device *dev) { struct tegra210_mixer *mixer = dev_get_drvdata(dev); @@ -83,7 +83,7 @@ static int __maybe_unused tegra210_mixer_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_mixer_runtime_resume(struct device *dev) +static int tegra210_mixer_runtime_resume(struct device *dev) { struct tegra210_mixer *mixer = dev_get_drvdata(dev); @@ -666,17 +666,16 @@ static void tegra210_mixer_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra210_mixer_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_mixer_runtime_suspend, - tegra210_mixer_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_mixer_runtime_suspend, + tegra210_mixer_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra210_mixer_driver = { .driver = { .name = "tegra210_mixer", .of_match_table = tegra210_mixer_of_match, - .pm = &tegra210_mixer_pm_ops, + .pm = pm_ptr(&tegra210_mixer_pm_ops), }, .probe = tegra210_mixer_platform_probe, .remove = tegra210_mixer_platform_remove, diff --git a/sound/soc/tegra/tegra210_mvc.c b/sound/soc/tegra/tegra210_mvc.c index 119f17501478..35b14c8396f4 100644 --- a/sound/soc/tegra/tegra210_mvc.c +++ b/sound/soc/tegra/tegra210_mvc.c @@ -47,7 +47,7 @@ static const struct tegra210_mvc_gain_params gain_params = { .duration_inv = 14316558, }; -static int __maybe_unused tegra210_mvc_runtime_suspend(struct device *dev) +static int tegra210_mvc_runtime_suspend(struct device *dev) { struct tegra210_mvc *mvc = dev_get_drvdata(dev); @@ -59,7 +59,7 @@ static int __maybe_unused tegra210_mvc_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_mvc_runtime_resume(struct device *dev) +static int tegra210_mvc_runtime_resume(struct device *dev) { struct tegra210_mvc *mvc = dev_get_drvdata(dev); @@ -758,17 +758,16 @@ static void tegra210_mvc_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra210_mvc_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_mvc_runtime_suspend, - tegra210_mvc_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_mvc_runtime_suspend, + tegra210_mvc_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra210_mvc_driver = { .driver = { .name = "tegra210-mvc", .of_match_table = tegra210_mvc_of_match, - .pm = &tegra210_mvc_pm_ops, + .pm = pm_ptr(&tegra210_mvc_pm_ops), }, .probe = tegra210_mvc_platform_probe, .remove = tegra210_mvc_platform_remove, diff --git a/sound/soc/tegra/tegra210_ope.c b/sound/soc/tegra/tegra210_ope.c index c595cec9baab..5036bcfe0828 100644 --- a/sound/soc/tegra/tegra210_ope.c +++ b/sound/soc/tegra/tegra210_ope.c @@ -356,7 +356,7 @@ static void tegra210_ope_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused tegra210_ope_runtime_suspend(struct device *dev) +static int tegra210_ope_runtime_suspend(struct device *dev) { struct tegra210_ope *ope = dev_get_drvdata(dev); @@ -374,7 +374,7 @@ static int __maybe_unused tegra210_ope_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_ope_runtime_resume(struct device *dev) +static int tegra210_ope_runtime_resume(struct device *dev) { struct tegra210_ope *ope = dev_get_drvdata(dev); @@ -393,10 +393,9 @@ static int __maybe_unused tegra210_ope_runtime_resume(struct device *dev) } static const struct dev_pm_ops tegra210_ope_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_ope_runtime_suspend, - tegra210_ope_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_ope_runtime_suspend, + tegra210_ope_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static const struct of_device_id tegra210_ope_of_match[] = { @@ -409,7 +408,7 @@ static struct platform_driver tegra210_ope_driver = { .driver = { .name = "tegra210-ope", .of_match_table = tegra210_ope_of_match, - .pm = &tegra210_ope_pm_ops, + .pm = pm_ptr(&tegra210_ope_pm_ops), }, .probe = tegra210_ope_probe, .remove = tegra210_ope_remove, diff --git a/sound/soc/tegra/tegra210_sfc.c b/sound/soc/tegra/tegra210_sfc.c index df88708c733c..a0bd36f12c68 100644 --- a/sound/soc/tegra/tegra210_sfc.c +++ b/sound/soc/tegra/tegra210_sfc.c @@ -3056,7 +3056,7 @@ static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = { }, }; -static int __maybe_unused tegra210_sfc_runtime_suspend(struct device *dev) +static int tegra210_sfc_runtime_suspend(struct device *dev) { struct tegra210_sfc *sfc = dev_get_drvdata(dev); @@ -3066,7 +3066,7 @@ static int __maybe_unused tegra210_sfc_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused tegra210_sfc_runtime_resume(struct device *dev) +static int tegra210_sfc_runtime_resume(struct device *dev) { struct tegra210_sfc *sfc = dev_get_drvdata(dev); @@ -3623,17 +3623,16 @@ static void tegra210_sfc_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra210_sfc_pm_ops = { - SET_RUNTIME_PM_OPS(tegra210_sfc_runtime_suspend, - tegra210_sfc_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra210_sfc_runtime_suspend, + tegra210_sfc_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra210_sfc_driver = { .driver = { .name = "tegra210-sfc", .of_match_table = tegra210_sfc_of_match, - .pm = &tegra210_sfc_pm_ops, + .pm = pm_ptr(&tegra210_sfc_pm_ops), }, .probe = tegra210_sfc_platform_probe, .remove = tegra210_sfc_platform_remove, From b7055fc11dc66f5dda6ffc0d88d7ede09970b244 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:46 +0100 Subject: [PATCH 596/651] ASoC: tegra20: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: linux-tegra@vger.kernel.org Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-85-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 13 ++++++------- sound/soc/tegra/tegra20_spdif.c | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 3b9823d1a87a..51df0835ce3e 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -34,7 +34,7 @@ #define DRV_NAME "tegra20-i2s" -static __maybe_unused int tegra20_i2s_runtime_suspend(struct device *dev) +static int tegra20_i2s_runtime_suspend(struct device *dev) { struct tegra20_i2s *i2s = dev_get_drvdata(dev); @@ -45,7 +45,7 @@ static __maybe_unused int tegra20_i2s_runtime_suspend(struct device *dev) return 0; } -static __maybe_unused int tegra20_i2s_runtime_resume(struct device *dev) +static int tegra20_i2s_runtime_resume(struct device *dev) { struct tegra20_i2s *i2s = dev_get_drvdata(dev); int ret; @@ -487,17 +487,16 @@ static const struct of_device_id tegra20_i2s_of_match[] = { }; static const struct dev_pm_ops tegra20_i2s_pm_ops = { - SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, - tegra20_i2s_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend, + tegra20_i2s_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra20_i2s_driver = { .driver = { .name = DRV_NAME, .of_match_table = tegra20_i2s_of_match, - .pm = &tegra20_i2s_pm_ops, + .pm = pm_ptr(&tegra20_i2s_pm_ops), }, .probe = tegra20_i2s_platform_probe, .remove = tegra20_i2s_platform_remove, diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 380011233eb1..38661d9b4a7c 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -25,7 +25,7 @@ #include "tegra20_spdif.h" -static __maybe_unused int tegra20_spdif_runtime_suspend(struct device *dev) +static int tegra20_spdif_runtime_suspend(struct device *dev) { struct tegra20_spdif *spdif = dev_get_drvdata(dev); @@ -36,7 +36,7 @@ static __maybe_unused int tegra20_spdif_runtime_suspend(struct device *dev) return 0; } -static __maybe_unused int tegra20_spdif_runtime_resume(struct device *dev) +static int tegra20_spdif_runtime_resume(struct device *dev) { struct tegra20_spdif *spdif = dev_get_drvdata(dev); int ret; @@ -403,10 +403,9 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) } static const struct dev_pm_ops tegra20_spdif_pm_ops = { - SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, - tegra20_spdif_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, + tegra20_spdif_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static const struct of_device_id tegra20_spdif_of_match[] = { @@ -418,7 +417,7 @@ MODULE_DEVICE_TABLE(of, tegra20_spdif_of_match); static struct platform_driver tegra20_spdif_driver = { .driver = { .name = "tegra20-spdif", - .pm = &tegra20_spdif_pm_ops, + .pm = pm_ptr(&tegra20_spdif_pm_ops), .of_match_table = tegra20_spdif_of_match, }, .probe = tegra20_spdif_platform_probe, From 212f5c4f1d45ffe43e52edc175f294426aba8ee7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:47 +0100 Subject: [PATCH 597/651] ASoC: tegra30: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Cc: linux-tegra@vger.kernel.org Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-86-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra30_ahub.c | 13 ++++++------- sound/soc/tegra/tegra30_i2s.c | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index c9b52f54cea8..51e5ab6c276b 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -40,7 +40,7 @@ static inline void tegra30_audio_write(u32 reg, u32 val) regmap_write(ahub->regmap_ahub, reg, val); } -static __maybe_unused int tegra30_ahub_runtime_suspend(struct device *dev) +static int tegra30_ahub_runtime_suspend(struct device *dev) { regcache_cache_only(ahub->regmap_apbif, true); regcache_cache_only(ahub->regmap_ahub, true); @@ -61,7 +61,7 @@ static __maybe_unused int tegra30_ahub_runtime_suspend(struct device *dev) * stopping streams should dynamically adjust the clock as required. However, * this is not yet implemented. */ -static __maybe_unused int tegra30_ahub_runtime_resume(struct device *dev) +static int tegra30_ahub_runtime_resume(struct device *dev) { int ret; @@ -600,10 +600,9 @@ static void tegra30_ahub_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra30_ahub_pm_ops = { - SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, - tegra30_ahub_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, + tegra30_ahub_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra30_ahub_driver = { @@ -612,7 +611,7 @@ static struct platform_driver tegra30_ahub_driver = { .driver = { .name = DRV_NAME, .of_match_table = tegra30_ahub_of_match, - .pm = &tegra30_ahub_pm_ops, + .pm = pm_ptr(&tegra30_ahub_pm_ops), }, }; module_platform_driver(tegra30_ahub_driver); diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 0d3badfbe143..b121af9ef8ed 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -35,7 +35,7 @@ #define DRV_NAME "tegra30-i2s" -static __maybe_unused int tegra30_i2s_runtime_suspend(struct device *dev) +static int tegra30_i2s_runtime_suspend(struct device *dev) { struct tegra30_i2s *i2s = dev_get_drvdata(dev); @@ -46,7 +46,7 @@ static __maybe_unused int tegra30_i2s_runtime_suspend(struct device *dev) return 0; } -static __maybe_unused int tegra30_i2s_runtime_resume(struct device *dev) +static int tegra30_i2s_runtime_resume(struct device *dev) { struct tegra30_i2s *i2s = dev_get_drvdata(dev); int ret; @@ -547,17 +547,16 @@ static void tegra30_i2s_platform_remove(struct platform_device *pdev) } static const struct dev_pm_ops tegra30_i2s_pm_ops = { - SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, - tegra30_i2s_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend, + tegra30_i2s_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver tegra30_i2s_driver = { .driver = { .name = DRV_NAME, .of_match_table = tegra30_i2s_of_match, - .pm = &tegra30_i2s_pm_ops, + .pm = pm_ptr(&tegra30_i2s_pm_ops), }, .probe = tegra30_i2s_platform_probe, .remove = tegra30_i2s_platform_remove, From c7ef05c0061acf505523133986adc47086265d99 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:48 +0100 Subject: [PATCH 598/651] ASoC: xtensa: Convert to RUNTIME_PM_OPS() Use the newer RUNTIME_PM_OPS() macro instead of SET_RUNTIME_PM_OPS() together with pm_ptr(). This optimizes slightly when CONFIG_PM is disabled, too. Reviewed-by: Max Filippov Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-87-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/xtensa/xtfpga-i2s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c index 4eaa9011405f..678ded059b95 100644 --- a/sound/soc/xtensa/xtfpga-i2s.c +++ b/sound/soc/xtensa/xtfpga-i2s.c @@ -629,8 +629,8 @@ MODULE_DEVICE_TABLE(of, xtfpga_i2s_of_match); #endif static const struct dev_pm_ops xtfpga_i2s_pm_ops = { - SET_RUNTIME_PM_OPS(xtfpga_i2s_runtime_suspend, - xtfpga_i2s_runtime_resume, NULL) + RUNTIME_PM_OPS(xtfpga_i2s_runtime_suspend, + xtfpga_i2s_runtime_resume, NULL) }; static struct platform_driver xtfpga_i2s_driver = { @@ -639,7 +639,7 @@ static struct platform_driver xtfpga_i2s_driver = { .driver = { .name = "xtfpga-i2s", .of_match_table = of_match_ptr(xtfpga_i2s_of_match), - .pm = &xtfpga_i2s_pm_ops, + .pm = pm_ptr(&xtfpga_i2s_pm_ops), }, }; From 5f86b16c49a9d156a459c7e9e3ebcbbe9439953c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:49 +0100 Subject: [PATCH 599/651] ASoC: amd: Convert to RUNTIME_PM_OPS() & co Use the newer RUNTIME_PM_OPS() and SYSTEM_SLEEP_PM_OPS() macros instead of SET_RUNTIME_PM_OPS() and SET_SYSTEM_SLEEP_PM_OPS() together with pm_ptr(), which allows us dropping ugly __maybe_unused attributes. This optimizes slightly when CONFIG_PM is disabled, too. Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-88-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pci.c | 10 +++++----- sound/soc/amd/acp/acp-rembrandt.c | 6 +++--- sound/soc/amd/acp/acp-renoir.c | 6 +++--- sound/soc/amd/acp/acp63.c | 6 +++--- sound/soc/amd/acp/acp70.c | 6 +++--- sound/soc/amd/ps/pci-ps.c | 12 ++++++------ sound/soc/amd/ps/ps-pdm-dma.c | 12 ++++++------ sound/soc/amd/ps/ps-sdw-dma.c | 6 +++--- sound/soc/amd/rpl/rpl-pci-acp6x.c | 10 +++++----- sound/soc/amd/vangogh/acp5x-pcm-dma.c | 11 +++++------ sound/soc/amd/yc/acp6x-pdm-dma.c | 12 ++++++------ sound/soc/amd/yc/pci-acp6x.c | 10 +++++----- 12 files changed, 53 insertions(+), 54 deletions(-) diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 9322379cb36f..de1cdca5ade7 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -221,7 +221,7 @@ disable_pci: return ret; }; -static int __maybe_unused snd_acp_suspend(struct device *dev) +static int snd_acp_suspend(struct device *dev) { struct acp_chip_info *chip; int ret; @@ -233,7 +233,7 @@ static int __maybe_unused snd_acp_suspend(struct device *dev) return ret; } -static int __maybe_unused snd_acp_resume(struct device *dev) +static int snd_acp_resume(struct device *dev) { struct acp_chip_info *chip; int ret; @@ -251,8 +251,8 @@ static int __maybe_unused snd_acp_resume(struct device *dev) } static const struct dev_pm_ops acp_pm_ops = { - SET_RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume) + RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_resume, NULL) + SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume) }; static void acp_pci_remove(struct pci_dev *pci) @@ -289,7 +289,7 @@ static struct pci_driver snd_amd_acp_pci_driver = { .probe = acp_pci_probe, .remove = acp_pci_remove, .driver = { - .pm = &acp_pm_ops, + .pm = pm_ptr(&acp_pm_ops), }, }; module_pci_driver(snd_amd_acp_pci_driver); diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c index 21614e2e1b6c..746b6ed72029 100644 --- a/sound/soc/amd/acp/acp-rembrandt.c +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -197,7 +197,7 @@ static void rembrandt_audio_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused rmb_pcm_resume(struct device *dev) +static int rmb_pcm_resume(struct device *dev) { struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; @@ -227,7 +227,7 @@ static int __maybe_unused rmb_pcm_resume(struct device *dev) } static const struct dev_pm_ops rmb_dma_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, rmb_pcm_resume) + SYSTEM_SLEEP_PM_OPS(NULL, rmb_pcm_resume) }; static struct platform_driver rembrandt_driver = { @@ -235,7 +235,7 @@ static struct platform_driver rembrandt_driver = { .remove = rembrandt_audio_remove, .driver = { .name = "acp_asoc_rembrandt", - .pm = &rmb_dma_pm_ops, + .pm = pm_ptr(&rmb_dma_pm_ops), }, }; diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index b8ded929d52e..ebf0106fc737 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -144,7 +144,7 @@ static void renoir_audio_remove(struct platform_device *pdev) acp_platform_unregister(dev); } -static int __maybe_unused rn_pcm_resume(struct device *dev) +static int rn_pcm_resume(struct device *dev) { struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; @@ -171,7 +171,7 @@ static int __maybe_unused rn_pcm_resume(struct device *dev) } static const struct dev_pm_ops rn_dma_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, rn_pcm_resume) + SYSTEM_SLEEP_PM_OPS(NULL, rn_pcm_resume) }; static struct platform_driver renoir_driver = { @@ -179,7 +179,7 @@ static struct platform_driver renoir_driver = { .remove = renoir_audio_remove, .driver = { .name = "acp_asoc_renoir", - .pm = &rn_dma_pm_ops, + .pm = pm_ptr(&rn_dma_pm_ops), }, }; diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c index 53c013a64854..52d895e624c7 100644 --- a/sound/soc/amd/acp/acp63.c +++ b/sound/soc/amd/acp/acp63.c @@ -248,7 +248,7 @@ static void acp63_audio_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused acp63_pcm_resume(struct device *dev) +static int acp63_pcm_resume(struct device *dev) { struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; @@ -278,7 +278,7 @@ static int __maybe_unused acp63_pcm_resume(struct device *dev) } static const struct dev_pm_ops acp63_dma_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, acp63_pcm_resume) + SYSTEM_SLEEP_PM_OPS(NULL, acp63_pcm_resume) }; static struct platform_driver acp63_driver = { @@ -286,7 +286,7 @@ static struct platform_driver acp63_driver = { .remove = acp63_audio_remove, .driver = { .name = "acp_asoc_acp63", - .pm = &acp63_dma_pm_ops, + .pm = pm_ptr(&acp63_dma_pm_ops), }, }; diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c index 1a89f8a3724f..6d5f5ade075c 100644 --- a/sound/soc/amd/acp/acp70.c +++ b/sound/soc/amd/acp/acp70.c @@ -180,7 +180,7 @@ static void acp_acp70_audio_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused acp70_pcm_resume(struct device *dev) +static int acp70_pcm_resume(struct device *dev) { struct acp_chip_info *chip = dev_get_platdata(dev); struct acp_stream *stream; @@ -207,7 +207,7 @@ static int __maybe_unused acp70_pcm_resume(struct device *dev) } static const struct dev_pm_ops acp70_dma_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, acp70_pcm_resume) + SYSTEM_SLEEP_PM_OPS(NULL, acp70_pcm_resume) }; static struct platform_driver acp70_driver = { @@ -215,7 +215,7 @@ static struct platform_driver acp70_driver = { .remove = acp_acp70_audio_remove, .driver = { .name = "acp_asoc_acp70", - .pm = &acp70_dma_pm_ops, + .pm = pm_ptr(&acp70_dma_pm_ops), }, }; diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c index 221c65ff03c9..8e57f31ef7f7 100644 --- a/sound/soc/amd/ps/pci-ps.c +++ b/sound/soc/amd/ps/pci-ps.c @@ -668,24 +668,24 @@ disable_pci: return ret; } -static int __maybe_unused snd_acp_suspend(struct device *dev) +static int snd_acp_suspend(struct device *dev) { return acp_hw_suspend(dev); } -static int __maybe_unused snd_acp_runtime_resume(struct device *dev) +static int snd_acp_runtime_resume(struct device *dev) { return acp_hw_runtime_resume(dev); } -static int __maybe_unused snd_acp_resume(struct device *dev) +static int snd_acp_resume(struct device *dev) { return acp_hw_resume(dev); } static const struct dev_pm_ops acp63_pm_ops = { - SET_RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume) + RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume) }; static void snd_acp63_remove(struct pci_dev *pci) @@ -727,7 +727,7 @@ static struct pci_driver ps_acp63_driver = { .probe = snd_acp63_probe, .remove = snd_acp63_remove, .driver = { - .pm = &acp63_pm_ops, + .pm = pm_ptr(&acp63_pm_ops), } }; diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c index 7cdeb34e8f73..9cfbe05ad996 100644 --- a/sound/soc/amd/ps/ps-pdm-dma.c +++ b/sound/soc/amd/ps/ps-pdm-dma.c @@ -402,7 +402,7 @@ static void acp63_pdm_audio_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused acp63_pdm_resume(struct device *dev) +static int acp63_pdm_resume(struct device *dev) { struct pdm_dev_data *adata; struct snd_pcm_runtime *runtime; @@ -423,7 +423,7 @@ static int __maybe_unused acp63_pdm_resume(struct device *dev) return 0; } -static int __maybe_unused acp63_pdm_suspend(struct device *dev) +static int acp63_pdm_suspend(struct device *dev) { struct pdm_dev_data *adata; @@ -432,7 +432,7 @@ static int __maybe_unused acp63_pdm_suspend(struct device *dev) return 0; } -static int __maybe_unused acp63_pdm_runtime_resume(struct device *dev) +static int acp63_pdm_runtime_resume(struct device *dev) { struct pdm_dev_data *adata; @@ -442,8 +442,8 @@ static int __maybe_unused acp63_pdm_runtime_resume(struct device *dev) } static const struct dev_pm_ops acp63_pdm_pm_ops = { - SET_RUNTIME_PM_OPS(acp63_pdm_suspend, acp63_pdm_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(acp63_pdm_suspend, acp63_pdm_resume) + RUNTIME_PM_OPS(acp63_pdm_suspend, acp63_pdm_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(acp63_pdm_suspend, acp63_pdm_resume) }; static struct platform_driver acp63_pdm_dma_driver = { @@ -451,7 +451,7 @@ static struct platform_driver acp63_pdm_dma_driver = { .remove = acp63_pdm_audio_remove, .driver = { .name = "acp_ps_pdm_dma", - .pm = &acp63_pdm_pm_ops, + .pm = pm_ptr(&acp63_pdm_pm_ops), }, }; diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 21b336109c99..1b933a017c06 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -767,7 +767,7 @@ static int acp70_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data) return 0; } -static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) +static int acp63_sdw_pcm_resume(struct device *dev) { struct sdw_dma_dev_data *sdw_data; @@ -779,7 +779,7 @@ static int __maybe_unused acp63_sdw_pcm_resume(struct device *dev) } static const struct dev_pm_ops acp63_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, acp63_sdw_pcm_resume) + SYSTEM_SLEEP_PM_OPS(NULL, acp63_sdw_pcm_resume) }; static struct platform_driver acp63_sdw_dma_driver = { @@ -787,7 +787,7 @@ static struct platform_driver acp63_sdw_dma_driver = { .remove = acp63_sdw_platform_remove, .driver = { .name = "amd_ps_sdw_dma", - .pm = &acp63_pm_ops, + .pm = pm_ptr(&acp63_pm_ops), }, }; diff --git a/sound/soc/amd/rpl/rpl-pci-acp6x.c b/sound/soc/amd/rpl/rpl-pci-acp6x.c index a8e548ed991b..e3afe9172bdf 100644 --- a/sound/soc/amd/rpl/rpl-pci-acp6x.c +++ b/sound/soc/amd/rpl/rpl-pci-acp6x.c @@ -159,7 +159,7 @@ disable_pci: return ret; } -static int __maybe_unused snd_rpl_suspend(struct device *dev) +static int snd_rpl_suspend(struct device *dev) { struct rpl_dev_data *adata; int ret; @@ -171,7 +171,7 @@ static int __maybe_unused snd_rpl_suspend(struct device *dev) return ret; } -static int __maybe_unused snd_rpl_resume(struct device *dev) +static int snd_rpl_resume(struct device *dev) { struct rpl_dev_data *adata; int ret; @@ -184,8 +184,8 @@ static int __maybe_unused snd_rpl_resume(struct device *dev) } static const struct dev_pm_ops rpl_pm = { - SET_RUNTIME_PM_OPS(snd_rpl_suspend, snd_rpl_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(snd_rpl_suspend, snd_rpl_resume) + RUNTIME_PM_OPS(snd_rpl_suspend, snd_rpl_resume, NULL) + SYSTEM_SLEEP_PM_OPS(snd_rpl_suspend, snd_rpl_resume) }; static void snd_rpl_remove(struct pci_dev *pci) @@ -217,7 +217,7 @@ static struct pci_driver rpl_acp6x_driver = { .probe = snd_rpl_probe, .remove = snd_rpl_remove, .driver = { - .pm = &rpl_pm, + .pm = pm_ptr(&rpl_pm), } }; diff --git a/sound/soc/amd/vangogh/acp5x-pcm-dma.c b/sound/soc/amd/vangogh/acp5x-pcm-dma.c index d5965f2b09bc..aa4726899434 100644 --- a/sound/soc/amd/vangogh/acp5x-pcm-dma.c +++ b/sound/soc/amd/vangogh/acp5x-pcm-dma.c @@ -420,7 +420,7 @@ static void acp5x_audio_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused acp5x_pcm_resume(struct device *dev) +static int acp5x_pcm_resume(struct device *dev) { struct i2s_dev_data *adata; struct i2s_stream_instance *rtd; @@ -473,7 +473,7 @@ static int __maybe_unused acp5x_pcm_resume(struct device *dev) return 0; } -static int __maybe_unused acp5x_pcm_suspend(struct device *dev) +static int acp5x_pcm_suspend(struct device *dev) { struct i2s_dev_data *adata; @@ -482,7 +482,7 @@ static int __maybe_unused acp5x_pcm_suspend(struct device *dev) return 0; } -static int __maybe_unused acp5x_pcm_runtime_resume(struct device *dev) +static int acp5x_pcm_runtime_resume(struct device *dev) { struct i2s_dev_data *adata; @@ -492,9 +492,8 @@ static int __maybe_unused acp5x_pcm_runtime_resume(struct device *dev) } static const struct dev_pm_ops acp5x_pm_ops = { - SET_RUNTIME_PM_OPS(acp5x_pcm_suspend, - acp5x_pcm_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(acp5x_pcm_suspend, acp5x_pcm_resume) + RUNTIME_PM_OPS(acp5x_pcm_suspend, acp5x_pcm_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(acp5x_pcm_suspend, acp5x_pcm_resume) }; static struct platform_driver acp5x_dma_driver = { diff --git a/sound/soc/amd/yc/acp6x-pdm-dma.c b/sound/soc/amd/yc/acp6x-pdm-dma.c index 3eb3e82efb10..ac758b90f441 100644 --- a/sound/soc/amd/yc/acp6x-pdm-dma.c +++ b/sound/soc/amd/yc/acp6x-pdm-dma.c @@ -394,7 +394,7 @@ static void acp6x_pdm_audio_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } -static int __maybe_unused acp6x_pdm_resume(struct device *dev) +static int acp6x_pdm_resume(struct device *dev) { struct pdm_dev_data *adata; struct snd_pcm_runtime *runtime; @@ -415,7 +415,7 @@ static int __maybe_unused acp6x_pdm_resume(struct device *dev) return 0; } -static int __maybe_unused acp6x_pdm_suspend(struct device *dev) +static int acp6x_pdm_suspend(struct device *dev) { struct pdm_dev_data *adata; @@ -424,7 +424,7 @@ static int __maybe_unused acp6x_pdm_suspend(struct device *dev) return 0; } -static int __maybe_unused acp6x_pdm_runtime_resume(struct device *dev) +static int acp6x_pdm_runtime_resume(struct device *dev) { struct pdm_dev_data *adata; @@ -434,8 +434,8 @@ static int __maybe_unused acp6x_pdm_runtime_resume(struct device *dev) } static const struct dev_pm_ops acp6x_pdm_pm_ops = { - SET_RUNTIME_PM_OPS(acp6x_pdm_suspend, acp6x_pdm_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(acp6x_pdm_suspend, acp6x_pdm_resume) + RUNTIME_PM_OPS(acp6x_pdm_suspend, acp6x_pdm_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(acp6x_pdm_suspend, acp6x_pdm_resume) }; static struct platform_driver acp6x_pdm_dma_driver = { @@ -443,7 +443,7 @@ static struct platform_driver acp6x_pdm_dma_driver = { .remove = acp6x_pdm_audio_remove, .driver = { .name = "acp_yc_pdm_dma", - .pm = &acp6x_pdm_pm_ops, + .pm = pm_ptr(&acp6x_pdm_pm_ops), }, }; diff --git a/sound/soc/amd/yc/pci-acp6x.c b/sound/soc/amd/yc/pci-acp6x.c index 7af6a349b1d4..1140ed1cbb3d 100644 --- a/sound/soc/amd/yc/pci-acp6x.c +++ b/sound/soc/amd/yc/pci-acp6x.c @@ -277,7 +277,7 @@ disable_pci: return ret; } -static int __maybe_unused snd_acp6x_suspend(struct device *dev) +static int snd_acp6x_suspend(struct device *dev) { struct acp6x_dev_data *adata; int ret; @@ -289,7 +289,7 @@ static int __maybe_unused snd_acp6x_suspend(struct device *dev) return ret; } -static int __maybe_unused snd_acp6x_resume(struct device *dev) +static int snd_acp6x_resume(struct device *dev) { struct acp6x_dev_data *adata; int ret; @@ -302,8 +302,8 @@ static int __maybe_unused snd_acp6x_resume(struct device *dev) } static const struct dev_pm_ops acp6x_pm = { - SET_RUNTIME_PM_OPS(snd_acp6x_suspend, snd_acp6x_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(snd_acp6x_suspend, snd_acp6x_resume) + RUNTIME_PM_OPS(snd_acp6x_suspend, snd_acp6x_resume, NULL) + SYSTEM_SLEEP_PM_OPS(snd_acp6x_suspend, snd_acp6x_resume) }; static void snd_acp6x_remove(struct pci_dev *pci) @@ -339,7 +339,7 @@ static struct pci_driver yc_acp6x_driver = { .probe = snd_acp6x_probe, .remove = snd_acp6x_remove, .driver = { - .pm = &acp6x_pm, + .pm = pm_ptr(&acp6x_pm), } }; From 15559cdeb9be5a0fe528cdc3f8b759a27ea8f943 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 17 Mar 2025 10:55:50 +0100 Subject: [PATCH 600/651] ASoC: pcm3168a: Convert to EXPORT_GPL_DEV_PM_OPS() Use the newer EXPORT_GPL_DEV_PM_OPS() macro together with pm_ptr(), which allows us to drop superfluous CONFIG_PM ifdefs. This optimizes slightly when CONFIG_PM is disabled, too. Cc: Shenghao Ding Cc: Kevin Lu Cc: Baojun Xu Signed-off-by: Takashi Iwai Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250317095603.20073-89-tiwai@suse.de Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a-i2c.c | 2 +- sound/soc/codecs/pcm3168a-spi.c | 2 +- sound/soc/codecs/pcm3168a.c | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/pcm3168a-i2c.c b/sound/soc/codecs/pcm3168a-i2c.c index 4da608ba514d..ff18c74b616c 100644 --- a/sound/soc/codecs/pcm3168a-i2c.c +++ b/sound/soc/codecs/pcm3168a-i2c.c @@ -59,7 +59,7 @@ static struct i2c_driver pcm3168a_i2c_driver = { .name = "pcm3168a", .acpi_match_table = pcm3168a_acpi_match, .of_match_table = pcm3168a_of_match, - .pm = &pcm3168a_pm_ops, + .pm = pm_ptr(&pcm3168a_pm_ops), }, }; module_i2c_driver(pcm3168a_i2c_driver); diff --git a/sound/soc/codecs/pcm3168a-spi.c b/sound/soc/codecs/pcm3168a-spi.c index b5b08046f545..0871338eacba 100644 --- a/sound/soc/codecs/pcm3168a-spi.c +++ b/sound/soc/codecs/pcm3168a-spi.c @@ -50,7 +50,7 @@ static struct spi_driver pcm3168a_spi_driver = { .driver = { .name = "pcm3168a", .of_match_table = pcm3168a_of_match, - .pm = &pcm3168a_pm_ops, + .pm = pm_ptr(&pcm3168a_pm_ops), }, }; module_spi_driver(pcm3168a_spi_driver); diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index df6836a652ef..c8617a488b11 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -849,7 +849,6 @@ void pcm3168a_remove(struct device *dev) } EXPORT_SYMBOL_GPL(pcm3168a_remove); -#ifdef CONFIG_PM static int pcm3168a_rt_resume(struct device *dev) { struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev); @@ -905,12 +904,10 @@ static int pcm3168a_rt_suspend(struct device *dev) return 0; } -#endif -const struct dev_pm_ops pcm3168a_pm_ops = { - SET_RUNTIME_PM_OPS(pcm3168a_rt_suspend, pcm3168a_rt_resume, NULL) +EXPORT_GPL_DEV_PM_OPS(pcm3168a_pm_ops) = { + RUNTIME_PM_OPS(pcm3168a_rt_suspend, pcm3168a_rt_resume, NULL) }; -EXPORT_SYMBOL_GPL(pcm3168a_pm_ops); MODULE_DESCRIPTION("PCM3168A codec driver"); MODULE_AUTHOR("Damien Horsley "); From 9c2c0ef6400980f09b377be250f5dff14dbbf3b6 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Mon, 17 Mar 2025 12:54:07 +0530 Subject: [PATCH 601/651] ASoC: amd: acp: Fix snd_soc_acpi_mach id's duplicate symbol error Move snd_soc_acpi_mach id's of all acp platforms form header file to amd-acpi-mach.c file to avoid below errors. ld.lld: error: duplicate symbol: amp_rt1019 ld.lld: error: duplicate symbol: amp_max ld.lld: error: duplicate symbol: snd_soc_acpi_amd_acp63_acp_machines ld.lld: error: duplicate symbol: snd_soc_acpi_amd_acp70_acp_machines ld.lld: error: duplicate symbol: snd_soc_acpi_amd_rmb_acp_machines ld.lld: error: duplicate symbol: snd_soc_acpi_amd_acp_machines Fixes: 6e60db74b69c ("ASoC: amd: acp: Refactor acp machine select") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503160801.yExt0K2E-lkp@intel.com/ Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250317072413.88971-1-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/Kconfig | 8 +++ sound/soc/amd/acp/Makefile | 2 + sound/soc/amd/acp/acp-pci.c | 8 +-- sound/soc/amd/acp/amd-acpi-mach.c | 93 +++++++++++++++++++++++++++++++ sound/soc/amd/acp/amd.h | 79 ++------------------------ 5 files changed, 111 insertions(+), 79 deletions(-) create mode 100644 sound/soc/amd/acp/amd-acpi-mach.c diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 157c124570c8..b9432052c638 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -28,6 +28,9 @@ config SND_SOC_AMD_ACP_LEGACY_COMMON config SND_SOC_AMD_ACP_I2S tristate +config SND_SOC_AMD_ACPI_MACH + tristate + config SND_SOC_AMD_ACP_PCM tristate select SND_SOC_ACPI if ACPI @@ -37,6 +40,7 @@ config SND_SOC_AMD_ACP_PCI depends on X86 && PCI depends on ACPI select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH help This options enables generic PCI driver for ACP device. @@ -47,6 +51,7 @@ config SND_AMD_ASOC_RENOIR select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH depends on X86 && PCI help This option enables Renoir I2S support on AMD platform. @@ -58,6 +63,7 @@ config SND_AMD_ASOC_REMBRANDT select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH depends on AMD_NODE depends on X86 && PCI help @@ -74,6 +80,7 @@ config SND_AMD_ASOC_ACP63 select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH help This option enables Acp6.3 I2S support on AMD platform. Say Y if you want to enable AUDIO on ACP6.3 @@ -88,6 +95,7 @@ config SND_AMD_ASOC_ACP70 select SND_SOC_AMD_ACP_I2S select SND_SOC_AMD_ACP_PDM select SND_SOC_AMD_ACP_LEGACY_COMMON + select SND_SOC_AMD_ACPI_MACH help This option enables Acp7.0 PDM support on AMD platform. Say Y if you want to enable AUDIO on ACP7.0 diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile index 7c75892e678b..08220b9a3802 100644 --- a/sound/soc/amd/acp/Makefile +++ b/sound/soc/amd/acp/Makefile @@ -11,6 +11,7 @@ snd-acp-pdm-y := acp-pdm.o snd-acp-legacy-common-y := acp-legacy-common.o snd-acp-pci-y := acp-pci.o snd-amd-sdw-acpi-y := amd-sdw-acpi.o +snd-amd-acpi-mach-y := amd-acpi-mach.o #platform specific driver snd-acp-renoir-y := acp-renoir.o @@ -32,6 +33,7 @@ obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o obj-$(CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON) += snd-acp-legacy-common.o obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o +obj-$(CONFIG_SND_SOC_AMD_ACPI_MACH) += snd-amd-acpi-mach.o obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index 123524f90d6c..1892fbdfc780 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -137,26 +137,26 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->name = "acp_asoc_renoir"; chip->rsrc = &rn_rsrc; chip->acp_hw_ops_init = acp31_hw_ops_init; - chip->machines = snd_soc_acpi_amd_acp_machines; + chip->machines = &snd_soc_acpi_amd_acp_machines; break; case 0x6f: chip->name = "acp_asoc_rembrandt"; chip->rsrc = &rmb_rsrc; chip->acp_hw_ops_init = acp6x_hw_ops_init; - chip->machines = snd_soc_acpi_amd_rmb_acp_machines; + chip->machines = &snd_soc_acpi_amd_rmb_acp_machines; break; case 0x63: chip->name = "acp_asoc_acp63"; chip->rsrc = &acp63_rsrc; chip->acp_hw_ops_init = acp63_hw_ops_init; - chip->machines = snd_soc_acpi_amd_acp63_acp_machines; + chip->machines = &snd_soc_acpi_amd_acp63_acp_machines; break; case 0x70: case 0x71: chip->name = "acp_asoc_acp70"; chip->rsrc = &acp70_rsrc; chip->acp_hw_ops_init = acp70_hw_ops_init; - chip->machines = snd_soc_acpi_amd_acp70_acp_machines; + chip->machines = &snd_soc_acpi_amd_acp70_acp_machines; break; default: dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision); diff --git a/sound/soc/amd/acp/amd-acpi-mach.c b/sound/soc/amd/acp/amd-acpi-mach.c new file mode 100644 index 000000000000..d95047d2ee94 --- /dev/null +++ b/sound/soc/amd/acp/amd-acpi-mach.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * amd-acpi-match.c - tables and support for ACP platforms + * ACPI enumeration. + * + * Copyright 2025 Advanced Micro Devices, Inc. + */ + +#include + +struct snd_soc_acpi_codecs amp_rt1019 = { + .num_codecs = 1, + .codecs = {"10EC1019"} +}; + +struct snd_soc_acpi_codecs amp_max = { + .num_codecs = 1, + .codecs = {"MX98360A"} +}; + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { + { + .id = "10EC5682", + .drv_name = "acp3xalc56821019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + { + .id = "RTL5682", + .drv_name = "acp3xalc5682sm98360", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + }, + { + .id = "RTL5682", + .drv_name = "acp3xalc5682s1019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + { + .id = "AMDI1019", + .drv_name = "renoir-acp", + }, + { + .id = "ESSX8336", + .drv_name = "acp3x-es83xx", + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_acp_machines, "SND_SOC_ACP_COMMON"); + +struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = { + { + .id = "10508825", + .drv_name = "rmb-nau8825-max", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + }, + { + .id = "AMDI0007", + .drv_name = "rembrandt-acp", + }, + { + .id = "RTL5682", + .drv_name = "rmb-rt5682s-rt1019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_rmb_acp_machines, "SND_SOC_ACP_COMMON"); + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines[] = { + { + .id = "AMDI0052", + .drv_name = "acp63-acp", + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_acp63_acp_machines, "SND_SOC_ACP_COMMON"); + +struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { + { + .id = "AMDI0029", + .drv_name = "acp70-acp", + }, + {}, +}; +EXPORT_SYMBOL_NS_GPL(snd_soc_acpi_amd_acp70_acp_machines, "SND_SOC_ACP_COMMON"); + +MODULE_DESCRIPTION("AMD ACP tables and support for ACPI enumeration"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Venkataprasad.potturu@amd.com"); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 796f8efd395c..928aa60ab386 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -277,81 +277,10 @@ struct acp_resource acp70_rsrc = { .sram_pte_offset = 0x03800000, }; -struct snd_soc_acpi_codecs amp_rt1019 = { - .num_codecs = 1, - .codecs = {"10EC1019"} -}; - -struct snd_soc_acpi_codecs amp_max = { - .num_codecs = 1, - .codecs = {"MX98360A"} -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { - { - .id = "10EC5682", - .drv_name = "acp3xalc56821019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - { - .id = "RTL5682", - .drv_name = "acp3xalc5682sm98360", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_max, - }, - { - .id = "RTL5682", - .drv_name = "acp3xalc5682s1019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - { - .id = "AMDI1019", - .drv_name = "renoir-acp", - }, - { - .id = "ESSX8336", - .drv_name = "acp3x-es83xx", - }, - {}, -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = { - { - .id = "10508825", - .drv_name = "rmb-nau8825-max", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_max, - }, - { - .id = "AMDI0007", - .drv_name = "rembrandt-acp", - }, - { - .id = "RTL5682", - .drv_name = "rmb-rt5682s-rt1019", - .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &_rt1019, - }, - {}, -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines[] = { - { - .id = "AMDI0052", - .drv_name = "acp63-acp", - }, - {}, -}; - -struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = { - { - .id = "AMDI0029", - .drv_name = "acp70-acp", - }, - {}, -}; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_acp_machines; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines; extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; extern const struct snd_soc_dai_ops acp_dmic_dai_ops; From 09dc8031f4a84103f4ba8f704ec21f1926b04366 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Mon, 17 Mar 2025 12:54:08 +0530 Subject: [PATCH 602/651] ASoC: amd: acp: Fix acp_resource duplicate symbol error Fix acp_resource structure duplicate defination error by adding export symbol and extern keyword in header file. ld.lld: error: duplicate symbol: acp63_rsrc ld.lld: error: duplicate symbol: acp70_rsrc Fixes: f8b4f3f525e8 ("ASoC: amd: acp: Refactor acp70 platform resource structure") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503160801.yExt0K2E-lkp@intel.com/ Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250317072413.88971-2-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 43 +++++++++++++++++++++++++++ sound/soc/amd/acp/amd.h | 42 +++----------------------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 255f90ca956a..5fad6c4a8d86 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -24,6 +24,49 @@ #define ACP63_PDM_ADDR 0x02 #define ACP70_PDM_ADDR 0x02 +struct acp_resource rn_rsrc = { + .offset = 20, + .no_of_ctrls = 1, + .irqp_used = 0, + .irq_reg_offset = 0x1800, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x02052800, +}; +EXPORT_SYMBOL_NS_GPL(rn_rsrc, "SND_SOC_ACP_COMMON"); + +struct acp_resource rmb_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x03802800, +}; +EXPORT_SYMBOL_NS_GPL(rmb_rsrc, "SND_SOC_ACP_COMMON"); + +struct acp_resource acp63_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x03802800, +}; +EXPORT_SYMBOL_NS_GPL(acp63_rsrc, "SND_SOC_ACP_COMMON"); + +struct acp_resource acp70_rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .scratch_reg_offset = 0x10000, + .sram_pte_offset = 0x03800000, +}; +EXPORT_SYMBOL_NS_GPL(acp70_rsrc, "SND_SOC_ACP_COMMON"); + const struct snd_acp_hw_ops acp_common_hw_ops = { /* ACP hardware initilizations */ .acp_init = acp_init, diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 928aa60ab386..863e74fcee43 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -238,44 +238,10 @@ enum acp_config { ACP_CONFIG_20, }; -struct acp_resource rn_rsrc = { - .offset = 20, - .no_of_ctrls = 1, - .irqp_used = 0, - .irq_reg_offset = 0x1800, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x02052800, -}; - -struct acp_resource rmb_rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x03802800, -}; - -struct acp_resource acp63_rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x12800, - .sram_pte_offset = 0x03802800, -}; - -struct acp_resource acp70_rsrc = { - .offset = 0, - .no_of_ctrls = 2, - .irqp_used = 1, - .soc_mclk = true, - .irq_reg_offset = 0x1a00, - .scratch_reg_offset = 0x10000, - .sram_pte_offset = 0x03800000, -}; +extern struct acp_resource rn_rsrc; +extern struct acp_resource rmb_rsrc; +extern struct acp_resource acp63_rsrc; +extern struct acp_resource acp70_rsrc; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines; extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines; From 77ad261ecc4aa1b09bc98b32cdbfadb5e92197b7 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Mon, 17 Mar 2025 12:54:09 +0530 Subject: [PATCH 603/651] ASoC: amd: acp: Fix acp_common_hw_ops declaration error Fix acp_common_hw_ops declaration error by adding static and remove export symbol. sparse: symbol 'acp_common_hw_ops' was not declared. Should it be static? Fixes: 8ae746fe5104 ("ASoC: amd: acp: Implement acp_common_hw_ops support for acp platforms") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503141442.iT0LHEMx-lkp@intel.com/ Signed-off-by: Venkata Prasad Potturu Link: https://patch.msgid.link/20250317072413.88971-3-venkataprasad.potturu@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-legacy-common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c index 5fad6c4a8d86..b4d68484e06d 100644 --- a/sound/soc/amd/acp/acp-legacy-common.c +++ b/sound/soc/amd/acp/acp-legacy-common.c @@ -67,7 +67,7 @@ struct acp_resource acp70_rsrc = { }; EXPORT_SYMBOL_NS_GPL(acp70_rsrc, "SND_SOC_ACP_COMMON"); -const struct snd_acp_hw_ops acp_common_hw_ops = { +static const struct snd_acp_hw_ops acp_common_hw_ops = { /* ACP hardware initilizations */ .acp_init = acp_init, .acp_deinit = acp_deinit, @@ -77,7 +77,6 @@ const struct snd_acp_hw_ops acp_common_hw_ops = { .en_interrupts = acp_enable_interrupts, .dis_interrupts = acp_disable_interrupts, }; -EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON"); irqreturn_t acp_irq_handler(int irq, void *data) { From 6d9d66626c58bcd9b949574aca7d47149b8ad9e1 Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Mon, 17 Mar 2025 08:21:56 -0400 Subject: [PATCH 604/651] ASoC: Intel: avs: Replace devm_kzalloc() with devm_kcalloc() Open coded arithmetic in allocator arguments is discouraged [1]. Helper functions like kcalloc or, in this case, devm_kcalloc are preferred. [1]: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Signed-off-by: Ethan Carter Edwards Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/20250317-sound-avs-kcalloc-v2-1-20e2a132b18f@ethancedwards.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 4bfbcb5a5ae8..dac463390da1 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1380,7 +1380,7 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l for_each_set_bit(i, &port_mask, ssp_count) cpu_count += hweight_long(tdms[i]); - cpus = devm_kzalloc(adev->dev, sizeof(*cpus) * cpu_count, GFP_KERNEL); + cpus = devm_kcalloc(adev->dev, cpu_count, sizeof(*cpus), GFP_KERNEL); if (!cpus) return -ENOMEM; From 61b1a1bddf7d166946d7ca7054b6cbced29b72f5 Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Mon, 17 Mar 2025 08:21:57 -0400 Subject: [PATCH 605/651] ASoC: Intel: avs: ssm4567: Replace devm_kzalloc() with devm_kcalloc() Open coded arithmetic in allocator arguments is discouraged [1]. Helper functions like kcalloc or, in this case, devm_kcalloc are preferred. [1]: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Signed-off-by: Ethan Carter Edwards Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/20250317-sound-avs-kcalloc-v2-2-20e2a132b18f@ethancedwards.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/ssm4567.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c index c9d89bfe7178..7667790d5273 100644 --- a/sound/soc/intel/avs/boards/ssm4567.c +++ b/sound/soc/intel/avs/boards/ssm4567.c @@ -97,7 +97,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); - dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); + dl->codecs = devm_kcalloc(dev, 2, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; From bde479694a7da7c127bb5bba98e2e4773f1d7951 Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Mon, 17 Mar 2025 08:21:58 -0400 Subject: [PATCH 606/651] ASoC: Intel: avs: max98373: Replace devm_kzalloc() with devm_kcalloc() Open coded arithmetic in allocator arguments is discouraged [1]. Helper functions like kcalloc or, in this case, devm_kcalloc are preferred. [1]: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Signed-off-by: Ethan Carter Edwards Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/20250317-sound-avs-kcalloc-v2-3-20e2a132b18f@ethancedwards.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/max98373.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c index 6f25e66344b7..970f82bf4ce8 100644 --- a/sound/soc/intel/avs/boards/max98373.c +++ b/sound/soc/intel/avs/boards/max98373.c @@ -111,7 +111,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); - dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); + dl->codecs = devm_kcalloc(dev, 2, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; From 3602571baf9a6864bde89422d179e422a3ea4d8d Mon Sep 17 00:00:00 2001 From: Ethan Carter Edwards Date: Mon, 17 Mar 2025 08:21:59 -0400 Subject: [PATCH 607/651] ASoC: Intel: avs: max98927: Replace devm_kzalloc() with devm_kcalloc() Open coded arithmetic in allocator arguments is discouraged [1]. Helper functions like kcalloc or, in this case, devm_kcalloc are preferred. [1]: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Signed-off-by: Ethan Carter Edwards Reviewed-by: Cezary Rojewski Link: https://patch.msgid.link/20250317-sound-avs-kcalloc-v2-4-20e2a132b18f@ethancedwards.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/max98927.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c index e8e5d1c717cd..e4ce553bf1d6 100644 --- a/sound/soc/intel/avs/boards/max98927.c +++ b/sound/soc/intel/avs/boards/max98927.c @@ -108,7 +108,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->name = devm_kasprintf(dev, GFP_KERNEL, AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); - dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); + dl->codecs = devm_kcalloc(dev, 2, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; From 811944a790451169876947a89338d2b86ff9fe5b Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 11 Mar 2025 12:32:53 -0400 Subject: [PATCH 608/651] ASoC: dt-bindings: support imx95's CM7 core Add binding for imx95's CM7 core, used for audio processing. Additionally, introduce a common binding for NXP audio processors with Sound Open Firmware (SOF) support. Signed-off-by: Laurentiu Mihalcea Reviewed-by: Krzysztof Kozlowski Reviewed-by: Iuliana Prodan Link: https://patch.msgid.link/20250311163255.2664-2-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- .../bindings/sound/fsl,imx95-cm7-sof.yaml | 64 +++++++++++++++++++ .../bindings/sound/fsl,sof-cpu.yaml | 27 ++++++++ 2 files changed, 91 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml create mode 100644 Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml diff --git a/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml b/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml new file mode 100644 index 000000000000..f00ae3219e15 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,imx95-cm7-sof.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/fsl,imx95-cm7-sof.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP imx95 CM7 core + +maintainers: + - Daniel Baluta + +description: NXP imx95 CM7 core used for audio processing + +properties: + compatible: + const: fsl,imx95-cm7-sof + + reg: + maxItems: 1 + + reg-names: + const: sram + + memory-region: + maxItems: 1 + + memory-region-names: + const: dma + + port: + description: SAI3 port + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + - reg-names + - memory-region + - memory-region-names + - port + +allOf: + - $ref: fsl,sof-cpu.yaml# + +unevaluatedProperties: false + +examples: + - | + cm7-cpu@80000000 { + compatible = "fsl,imx95-cm7-sof"; + reg = <0x80000000 0x6100000>; + reg-names = "sram"; + mboxes = <&mu7 2 0>, <&mu7 2 1>, <&mu7 3 0>, <&mu7 3 1>; + mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1"; + memory-region = <&adma_res>; + memory-region-names = "dma"; + port { + /* SAI3-WM8962 link */ + endpoint { + remote-endpoint = <&wm8962_ep>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml b/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml new file mode 100644 index 000000000000..31863932dbc3 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,sof-cpu.yaml @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/fsl,sof-cpu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP audio processor common properties + +maintainers: + - Daniel Baluta + +properties: + mboxes: + maxItems: 4 + + mbox-names: + items: + - const: txdb0 + - const: txdb1 + - const: rxdb0 + - const: rxdb1 + +required: + - mboxes + - mbox-names + +additionalProperties: true From ed92f40eccc801bd0e5dfd78b1058072638471f1 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Tue, 11 Mar 2025 12:32:54 -0400 Subject: [PATCH 609/651] ASoC: dt-bindings: audio-graph-card2: add widgets and hp-det-gpios support Introduce the 'widgets' property, allowing the creation of widgets from 4 template widgets: Microphone, Line, Headphone, and Speaker. Also introduce the 'hp-det-gpios' property, which allows using headphone detection using the specified GPIO. Signed-off-by: Laurentiu Mihalcea Acked-by: Krzysztof Kozlowski Reviewed-by: Iuliana Prodan Reviewed-by: Daniel Baluta Link: https://patch.msgid.link/20250311163255.2664-3-laurentiumihalcea111@gmail.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/audio-graph-card2.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml index f943f90d8b15..94588353f852 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml +++ b/Documentation/devicetree/bindings/sound/audio-graph-card2.yaml @@ -37,6 +37,10 @@ properties: codec2codec: type: object description: Codec to Codec node + hp-det-gpios: + $ref: audio-graph.yaml#/properties/hp-det-gpios + widgets: + $ref: audio-graph.yaml#/properties/widgets required: - compatible From 18abb3797f1ceca97a705aa1c14cbec5c6fcab79 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 17 Mar 2025 10:13:18 +0000 Subject: [PATCH 610/651] ASoC: soc-utils: Transition to the faux device interface The ASoC soc-utils driver does not require the creation of a platform device. Originally, this approach was chosen for simplicity when the driver was first implemented. With the introduction of the lightweight faux device interface, we now have a more appropriate alternative. Migrate the driver to utilize the faux bus, given that the platform device it previously created was not a real one anyway. This will simplify the code, reducing its footprint while maintaining functionality. Cc: Mark Brown Cc: Takashi Iwai Cc: linux-sound@vger.kernel.org Signed-off-by: Sudeep Holla Link: https://patch.msgid.link/20250317-plat2faux_dev-v1-6-5fe67c085ad5@arm.com Signed-off-by: Mark Brown --- sound/soc/soc-utils.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 318b141c00b3..5e3e4f14c392 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -7,7 +7,7 @@ // Author: Mark Brown // Liam Girdwood -#include +#include #include #include #include @@ -262,48 +262,38 @@ struct snd_soc_dai_link_component snd_soc_dummy_dlc = { }; EXPORT_SYMBOL_GPL(snd_soc_dummy_dlc); -static int snd_soc_dummy_probe(struct platform_device *pdev) +static int snd_soc_dummy_probe(struct faux_device *fdev) { int ret; - ret = devm_snd_soc_register_component(&pdev->dev, + ret = devm_snd_soc_register_component(&fdev->dev, &dummy_codec, &dummy_dai, 1); if (ret < 0) return ret; - ret = devm_snd_soc_register_component(&pdev->dev, &dummy_platform, + ret = devm_snd_soc_register_component(&fdev->dev, &dummy_platform, NULL, 0); return ret; } -static struct platform_driver soc_dummy_driver = { - .driver = { - .name = "snd-soc-dummy", - }, +static struct faux_device_ops soc_dummy_ops = { .probe = snd_soc_dummy_probe, }; -static struct platform_device *soc_dummy_dev; +static struct faux_device *soc_dummy_dev; int __init snd_soc_util_init(void) { - int ret; + soc_dummy_dev = faux_device_create("snd-soc-dummy", NULL, + &soc_dummy_ops); + if (!soc_dummy_dev) + return -ENODEV; - soc_dummy_dev = - platform_device_register_simple("snd-soc-dummy", -1, NULL, 0); - if (IS_ERR(soc_dummy_dev)) - return PTR_ERR(soc_dummy_dev); - - ret = platform_driver_register(&soc_dummy_driver); - if (ret != 0) - platform_device_unregister(soc_dummy_dev); - - return ret; + return 0; } void snd_soc_util_exit(void) { - platform_driver_unregister(&soc_dummy_driver); - platform_device_unregister(soc_dummy_dev); + faux_device_destroy(soc_dummy_dev); } From 340abded86def0ab8ad8ef9ba73d8ac2fb6fe991 Mon Sep 17 00:00:00 2001 From: Jayesh Choudhary Date: Tue, 18 Mar 2025 16:17:15 +0530 Subject: [PATCH 611/651] ASoC: ti: j721e-evm: Reduce log level for EPROBE_DEFER Drop the log level for deferral probe to avoid flooding in kernel logs. Signed-off-by: Jayesh Choudhary Link: https://patch.msgid.link/20250318104715.43267-1-j-choudhary@ti.com Signed-off-by: Mark Brown --- sound/soc/ti/j721e-evm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c index c0fa72e626ff..2057d46ad884 100644 --- a/sound/soc/ti/j721e-evm.c +++ b/sound/soc/ti/j721e-evm.c @@ -913,8 +913,9 @@ static int j721e_soc_probe(struct platform_device *pdev) mutex_init(&priv->mutex); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) - dev_err(&pdev->dev, "devm_snd_soc_register_card() failed: %d\n", - ret); + dev_err_probe(&pdev->dev, ret, + "devm_snd_soc_register_card() failed: %d\n", + ret); return ret; } From 1822c4484efeb8056de53bf4edfca377d2939418 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Tue, 18 Mar 2025 16:10:43 +0800 Subject: [PATCH 612/651] ASoC: codecs: ntp8918: Remove duplicate clk.h header Remove duplicate header which is included twice. Signed-off-by: Chen Ni Link: https://patch.msgid.link/20250318081043.2870229-1-nichen@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/codecs/ntp8918.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ntp8918.c b/sound/soc/codecs/ntp8918.c index a332893fc51d..5593d48ef696 100644 --- a/sound/soc/codecs/ntp8918.c +++ b/sound/soc/codecs/ntp8918.c @@ -8,7 +8,6 @@ */ #include -#include #include #include #include From 45ff65e30deb919604e68faed156ad96ce7474d9 Mon Sep 17 00:00:00 2001 From: Jayesh Choudhary Date: Tue, 18 Mar 2025 17:05:24 +0530 Subject: [PATCH 613/651] ASoC: ti: j721e-evm: Fix clock configuration for ti,j7200-cpb-audio compatible For 'ti,j7200-cpb-audio' compatible, there is support for only one PLL for 48k. For 11025, 22050, 44100 and 88200 sampling rates, due to absence of J721E_CLK_PARENT_44100, we get EINVAL while running any audio application. Add support for these rates by using the 48k parent clock and adjusting the clock for these rates later in j721e_configure_refclk. Fixes: 6748d0559059 ("ASoC: ti: Add custom machine driver for j721e EVM (CPB and IVI)") Signed-off-by: Jayesh Choudhary Link: https://patch.msgid.link/20250318113524.57100-1-j-choudhary@ti.com Signed-off-by: Mark Brown --- sound/soc/ti/j721e-evm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c index d9d1e021f5b2..0f96cc45578d 100644 --- a/sound/soc/ti/j721e-evm.c +++ b/sound/soc/ti/j721e-evm.c @@ -182,6 +182,8 @@ static int j721e_configure_refclk(struct j721e_priv *priv, clk_id = J721E_CLK_PARENT_48000; else if (!(rate % 11025) && priv->pll_rates[J721E_CLK_PARENT_44100]) clk_id = J721E_CLK_PARENT_44100; + else if (!(rate % 11025) && priv->pll_rates[J721E_CLK_PARENT_48000]) + clk_id = J721E_CLK_PARENT_48000; else return ret; From 38e94cefbf45c1edc5b751ab90a3088f7c6fac1a Mon Sep 17 00:00:00 2001 From: Olivia Mackintosh Date: Sun, 16 Mar 2025 15:33:23 +0000 Subject: [PATCH 614/651] ALSA: usb-audio: separate DJM-A9 cap lvl options Mixer quicks for the Pioneer DJM-A9 mixer was added in 5289d00 with additional capture level values added to the common DJM array of values. This breaks the existing DJM mixers however as alsa-utils relies on enumeration of the actual mixer options based on the value array which results in error when storing state. This commit just separates the A9 values into a separate array and references them in the corresponding mixer control. Fixes: 5289d0069639 ("ALSA: usb-audio: Add Pioneer DJ/AlphaTheta DJM-A9 Mixer") Signed-off-by: Olivia Mackintosh Link: https://patch.msgid.link/20250316153323.16381-1-livvy@base.nu Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ed6127b0389f..d4745b98a93e 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -3688,8 +3688,7 @@ static const char *snd_djm_get_label(u8 device_idx, u16 wvalue, u16 windex) // common DJM capture level option values static const u16 snd_djm_opts_cap_level[] = { - 0x0000, 0x0100, 0x0200, 0x0300, 0x400, 0x500 }; - + 0x0000, 0x0100, 0x0200, 0x0300 }; // DJM-250MK2 static const u16 snd_djm_opts_250mk2_cap1[] = { @@ -3831,6 +3830,8 @@ static const struct snd_djm_ctl snd_djm_ctls_750mk2[] = { // DJM-A9 +static const u16 snd_djm_opts_a9_cap_level[] = { + 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500 }; static const u16 snd_djm_opts_a9_cap1[] = { 0x0107, 0x0108, 0x0109, 0x010a, 0x010e, 0x111, 0x112, 0x113, 0x114, 0x0131, 0x132, 0x133, 0x134 }; @@ -3844,7 +3845,7 @@ static const u16 snd_djm_opts_a9_cap5[] = { 0x0501, 0x0502, 0x0503, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509, 0x050a, 0x050e }; static const struct snd_djm_ctl snd_djm_ctls_a9[] = { - SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), + SND_DJM_CTL("Capture Level", a9_cap_level, 0, SND_DJM_WINDEX_CAPLVL), SND_DJM_CTL("Master Input", a9_cap1, 3, SND_DJM_WINDEX_CAP), SND_DJM_CTL("Ch1 Input", a9_cap2, 2, SND_DJM_WINDEX_CAP), SND_DJM_CTL("Ch2 Input", a9_cap3, 2, SND_DJM_WINDEX_CAP), From 35ef1c79d2e09e9e5a66e28a66fe0df4368b0f3d Mon Sep 17 00:00:00 2001 From: Dhruv Deshpande Date: Mon, 17 Mar 2025 08:56:53 +0000 Subject: [PATCH 615/651] ALSA: hda/realtek: Support mute LED on HP Laptop 15s-du3xxx The mute LED on this HP laptop uses ALC236 and requires a quirk to function. This patch enables the existing quirk for the device. Tested on my laptop and the LED behaviour works as intended. Cc: stable@vger.kernel.org Signed-off-by: Dhruv Deshpande Link: https://patch.msgid.link/20250317085621.45056-1-dhrv.d@proton.me Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 23e5de9499a1..ccc3b864d133 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10521,6 +10521,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8811, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), SND_PCI_QUIRK(0x103c, 0x8812, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), SND_PCI_QUIRK(0x103c, 0x881d, "HP 250 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x881e, "HP Laptop 15s-du3xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8847, "HP EliteBook x360 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), From 84d6a465f211d6e61ab09a6642febf1a7013b6bf Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 13 Mar 2025 17:32:38 +0800 Subject: [PATCH 616/651] ASoC: tas2781: Support dsp firmware Alpha and Beta seaies For calibration, basic version does not contain any calibration addresses, it depends on calibration tool to convey the addresses to the driver. Since Alpha and Beta firmware, all the calibration addresses are saved into the firmware. Signed-off-by: Shenghao Ding Reviewed-by: Mark Brown Reviewed-by: Andy Shevchenko Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250313093238.1184-1-shenghao-ding@ti.com --- include/sound/tas2781-dsp.h | 30 ++++- include/sound/tas2781.h | 11 ++ sound/pci/hda/tas2781_spi_fwlib.c | 8 +- sound/soc/codecs/tas2781-fmwlib.c | 190 ++++++++++++++++++++++---- sound/soc/codecs/tas2781-i2c.c | 215 ++++++++++++++++++++++-------- 5 files changed, 368 insertions(+), 86 deletions(-) diff --git a/include/sound/tas2781-dsp.h b/include/sound/tas2781-dsp.h index 3cda9da14f6d..c3a9efa73d5d 100644 --- a/include/sound/tas2781-dsp.h +++ b/include/sound/tas2781-dsp.h @@ -2,7 +2,7 @@ // // ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier // -// Copyright (C) 2022 - 2024 Texas Instruments Incorporated +// Copyright (C) 2022 - 2025 Texas Instruments Incorporated // https://www.ti.com // // The TAS2781 driver implements a flexible and configurable @@ -30,8 +30,10 @@ #define PRE_DEVICE_C 0x12 #define PRE_DEVICE_D 0x16 -#define PPC3_VERSION 0x4100 -#define PPC3_VERSION_TAS2781 0x14600 +#define PPC3_VERSION_BASE 0x4100 +#define PPC3_VERSION_TAS2781_BASIC_MIN 0x14600 +#define PPC3_VERSION_TAS2781_ALPHA_MIN 0x4a00 +#define PPC3_VERSION_TAS2781_BETA_MIN 0x19400 #define TASDEVICE_DEVICE_SUM 8 #define TASDEVICE_CONFIG_SUM 64 @@ -106,6 +108,27 @@ struct tasdevice_calibration { struct tasdevice_data dev_data; }; +struct fct_param_address { + /* Thermal data for PG 1.0 device */ + unsigned char thr[3]; + /* Thermal data for PG 2.0 device */ + unsigned char thr2[3]; + /* Pilot tone enable flag, usually the sine wave */ + unsigned char plt_flg[3]; + /* Pilot tone gain for calibration */ + unsigned char sin_gn[3]; + /* Pilot tone gain for calibration */ + unsigned char sin_gn2[3]; + /* high 32-bit of real-time spk impedance */ + unsigned char r0_reg[3]; + /* check spk connection */ + unsigned char tf_reg[3]; + /* check spk resonant frequency */ + unsigned char a1_reg[3]; + /* check spk resonant frequency */ + unsigned char a2_reg[3]; +}; + struct tasdevice_fw { struct tasdevice_dspfw_hdr fw_hdr; unsigned short nr_programs; @@ -114,6 +137,7 @@ struct tasdevice_fw { struct tasdevice_config *configs; unsigned short nr_calibrations; struct tasdevice_calibration *calibrations; + struct fct_param_address fct_par_addr; struct device *dev; }; diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 72d2060904f6..e38fa735a18d 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -112,6 +112,12 @@ enum audio_device { TAS2781, }; +enum dspbin_type { + TASDEV_BASIC, + TASDEV_ALPHA, + TASDEV_BETA, +}; + enum device_catlog_id { LENOVO = 0, OTHERS @@ -126,6 +132,7 @@ struct bulk_reg_val { struct tasdevice { struct bulk_reg_val *cali_data_backup; + struct bulk_reg_val alp_cali_bckp; struct tasdevice_fw *cali_data_fmw; unsigned int dev_addr; unsigned int err_code; @@ -171,6 +178,7 @@ struct tasdevice_priv { unsigned char dev_name[32]; const char *name_prefix; unsigned char ndev; + unsigned int dspbin_typ; unsigned int magic_num; unsigned int chip_id; unsigned int sysclk; @@ -196,6 +204,9 @@ struct tasdevice_priv { int (*fw_parse_configuration_data)(struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset); + int (*fw_parse_fct_param_address)(struct tasdevice_priv *tas_priv, + struct tasdevice_fw *tas_fmw, + const struct firmware *fmw, int offset); int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv, struct tasdev_blk *block); diff --git a/sound/pci/hda/tas2781_spi_fwlib.c b/sound/pci/hda/tas2781_spi_fwlib.c index 131d9a77d140..d90d022d8449 100644 --- a/sound/pci/hda/tas2781_spi_fwlib.c +++ b/sound/pci/hda/tas2781_spi_fwlib.c @@ -2,7 +2,7 @@ // // TAS2781 HDA SPI driver // -// Copyright 2024-2025 Texas Instruments, Inc. +// Copyright 2024 - 2025 Texas Instruments, Inc. // // Author: Baojun Xu @@ -370,10 +370,10 @@ static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw, int i, n = ARRAY_SIZE(non_ppc3_mapping_table); unsigned char dev_idx = 0; - if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781) { + if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN) { p = (struct blktyp_devidx_map *)ppc3_tas2781_mapping_table; n = ARRAY_SIZE(ppc3_tas2781_mapping_table); - } else if (fw_fixed_hdr->ppcver >= PPC3_VERSION) { + } else if (fw_fixed_hdr->ppcver >= PPC3_VERSION_BASE) { p = (struct blktyp_devidx_map *)ppc3_mapping_table; n = ARRAY_SIZE(ppc3_mapping_table); } @@ -1605,7 +1605,7 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv, int rc = 0; if (drv_ver == 0x100) { - if (ppcver >= PPC3_VERSION) { + if (ppcver >= PPC3_VERSION_BASE) { tas_priv->fw_parse_variable_header = fw_parse_variable_header_kernel; tas_priv->fw_parse_program_data = diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 61d9c220b6a4..bed0198f1139 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -389,10 +389,10 @@ static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw, int i, n = ARRAY_SIZE(non_ppc3_mapping_table); unsigned char dev_idx = 0; - if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781) { + if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN) { p = (struct blktyp_devidx_map *)ppc3_tas2781_mapping_table; n = ARRAY_SIZE(ppc3_tas2781_mapping_table); - } else if (fw_fixed_hdr->ppcver >= PPC3_VERSION) { + } else if (fw_fixed_hdr->ppcver >= PPC3_VERSION_BASE) { p = (struct blktyp_devidx_map *)ppc3_mapping_table; n = ARRAY_SIZE(ppc3_mapping_table); } @@ -559,6 +559,124 @@ out: return offset; } +static void fct_param_address_parser(struct cali_reg *r, + struct tasdevice_fw *tas_fmw, const unsigned char *data) +{ + struct fct_param_address *p = &tas_fmw->fct_par_addr; + unsigned int i; + + /* + * Calibration parameters locations and data schema in dsp firmware. + * The number of items are flexible, but not more than 20. The dsp tool + * will reseve 20*24-byte space for fct params. In some cases, the + * number of fct param is less than 20, the data will be saved from the + * beginning, the rest part will be stuffed with zero. + * + * fct_param_num (not more than 20) + * for (i = 0; i < fct_param_num; i++) { + * Alias of fct param (20 bytes) + * Book (1 byte) + * Page (1 byte) + * Offset (1 byte) + * CoeffLength (1 byte) = 0x1 + * } + * if (20 - fct_param_num) + * 24*(20 - fct_param_num) pieces of '0' as stuffing + * + * As follow: + * umg_SsmKEGCye = Book, Page, Offset, CoeffLength + * iks_E0 = Book, Page, Offset, CoeffLength + * yep_LsqM0 = Book, Page, Offset, CoeffLength + * oyz_U0_ujx = Book, Page, Offset, CoeffLength + * iks_GC_GMgq = Book, Page, Offset, CoeffLength + * gou_Yao = Book, Page, Offset, CoeffLength + * kgd_Wsc_Qsbp = Book, Page, Offset, CoeffLength + * yec_CqseSsqs = Book, Page, Offset, CoeffLength + * iks_SogkGgog2 = Book, Page, Offset, CoeffLength + * yec_Sae_Y = Book, Page, Offset, CoeffLength + * Re_Int = Book, Page, Offset, CoeffLength + * SigFlag = Book, Page, Offset, CoeffLength + * a1_Int = Book, Page, Offset, CoeffLength + * a2_Int = Book, Page, Offset, CoeffLength + */ + for (i = 0; i < 20; i++) { + const unsigned char *dat = &data[24 * i]; + + /* + * check whether current fct param is empty. + */ + if (dat[23] != 1) + break; + + if (!strncmp(dat, "umg_SsmKEGCye", 20)) + r->pow_reg = TASDEVICE_REG(dat[20], dat[21], dat[22]); + /* high 32-bit of real-time spk impedance */ + else if (!strncmp(dat, "iks_E0", 20)) + r->r0_reg = TASDEVICE_REG(dat[20], dat[21], dat[22]); + /* inverse of real-time spk impedance */ + else if (!strncmp(dat, "yep_LsqM0", 20)) + r->invr0_reg = + TASDEVICE_REG(dat[20], dat[21], dat[22]); + /* low 32-bit of real-time spk impedance */ + else if (!strncmp(dat, "oyz_U0_ujx", 20)) + r->r0_low_reg = + TASDEVICE_REG(dat[20], dat[21], dat[22]); + /* Delta Thermal Limit */ + else if (!strncmp(dat, "iks_GC_GMgq", 20)) + r->tlimit_reg = + TASDEVICE_REG(dat[20], dat[21], dat[22]); + /* Thermal data for PG 1.0 device */ + else if (!strncmp(dat, "gou_Yao", 20)) + memcpy(p->thr, &dat[20], 3); + /* Pilot tone enable flag, usually the sine wave */ + else if (!strncmp(dat, "kgd_Wsc_Qsbp", 20)) + memcpy(p->plt_flg, &dat[20], 3); + /* Pilot tone gain for calibration */ + else if (!strncmp(dat, "yec_CqseSsqs", 20)) + memcpy(p->sin_gn, &dat[20], 3); + /* Pilot tone gain for calibration, useless in PG 2.0 */ + else if (!strncmp(dat, "iks_SogkGgog2", 20)) + memcpy(p->sin_gn2, &dat[20], 3); + /* Thermal data for PG 2.0 device */ + else if (!strncmp(dat, "yec_Sae_Y", 20)) + memcpy(p->thr2, &dat[20], 3); + /* Spk Equivalent Resistance in fixed-point format */ + else if (!strncmp(dat, "Re_Int", 20)) + memcpy(p->r0_reg, &dat[20], 3); + /* Check whether the spk connection is open */ + else if (!strncmp(dat, "SigFlag", 20)) + memcpy(p->tf_reg, &dat[20], 3); + /* check spk resonant frequency */ + else if (!strncmp(dat, "a1_Int", 20)) + memcpy(p->a1_reg, &dat[20], 3); + /* check spk resonant frequency */ + else if (!strncmp(dat, "a2_Int", 20)) + memcpy(p->a2_reg, &dat[20], 3); + } +} + +static int fw_parse_fct_param_address(struct tasdevice_priv *tas_priv, + struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset) +{ + struct calidata *cali_data = &tas_priv->cali_data; + struct cali_reg *r = &cali_data->cali_reg_array; + const unsigned char *data = fmw->data; + + if (offset + 520 > fmw->size) { + dev_err(tas_priv->dev, "%s: File Size error\n", __func__); + return -EINVAL; + } + + /* skip reserved part */ + offset += 40; + + fct_param_address_parser(r, tas_fmw, &data[offset]); + + offset += 480; + + return offset; +} + static int fw_parse_variable_header_kernel( struct tasdevice_priv *tas_priv, const struct firmware *fmw, int offset) @@ -1686,13 +1804,29 @@ static int tasdevice_load_block(struct tasdevice_priv *tas_priv, return rc; } +static void dspbin_type_check(struct tasdevice_priv *tas_priv, + unsigned int ppcver) +{ + if (ppcver >= PPC3_VERSION_TAS2781_ALPHA_MIN) { + if (ppcver >= PPC3_VERSION_TAS2781_BETA_MIN) + tas_priv->dspbin_typ = TASDEV_BETA; + else if (ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN) + tas_priv->dspbin_typ = TASDEV_BASIC; + else + tas_priv->dspbin_typ = TASDEV_ALPHA; + } + if (tas_priv->dspbin_typ != TASDEV_BASIC) + tas_priv->fw_parse_fct_param_address = + fw_parse_fct_param_address; +} + static int dspfw_default_callback(struct tasdevice_priv *tas_priv, unsigned int drv_ver, unsigned int ppcver) { int rc = 0; if (drv_ver == 0x100) { - if (ppcver >= PPC3_VERSION) { + if (ppcver >= PPC3_VERSION_BASE) { tas_priv->fw_parse_variable_header = fw_parse_variable_header_kernel; tas_priv->fw_parse_program_data = @@ -1701,6 +1835,7 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv, fw_parse_configuration_data_kernel; tas_priv->tasdevice_load_block = tasdevice_load_block_kernel; + dspbin_type_check(tas_priv, ppcver); } else { switch (ppcver) { case 0x00: @@ -1716,7 +1851,7 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv, default: dev_err(tas_priv->dev, "%s: PPCVer must be 0x0 or 0x%02x", - __func__, PPC3_VERSION); + __func__, PPC3_VERSION_BASE); dev_err(tas_priv->dev, " Current:0x%02x\n", ppcver); rc = -EINVAL; @@ -1952,28 +2087,25 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw, struct tasdevice_fw_fixed_hdr *fw_fixed_hdr; struct tasdevice_fw *tas_fmw; int offset = 0; - int ret = 0; + int ret; if (!fmw || !fmw->data) { dev_err(tas_priv->dev, "%s: Failed to read firmware %s\n", __func__, tas_priv->coef_binaryname); - ret = -EINVAL; - goto out; + return -EINVAL; } tas_priv->fmw = kzalloc(sizeof(struct tasdevice_fw), GFP_KERNEL); - if (!tas_priv->fmw) { - ret = -ENOMEM; - goto out; - } + if (!tas_priv->fmw) + return -ENOMEM; + tas_fmw = tas_priv->fmw; tas_fmw->dev = tas_priv->dev; offset = fw_parse_header(tas_priv, tas_fmw, fmw, offset); - if (offset == -EINVAL) { - ret = -EINVAL; - goto out; - } + if (offset == -EINVAL) + return -EINVAL; + fw_fixed_hdr = &(tas_fmw->fw_hdr.fixed_hdr); /* Support different versions of firmware */ switch (fw_fixed_hdr->drv_ver) { @@ -2006,28 +2138,32 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw, ret = dspfw_default_callback(tas_priv, fw_fixed_hdr->drv_ver, fw_fixed_hdr->ppcver); if (ret) - goto out; + return ret; break; } offset = tas_priv->fw_parse_variable_header(tas_priv, fmw, offset); - if (offset < 0) { - ret = offset; - goto out; - } + if (offset < 0) + return offset; + offset = tas_priv->fw_parse_program_data(tas_priv, tas_fmw, fmw, offset); - if (offset < 0) { - ret = offset; - goto out; - } + if (offset < 0) + return offset; + offset = tas_priv->fw_parse_configuration_data(tas_priv, tas_fmw, fmw, offset); if (offset < 0) - ret = offset; + return offset; -out: - return ret; + if (tas_priv->fw_parse_fct_param_address) { + offset = tas_priv->fw_parse_fct_param_address(tas_priv, + tas_fmw, fmw, offset); + if (offset < 0) + return offset; + } + + return 0; } int tasdevice_dsp_parser(void *context) diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index 90c5b2e74d12..b950914b7d48 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -349,13 +349,31 @@ static int calib_data_get(struct tasdevice_priv *tas_priv, int reg, return rc; } +static int partial_cali_data_update(int *reg, int j) +{ + switch (tas2781_cali_start_reg[j].reg) { + case 0: + return reg[0]; + case TAS2781_PRM_PLT_FLAG_REG: + return reg[1]; + case TAS2781_PRM_SINEGAIN_REG: + return reg[2]; + case TAS2781_PRM_SINEGAIN2_REG: + return reg[3]; + default: + return 0; + } +} + static void sngl_calib_start(struct tasdevice_priv *tas_priv, int i, int *reg, unsigned char *dat) { struct tasdevice *tasdev = tas_priv->tasdevice; struct bulk_reg_val *p = tasdev[i].cali_data_backup; + struct bulk_reg_val *t = &tasdev[i].alp_cali_bckp; const int sum = ARRAY_SIZE(tas2781_cali_start_reg); - int j; + unsigned char val[4]; + int j, r; if (p == NULL) return; @@ -370,30 +388,23 @@ static void sngl_calib_start(struct tasdevice_priv *tas_priv, int i, tasdevice_dev_read(tas_priv, i, p[j].reg, (int *)&p[j].val[0]); } else { - switch (tas2781_cali_start_reg[j].reg) { - case 0: { - if (!reg[0]) - continue; - p[j].reg = reg[0]; + if (!tas_priv->dspbin_typ) { + r = partial_cali_data_update(reg, j); + if (r) + p[j].reg = r; } - break; - case TAS2781_PRM_PLT_FLAG_REG: - p[j].reg = reg[1]; - break; - case TAS2781_PRM_SINEGAIN_REG: - p[j].reg = reg[2]; - break; - case TAS2781_PRM_SINEGAIN2_REG: - p[j].reg = reg[3]; - break; - } - tasdevice_dev_bulk_read(tas_priv, i, p[j].reg, - p[j].val, 4); + + if (p[j].reg) + tasdevice_dev_bulk_read(tas_priv, i, p[j].reg, + p[j].val, 4); } } + if (tas_priv->dspbin_typ == TASDEV_ALPHA) + tasdevice_dev_bulk_read(tas_priv, i, t->reg, t->val, 4); + /* Update the setting for calibration */ - for (j = 0; j < sum - 2; j++) { + for (j = 0; j < sum - 4; j++) { if (p[j].val_len == 1) { if (p[j].is_locked) tasdevice_dev_write(tas_priv, i, @@ -401,17 +412,33 @@ static void sngl_calib_start(struct tasdevice_priv *tas_priv, int i, TAS2781_TEST_PAGE_UNLOCK); tasdevice_dev_write(tas_priv, i, p[j].reg, tas2781_cali_start_reg[j].val[0]); - } else { - if (!p[j].reg) - continue; - tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, - (unsigned char *) - tas2781_cali_start_reg[j].val, 4); } } - tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, &dat[1], 4); - tasdevice_dev_bulk_write(tas_priv, i, p[j + 1].reg, &dat[5], 4); + if (tas_priv->dspbin_typ == TASDEV_ALPHA) { + val[0] = 0x00; + val[1] = 0x00; + val[2] = 0x21; + val[3] = 0x8e; + } else { + val[0] = tas2781_cali_start_reg[j].val[0]; + val[1] = tas2781_cali_start_reg[j].val[1]; + val[2] = tas2781_cali_start_reg[j].val[2]; + val[3] = tas2781_cali_start_reg[j].val[3]; + } + tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, val, 4); + tasdevice_dev_bulk_write(tas_priv, i, p[j + 1].reg, + (unsigned char *)tas2781_cali_start_reg[j + 1].val, 4); + tasdevice_dev_bulk_write(tas_priv, i, p[j + 2].reg, &dat[1], 4); + tasdevice_dev_bulk_write(tas_priv, i, p[j + 3].reg, &dat[5], 4); + if (tas_priv->dspbin_typ == TASDEV_ALPHA) { + val[0] = 0x00; + val[1] = 0x00; + val[2] = 0x2a; + val[3] = 0x0b; + + tasdevice_dev_bulk_read(tas_priv, i, t->reg, val, 4); + } } static int tas2781_calib_start_put(struct snd_kcontrol *kcontrol, @@ -452,14 +479,15 @@ static int tas2781_calib_start_put(struct snd_kcontrol *kcontrol, return 1; } -static void tas2781_calib_stop_put(struct tasdevice_priv *tas_priv) +static void tas2781_calib_stop_put(struct tasdevice_priv *priv) { const int sum = ARRAY_SIZE(tas2781_cali_start_reg); int i, j; - for (i = 0; i < tas_priv->ndev; i++) { - struct tasdevice *tasdev = tas_priv->tasdevice; + for (i = 0; i < priv->ndev; i++) { + struct tasdevice *tasdev = priv->tasdevice; struct bulk_reg_val *p = tasdev[i].cali_data_backup; + struct bulk_reg_val *t = &tasdev[i].alp_cali_bckp; if (p == NULL) continue; @@ -467,18 +495,21 @@ static void tas2781_calib_stop_put(struct tasdevice_priv *tas_priv) for (j = 0; j < sum; j++) { if (p[j].val_len == 1) { if (p[j].is_locked) - tasdevice_dev_write(tas_priv, i, + tasdevice_dev_write(priv, i, TAS2781_TEST_UNLOCK_REG, TAS2781_TEST_PAGE_UNLOCK); - tasdevice_dev_write(tas_priv, i, p[j].reg, + tasdevice_dev_write(priv, i, p[j].reg, p[j].val[0]); } else { if (!p[j].reg) continue; - tasdevice_dev_bulk_write(tas_priv, i, p[j].reg, + tasdevice_dev_bulk_write(priv, i, p[j].reg, p[j].val, 4); } } + + if (priv->dspbin_typ == TASDEV_ALPHA) + tasdevice_dev_bulk_write(priv, i, t->reg, t->val, 4); } } @@ -590,16 +621,20 @@ static int tasdev_cali_data_put(struct snd_kcontrol *kcontrol, i += 2; priv->is_user_space_calidata = true; - p->r0_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); - i += 3; - p->r0_low_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); - i += 3; - p->invr0_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); - i += 3; - p->pow_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); - i += 3; - p->tlimit_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); - i += 3; + if (priv->dspbin_typ == TASDEV_BASIC) { + p->r0_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->r0_low_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->invr0_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->pow_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + p->tlimit_reg = TASDEVICE_REG(src[i], src[i + 1], src[i + 2]); + i += 3; + } else { + i += 15; + } memcpy(dst, &src[i], cali_data->total_sz); return 1; @@ -646,12 +681,19 @@ static int tasdev_tf_data_get(struct snd_kcontrol *kcontrol, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *) kcontrol->private_value; unsigned char *dst = ucontrol->value.bytes.data; - unsigned int reg; + unsigned int reg = TAS2781_RUNTIME_RE_REG_TF; + + if (tas_priv->chip_id == TAS2781) { + struct tasdevice_fw *tas_fmw = tas_priv->fmw; + struct fct_param_address *p = &(tas_fmw->fct_par_addr); - if (tas_priv->chip_id == TAS2781) reg = TAS2781_RUNTIME_RE_REG_TF; - else + if (tas_priv->dspbin_typ) + reg = TASDEVICE_REG(p->tf_reg[0], p->tf_reg[1], + p->tf_reg[2]); + } else { reg = TAS2563_RUNTIME_RE_REG_TF; + } guard(mutex)(&tas_priv->codec_lock); dst[0] = bytes_ext->max; @@ -666,12 +708,19 @@ static int tasdev_re_data_get(struct snd_kcontrol *kcontrol, struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *) kcontrol->private_value; unsigned char *dst = ucontrol->value.bytes.data; - unsigned int reg; + unsigned int reg = TAS2781_RUNTIME_RE_REG; - if (tas_priv->chip_id == TAS2781) - reg = TAS2781_RUNTIME_RE_REG; - else + if (tas_priv->chip_id == TAS2781) { + struct tasdevice_fw *tas_fmw = tas_priv->fmw; + struct fct_param_address *p = &(tas_fmw->fct_par_addr); + + if (tas_priv->dspbin_typ) + reg = TASDEVICE_REG(p->r0_reg[0], p->r0_reg[1], + p->r0_reg[2]); + } else { reg = TAS2563_RUNTIME_RE_REG; + } + guard(mutex)(&tas_priv->codec_lock); dst[0] = bytes_ext->max; return calib_data_get(tas_priv, reg, &dst[1]); @@ -705,11 +754,16 @@ static int tasdev_XMA1_data_get(struct snd_kcontrol *kcontrol, { struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct tasdevice_fw *tas_fmw = tas_priv->fmw; + struct fct_param_address *p = &(tas_fmw->fct_par_addr); struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *) kcontrol->private_value; unsigned char *dst = ucontrol->value.bytes.data; unsigned int reg = TASDEVICE_XM_A1_REG; + if (tas_priv->dspbin_typ) + reg = TASDEVICE_REG(p->a1_reg[0], p->a1_reg[1], p->a1_reg[2]); + guard(mutex)(&tas_priv->codec_lock); dst[0] = bytes_ext->max; return calib_data_get(tas_priv, reg, &dst[1]); @@ -720,11 +774,16 @@ static int tasdev_XMA2_data_get(struct snd_kcontrol *kcontrol, { struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(comp); + struct tasdevice_fw *tas_fmw = tas_priv->fmw; + struct fct_param_address *p = &(tas_fmw->fct_par_addr); struct soc_bytes_ext *bytes_ext = (struct soc_bytes_ext *) kcontrol->private_value; unsigned char *dst = ucontrol->value.bytes.data; unsigned int reg = TASDEVICE_XM_A2_REG; + if (tas_priv->dspbin_typ) + reg = TASDEVICE_REG(p->a2_reg[0], p->a2_reg[1], p->a2_reg[2]); + guard(mutex)(&tas_priv->codec_lock); dst[0] = bytes_ext->max; return calib_data_get(tas_priv, reg, &dst[1]); @@ -1172,10 +1231,51 @@ static int tasdevice_dsp_create_ctrls(struct tasdevice_priv *tas_priv) nr_controls < mix_index ? nr_controls : mix_index); } +static void cali_reg_update(struct bulk_reg_val *p, + struct fct_param_address *t) +{ + const int sum = ARRAY_SIZE(tas2781_cali_start_reg); + int reg, j; + + for (j = 0; j < sum; j++) { + switch (tas2781_cali_start_reg[j].reg) { + case 0: + reg = TASDEVICE_REG(t->thr[0], t->thr[1], t->thr[2]); + break; + case TAS2781_PRM_PLT_FLAG_REG: + reg = TASDEVICE_REG(t->plt_flg[0], t->plt_flg[1], + t->plt_flg[2]); + break; + case TAS2781_PRM_SINEGAIN_REG: + reg = TASDEVICE_REG(t->sin_gn[0], t->sin_gn[1], + t->sin_gn[2]); + break; + case TAS2781_PRM_SINEGAIN2_REG: + reg = TASDEVICE_REG(t->sin_gn[0], t->sin_gn[1], + t->sin_gn[2]); + break; + default: + reg = 0; + break; + } + if (reg) + p[j].reg = reg; + } +} + +static void alpa_cali_update(struct bulk_reg_val *p, + struct fct_param_address *t) +{ + p->is_locked = false; + p->reg = TASDEVICE_REG(t->thr2[0], t->thr2[1], t->thr2[2]); + p->val_len = 4; +} + static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv) { struct calidata *cali_data = &priv->cali_data; struct tasdevice *tasdev = priv->tasdevice; + struct tasdevice_fw *fmw = priv->fmw; struct soc_bytes_ext *ext_cali_data; struct snd_kcontrol_new *cali_ctrls; unsigned int nctrls; @@ -1191,14 +1291,25 @@ static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv) } if (priv->chip_id == TAS2781) { + struct fct_param_address *t = &(fmw->fct_par_addr); + cali_ctrls = (struct snd_kcontrol_new *)tas2781_cali_controls; nctrls = ARRAY_SIZE(tas2781_cali_controls); for (i = 0; i < priv->ndev; i++) { - tasdev[i].cali_data_backup = + struct bulk_reg_val *p; + + p = tasdev[i].cali_data_backup = kmemdup(tas2781_cali_start_reg, sizeof(tas2781_cali_start_reg), GFP_KERNEL); if (!tasdev[i].cali_data_backup) return -ENOMEM; + if (priv->dspbin_typ) { + cali_reg_update(p, t); + if (priv->dspbin_typ == TASDEV_ALPHA) { + p = &tasdev[i].alp_cali_bckp; + alpa_cali_update(p, t); + } + } } } else { cali_ctrls = (struct snd_kcontrol_new *)tas2563_cali_controls; From 765fee28fe0e7d6a5ff8f2eeb7990b7d3ad20825 Mon Sep 17 00:00:00 2001 From: Andres Urian Florez Date: Tue, 18 Mar 2025 21:05:10 -0500 Subject: [PATCH 617/651] ALSA: echoaudio: remove unused variable This patch cleans up the code in the __snd_echo_probe function of the echoaudio.c driver by removing the unused variable i and moving the declaration of the loop variable i inside the foor loops where it is used Signed-off-by: Andres Urian Florez Link: https://patch.msgid.link/20250319020515.22150-1-andres.emb.sys@gmail.com Signed-off-by: Takashi Iwai --- sound/pci/echoaudio/echoaudio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 7484de255a3e..4effcc0090ac 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -1966,7 +1966,6 @@ static int __snd_echo_probe(struct pci_dev *pci, struct snd_card *card; struct echoaudio *chip; char *dsp; - __maybe_unused int i; int err; if (dev >= SNDRV_CARDS) @@ -1976,7 +1975,6 @@ static int __snd_echo_probe(struct pci_dev *pci, return -ENOENT; } - i = 0; err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, sizeof(*chip), &card); if (err < 0) @@ -2080,7 +2078,7 @@ static int __snd_echo_probe(struct pci_dev *pci, #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH /* Creates a list of available digital modes */ chip->num_digital_modes = 0; - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) if (chip->digital_modes & (1 << i)) chip->digital_mode_list[chip->num_digital_modes++] = i; @@ -2092,7 +2090,7 @@ static int __snd_echo_probe(struct pci_dev *pci, #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK /* Creates a list of available clock sources */ chip->num_clock_sources = 0; - for (i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) if (chip->input_clock_types & (1 << i)) chip->clock_source_list[chip->num_clock_sources++] = i; From 7a24b876ad8cdd56457e881d384a038922b508c3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:45 +0000 Subject: [PATCH 618/651] ASoC: ops-test: Add some basic kunit tests for soc-ops Add some basic kunit tests for some of the ASoC control put and get helpers. This will assist in doing some refactoring. Note that presently some tests fail, but the rest of the series will fix these up. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/Kconfig | 7 + sound/soc/Makefile | 4 + sound/soc/soc-ops-test.c | 541 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 552 insertions(+) create mode 100644 sound/soc/soc-ops-test.c diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 5efba76abb31..8b7d51266f81 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -81,6 +81,13 @@ config SND_SOC_UTILS_KUNIT_TEST help If you want to perform tests on ALSA SoC utils library say Y here. +config SND_SOC_OPS_KUNIT_TEST + tristate "KUnit tests for SoC ops" + depends on KUNIT + default KUNIT_ALL_TESTS + help + If you want to perform tests on ALSA SoC ops library say Y here. + config SND_SOC_ACPI tristate diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 08baaa11d813..358e227c5ab6 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -21,6 +21,10 @@ ifneq ($(CONFIG_SND_SOC_UTILS_KUNIT_TEST),) obj-$(CONFIG_SND_SOC_UTILS_KUNIT_TEST) += soc-utils-test.o endif +ifneq ($(CONFIG_SND_SOC_OPS_KUNIT_TEST),) +obj-$(CONFIG_SND_SOC_OPS_KUNIT_TEST) += soc-ops-test.o +endif + ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) snd-soc-core-y += soc-generic-dmaengine-pcm.o endif diff --git a/sound/soc/soc-ops-test.c b/sound/soc/soc-ops-test.c new file mode 100644 index 000000000000..dc1e482bba6a --- /dev/null +++ b/sound/soc/soc-ops-test.c @@ -0,0 +1,541 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2025 Cirrus Logic, Inc. and +// Cirrus Logic International Semiconductor Ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum soc_ops_test_control_layout { + SOC_OPS_TEST_SINGLE, + SOC_OPS_TEST_DOUBLE, + SOC_OPS_TEST_DOUBLE_R, +}; + +#define TEST_MC(clayout, xmin, xmax, xpmax, xsign, xinvert) \ + .mc = { \ + .min = xmin, .max = xmax, .platform_max = xpmax, \ + .reg = 0, .shift = 0, .sign_bit = xsign, .invert = xinvert, \ + .rreg = SOC_OPS_TEST_##clayout == SOC_OPS_TEST_DOUBLE_R ? 1 : 0, \ + .rshift = SOC_OPS_TEST_##clayout == SOC_OPS_TEST_DOUBLE ? 16 : 0, \ + } + +#define TEST_UINFO(clayout, ctype, cmin, cmax) \ + .uinfo = { \ + .type = SNDRV_CTL_ELEM_TYPE_##ctype, \ + .count = SOC_OPS_TEST_##clayout == SOC_OPS_TEST_SINGLE ? 1 : 2, \ + .value.integer.min = cmin, \ + .value.integer.max = cmax, \ + } + +#define ITEST(cname, clayout, ctype, cfunc, cmin, cmax, \ + xmin, xmax, xpmax, xsign, xinvert) \ + { \ + .name = cname, \ + .func_name = #cfunc, \ + .layout = SOC_OPS_TEST_##clayout, \ + .info = snd_soc_info_##cfunc, \ + TEST_MC(clayout, xmin, xmax, xpmax, xsign, xinvert), \ + TEST_UINFO(clayout, ctype, cmin, cmax), \ + } + +#define ATEST(clayout, cfunc, cctl, cret, cinit, \ + xmask, xreg, xmin, xmax, xpmax, xsign, xinvert) \ + { \ + .func_name = #cfunc, \ + .layout = SOC_OPS_TEST_##clayout, \ + .put = snd_soc_put_##cfunc, \ + .get = snd_soc_get_##cfunc, \ + TEST_MC(clayout, xmin, xmax, xpmax, xsign, xinvert), \ + .lctl = cctl, .rctl = cctl, \ + .lmask = SOC_OPS_TEST_##clayout == SOC_OPS_TEST_DOUBLE ? \ + (xmask) | (xmask) << 16 : (xmask), \ + .rmask = SOC_OPS_TEST_##clayout == SOC_OPS_TEST_DOUBLE_R ? (xmask) : 0, \ + .init = cinit ? 0xFFFFFFFF : 0x00000000, \ + .lreg = SOC_OPS_TEST_##clayout == SOC_OPS_TEST_DOUBLE ? \ + (xreg) | (xreg) << 16 : (xreg), \ + .rreg = SOC_OPS_TEST_##clayout == SOC_OPS_TEST_DOUBLE_R ? (xreg) : 0, \ + .ret = cret, \ + } + +struct soc_ops_test_priv { + struct kunit *test; + + struct snd_soc_component component; +}; + +struct info_test_param { + const char * const name; + const char * const func_name; + enum soc_ops_test_control_layout layout; + struct soc_mixer_control mc; + int (*info)(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *info); + + struct snd_ctl_elem_info uinfo; +}; + +struct access_test_param { + const char * const func_name; + enum soc_ops_test_control_layout layout; + struct soc_mixer_control mc; + int (*put)(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *value); + int (*get)(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *value); + + unsigned int init; + unsigned int lmask; + unsigned int rmask; + unsigned int lreg; + unsigned int rreg; + long lctl; + long rctl; + int ret; +}; + +static const struct info_test_param all_info_test_params[] = { + // Handling of volume control name for types + ITEST("Test Control", SINGLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Volume", SINGLE, INTEGER, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Volume Control", SINGLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Control", DOUBLE_R, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Volume", DOUBLE_R, INTEGER, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Volume Control", DOUBLE_R, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Control", DOUBLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Volume", DOUBLE, INTEGER, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Volume Control", DOUBLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 0), + ITEST("Test Control", SINGLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 1), + ITEST("Test Volume", SINGLE, INTEGER, volsw, 0, 1, 0, 1, 0, 0, 1), + ITEST("Test Volume Control", SINGLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 1), + ITEST("Test Control", DOUBLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 1), + ITEST("Test Volume", DOUBLE, INTEGER, volsw, 0, 1, 0, 1, 0, 0, 1), + ITEST("Test Volume Control", DOUBLE, BOOLEAN, volsw, 0, 1, 0, 1, 0, 0, 1), + ITEST("Test Control", SINGLE, INTEGER, volsw, 0, 2, 0, 2, 0, 0, 0), + ITEST("Test Volume", SINGLE, INTEGER, volsw, 0, 2, 0, 2, 0, 0, 0), + ITEST("Test Volume Control", SINGLE, INTEGER, volsw, 0, 2, 0, 2, 0, 0, 0), + ITEST("Test Control", SINGLE, INTEGER, volsw, 0, 1, 0, 2, 1, 0, 0), + ITEST("Test Volume", SINGLE, INTEGER, volsw, 0, 1, 0, 2, 1, 0, 0), + ITEST("Test Volume Control", SINGLE, INTEGER, volsw, 0, 1, 0, 2, 1, 0, 0), + // Negative minimums + ITEST("Test Control", SINGLE, INTEGER, volsw, 0, 20, -10, 10, 0, 4, 0), + ITEST("Test Control", SINGLE, INTEGER, volsw, 0, 15, -10, 10, 15, 4, 0), + ITEST("Test Control", SINGLE, INTEGER, volsw, 0, 20, -10, 10, 0, 4, 1), + ITEST("Test Control", SINGLE, INTEGER, volsw, 0, 15, -10, 10, 15, 4, 1), + // SX control volume control naming + ITEST("Test Control", SINGLE, BOOLEAN, volsw_sx, 0, 1, 0xF, 1, 0, 0, 0), + ITEST("Test Volume", SINGLE, INTEGER, volsw_sx, 0, 1, 0xF, 1, 0, 0, 0), + ITEST("Test Volume Control", SINGLE, BOOLEAN, volsw_sx, 0, 1, 0xF, 1, 0, 0, 0), + ITEST("Test Control", SINGLE, INTEGER, volsw_sx, 0, 4, 0xE, 4, 0, 0, 0), + ITEST("Test Volume", SINGLE, INTEGER, volsw_sx, 0, 4, 0xE, 4, 0, 0, 0), + ITEST("Test Volume Control", SINGLE, INTEGER, volsw_sx, 0, 4, 0xE, 4, 0, 0, 0), + ITEST("Test Control", SINGLE, INTEGER, volsw_sx, 0, 3, 0xE, 4, 3, 0, 0), + ITEST("Test Volume", SINGLE, INTEGER, volsw_sx, 0, 3, 0xE, 4, 3, 0, 0), + ITEST("Test Volume Control", SINGLE, INTEGER, volsw_sx, 0, 3, 0xE, 4, 3, 0, 0), +}; + +static const struct access_test_param all_access_test_params[] = { + // Single positive value controls + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 0, 0, 0), + ATEST(SINGLE, volsw, 0, 0, false, 0x1F, 0x00, 0, 20, 0, 0, 0), + ATEST(SINGLE, volsw, 20, 1, false, 0x1F, 0x14, 0, 20, 0, 0, 0), + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 15, 0, 0), + ATEST(SINGLE, volsw, 25, -22, false, 0x1F, 0x00, 0, 20, 15, 0, 0), + ATEST(SINGLE, volsw, 15, 1, false, 0x1F, 0x0F, 0, 20, 15, 0, 0), + // Inverted single positive value controls + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 0, 0, 1), + ATEST(SINGLE, volsw, 0, 1, false, 0x1F, 0x14, 0, 20, 0, 0, 1), + ATEST(SINGLE, volsw, 20, 0, false, 0x1F, 0x00, 0, 20, 0, 0, 1), + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 15, 0, 1), + ATEST(SINGLE, volsw, 25, -22, false, 0x1F, 0x00, 0, 20, 15, 0, 1), + ATEST(SINGLE, volsw, 15, 1, false, 0x1F, 0x05, 0, 20, 15, 0, 1), + ATEST(SINGLE, volsw, 10, 1, true, 0x1F, 0x0A, 0, 20, 0, 0, 0), + ATEST(SINGLE, volsw, 0, 1, true, 0x1F, 0x00, 0, 20, 0, 0, 0), + ATEST(SINGLE, volsw, 20, 1, true, 0x1F, 0x14, 0, 20, 0, 0, 0), + ATEST(SINGLE, volsw, 10, 1, true, 0x1F, 0x0A, 0, 20, 15, 0, 0), + ATEST(SINGLE, volsw, 25, -22, true, 0x1F, 0x00, 0, 20, 15, 0, 0), + ATEST(SINGLE, volsw, 15, 1, true, 0x1F, 0x0F, 0, 20, 15, 0, 0), + // Single negative value controls + ATEST(SINGLE, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 0, 4, 0), + ATEST(SINGLE, volsw, 0, 1, false, 0x1F, 0x16, -10, 10, 0, 4, 0), + ATEST(SINGLE, volsw, 20, 1, false, 0x1F, 0x0A, -10, 10, 0, 4, 0), + ATEST(SINGLE, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(SINGLE, volsw, 25, -22, false, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(SINGLE, volsw, 15, 1, false, 0x1F, 0x05, -10, 10, 15, 4, 0), + // Single non-zero minimum positive value controls + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 0, 0, 0), + ATEST(SINGLE, volsw, 0, 1, false, 0x1F, 0x0A, 10, 30, 0, 0, 0), + ATEST(SINGLE, volsw, 20, 1, false, 0x1F, 0x1E, 10, 30, 0, 0, 0), + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 15, 0, 0), + ATEST(SINGLE, volsw, 25, -22, false, 0x1F, 0x00, 10, 30, 15, 0, 0), + ATEST(SINGLE, volsw, 15, 1, false, 0x1F, 0x19, 10, 30, 15, 0, 0), + // Inverted single non-zero minimum positive value controls + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 0, 0, 1), + ATEST(SINGLE, volsw, 0, 1, false, 0x1F, 0x1E, 10, 30, 0, 0, 1), + ATEST(SINGLE, volsw, 20, 1, false, 0x1F, 0x0A, 10, 30, 0, 0, 1), + ATEST(SINGLE, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 15, 0, 1), + ATEST(SINGLE, volsw, 25, -22, false, 0x1F, 0x00, 10, 30, 15, 0, 1), + ATEST(SINGLE, volsw, 15, 1, false, 0x1F, 0x0F, 10, 30, 15, 0, 1), + // Double register positive value controls + ATEST(DOUBLE_R, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 0, 0, 0), + ATEST(DOUBLE_R, volsw, 0, 0, false, 0x1F, 0x00, 0, 20, 0, 0, 0), + ATEST(DOUBLE_R, volsw, 20, 1, false, 0x1F, 0x14, 0, 20, 0, 0, 0), + ATEST(DOUBLE_R, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 15, 0, 0), + ATEST(DOUBLE_R, volsw, 25, -22, false, 0x1F, 0x00, 0, 20, 15, 0, 0), + ATEST(DOUBLE_R, volsw, 15, 1, false, 0x1F, 0x0F, 0, 20, 15, 0, 0), + // Double register negative value controls + ATEST(DOUBLE_R, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 0, 4, 0), + ATEST(DOUBLE_R, volsw, 0, 1, false, 0x1F, 0x16, -10, 10, 0, 4, 0), + ATEST(DOUBLE_R, volsw, 20, 1, false, 0x1F, 0x0A, -10, 10, 0, 4, 0), + ATEST(DOUBLE_R, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(DOUBLE_R, volsw, 25, -22, false, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(DOUBLE_R, volsw, 15, 1, false, 0x1F, 0x05, -10, 10, 15, 4, 0), + ATEST(DOUBLE_R, volsw, 10, 1, true, 0x1F, 0x00, -10, 10, 0, 4, 0), + ATEST(DOUBLE_R, volsw, 0, 1, true, 0x1F, 0x16, -10, 10, 0, 4, 0), + ATEST(DOUBLE_R, volsw, 20, 1, true, 0x1F, 0x0A, -10, 10, 0, 4, 0), + ATEST(DOUBLE_R, volsw, 10, 1, true, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(DOUBLE_R, volsw, 25, -22, true, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(DOUBLE_R, volsw, 15, 1, true, 0x1F, 0x05, -10, 10, 15, 4, 0), + // Inverted double register negative value controls + ATEST(DOUBLE_R, volsw, 10, 1, true, 0x1F, 0x00, -10, 10, 0, 4, 1), + ATEST(DOUBLE_R, volsw, 0, 1, true, 0x1F, 0x0A, -10, 10, 0, 4, 1), + ATEST(DOUBLE_R, volsw, 20, 1, true, 0x1F, 0x16, -10, 10, 0, 4, 1), + ATEST(DOUBLE_R, volsw, 10, 1, true, 0x1F, 0x00, -10, 10, 15, 4, 1), + ATEST(DOUBLE_R, volsw, 25, -22, true, 0x1F, 0x00, -10, 10, 15, 4, 1), + ATEST(DOUBLE_R, volsw, 15, 1, true, 0x1F, 0x1B, -10, 10, 15, 4, 1), + // Double register non-zero minimum positive value controls + ATEST(DOUBLE_R, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 0, 0, 0), + ATEST(DOUBLE_R, volsw, 0, 1, false, 0x1F, 0x0A, 10, 30, 0, 0, 0), + ATEST(DOUBLE_R, volsw, 20, 1, false, 0x1F, 0x1E, 10, 30, 0, 0, 0), + ATEST(DOUBLE_R, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 15, 0, 0), + ATEST(DOUBLE_R, volsw, 25, -22, false, 0x1F, 0x00, 10, 30, 15, 0, 0), + ATEST(DOUBLE_R, volsw, 15, 1, false, 0x1F, 0x19, 10, 30, 15, 0, 0), + // Double shift positive value controls + ATEST(DOUBLE, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 0, 0, 0), + ATEST(DOUBLE, volsw, 0, 0, false, 0x1F, 0x00, 0, 20, 0, 0, 0), + ATEST(DOUBLE, volsw, 20, 1, false, 0x1F, 0x14, 0, 20, 0, 0, 0), + ATEST(DOUBLE, volsw, 10, 1, false, 0x1F, 0x0A, 0, 20, 15, 0, 0), + ATEST(DOUBLE, volsw, 25, -22, false, 0x1F, 0x00, 0, 20, 15, 0, 0), + ATEST(DOUBLE, volsw, 15, 1, false, 0x1F, 0x0F, 0, 20, 15, 0, 0), + // Double shift negative value controls + ATEST(DOUBLE, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 0, 4, 0), + ATEST(DOUBLE, volsw, 0, 1, false, 0x1F, 0x16, -10, 10, 0, 4, 0), + ATEST(DOUBLE, volsw, 20, 1, false, 0x1F, 0x0A, -10, 10, 0, 4, 0), + ATEST(DOUBLE, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(DOUBLE, volsw, 25, -22, false, 0x1F, 0x00, -10, 10, 15, 4, 0), + ATEST(DOUBLE, volsw, 15, 1, false, 0x1F, 0x05, -10, 10, 15, 4, 0), + // Inverted double shift negative value controls + ATEST(DOUBLE, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 0, 4, 1), + ATEST(DOUBLE, volsw, 0, 1, false, 0x1F, 0x0A, -10, 10, 0, 4, 1), + ATEST(DOUBLE, volsw, 20, 1, false, 0x1F, 0x16, -10, 10, 0, 4, 1), + ATEST(DOUBLE, volsw, 10, 0, false, 0x1F, 0x00, -10, 10, 15, 4, 1), + ATEST(DOUBLE, volsw, 25, -22, false, 0x1F, 0x00, -10, 10, 15, 4, 1), + ATEST(DOUBLE, volsw, 15, 1, false, 0x1F, 0x1B, -10, 10, 15, 4, 1), + // Double shift non-zero minimum positive value controls + ATEST(DOUBLE, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 0, 0, 0), + ATEST(DOUBLE, volsw, 0, 1, false, 0x1F, 0x0A, 10, 30, 0, 0, 0), + ATEST(DOUBLE, volsw, 20, 1, false, 0x1F, 0x1E, 10, 30, 0, 0, 0), + ATEST(DOUBLE, volsw, 10, 1, false, 0x1F, 0x14, 10, 30, 15, 0, 0), + ATEST(DOUBLE, volsw, 25, -22, false, 0x1F, 0x00, 10, 30, 15, 0, 0), + ATEST(DOUBLE, volsw, 15, 1, false, 0x1F, 0x19, 10, 30, 15, 0, 0), + ATEST(DOUBLE, volsw, 10, 1, true, 0x1F, 0x14, 10, 30, 0, 0, 0), + ATEST(DOUBLE, volsw, 0, 1, true, 0x1F, 0x0A, 10, 30, 0, 0, 0), + ATEST(DOUBLE, volsw, 20, 1, true, 0x1F, 0x1E, 10, 30, 0, 0, 0), + ATEST(DOUBLE, volsw, 10, 1, true, 0x1F, 0x14, 10, 30, 15, 0, 0), + ATEST(DOUBLE, volsw, 25, -22, true, 0x1F, 0x00, 10, 30, 15, 0, 0), + ATEST(DOUBLE, volsw, 15, 1, true, 0x1F, 0x19, 10, 30, 15, 0, 0), + // Single SX all values + ATEST(SINGLE, volsw_sx, 0, 1, false, 0xF, 0x0F, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 1, 0, false, 0xF, 0x00, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 2, 1, false, 0xF, 0x01, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 3, 1, false, 0xF, 0x02, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 4, 1, false, 0xF, 0x03, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 5, -22, false, 0xF, 0x00, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 0, 0, true, 0xF, 0x0F, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 1, 1, true, 0xF, 0x00, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 2, 1, true, 0xF, 0x01, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 3, 1, true, 0xF, 0x02, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 4, 1, true, 0xF, 0x03, 0x0F, 4, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 5, -22, true, 0xF, 0x00, 0x0F, 4, 0, 0, 0), + // Inverted single SX all values + ATEST(SINGLE, volsw_sx, 0, 1, false, 0x1F, 0x03, 0x0F, 4, 0, 0, 1), + ATEST(SINGLE, volsw_sx, 1, 1, false, 0x1F, 0x02, 0x0F, 4, 0, 0, 1), + ATEST(SINGLE, volsw_sx, 2, 1, false, 0x1F, 0x01, 0x0F, 4, 0, 0, 1), + ATEST(SINGLE, volsw_sx, 3, 0, false, 0x1F, 0x00, 0x0F, 4, 0, 0, 1), + ATEST(SINGLE, volsw_sx, 4, 1, false, 0x1F, 0x0F, 0x0F, 4, 0, 0, 1), + ATEST(SINGLE, volsw_sx, 5, -22, false, 0x1F, 0x00, 0x0F, 4, 0, 0, 1), + // Single SX select values + ATEST(SINGLE, volsw_sx, 0, 1, false, 0xFF, 0x88, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 1, 1, false, 0xFF, 0x89, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 119, 1, false, 0xFF, 0xFF, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 120, 0, false, 0xFF, 0x00, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 121, 1, false, 0xFF, 0x01, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 143, 1, false, 0xFF, 0x17, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 144, 1, false, 0xFF, 0x18, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 145, -22, false, 0xFF, 0x00, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 0, 1, true, 0xFF, 0x88, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 1, 1, true, 0xFF, 0x89, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 119, 0, true, 0xFF, 0xFF, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 120, 1, true, 0xFF, 0x00, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 121, 1, true, 0xFF, 0x01, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 143, 1, true, 0xFF, 0x17, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 144, 1, true, 0xFF, 0x18, 0x88, 144, 0, 0, 0), + ATEST(SINGLE, volsw_sx, 145, -22, true, 0xFF, 0x00, 0x88, 144, 0, 0, 0), + // Double shift SX select values + ATEST(DOUBLE, volsw_sx, 0, 1, true, 0xFF, 0x88, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE, volsw_sx, 1, 1, true, 0xFF, 0x89, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE, volsw_sx, 119, 0, true, 0xFF, 0xFF, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE, volsw_sx, 120, 1, true, 0xFF, 0x00, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE, volsw_sx, 121, 1, true, 0xFF, 0x01, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE, volsw_sx, 143, 1, true, 0xFF, 0x17, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE, volsw_sx, 144, 1, true, 0xFF, 0x18, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE, volsw_sx, 145, -22, true, 0xFF, 0x00, 0x88, 144, 0, 0, 0), + // Double register SX select values + ATEST(DOUBLE_R, volsw_sx, 0, 1, true, 0xFF, 0x88, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE_R, volsw_sx, 1, 1, true, 0xFF, 0x89, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE_R, volsw_sx, 119, 0, true, 0xFF, 0xFF, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE_R, volsw_sx, 120, 1, true, 0xFF, 0x00, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE_R, volsw_sx, 121, 1, true, 0xFF, 0x01, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE_R, volsw_sx, 143, 1, true, 0xFF, 0x17, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE_R, volsw_sx, 144, 1, true, 0xFF, 0x18, 0x88, 144, 0, 0, 0), + ATEST(DOUBLE_R, volsw_sx, 145, -22, true, 0xFF, 0x00, 0x88, 144, 0, 0, 0), +}; + +static const char *control_type_str(const snd_ctl_elem_type_t type) +{ + switch (type) { + case SNDRV_CTL_ELEM_TYPE_BOOLEAN: + return "bool"; + case SNDRV_CTL_ELEM_TYPE_INTEGER: + return "int"; + default: + return "unknown"; + } +} + +static const char *control_layout_str(const enum soc_ops_test_control_layout layout) +{ + switch (layout) { + case SOC_OPS_TEST_SINGLE: + return "single"; + case SOC_OPS_TEST_DOUBLE: + return "double"; + case SOC_OPS_TEST_DOUBLE_R: + return "double_r"; + default: + return "unknown"; + } +}; + +static int mock_regmap_read(void *context, const void *reg_buf, + const size_t reg_size, void *val_buf, + size_t val_size) +{ + struct soc_ops_test_priv *priv = context; + + KUNIT_FAIL(priv->test, "Unexpected bus read"); + + return -EIO; +} + +static int mock_regmap_gather_write(void *context, + const void *reg_buf, size_t reg_size, + const void *val_buf, size_t val_size) +{ + struct soc_ops_test_priv *priv = context; + + KUNIT_FAIL(priv->test, "Unexpected bus gather_write"); + + return -EIO; +} + +static int mock_regmap_write(void *context, const void *val_buf, + size_t val_size) +{ + struct soc_ops_test_priv *priv = context; + + KUNIT_FAIL(priv->test, "Unexpected bus write"); + + return -EIO; +} + +static const struct regmap_bus mock_regmap_bus = { + .read = mock_regmap_read, + .write = mock_regmap_write, + .gather_write = mock_regmap_gather_write, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, + .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +static const struct regmap_config mock_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, + .max_register = 0x1, + .cache_type = REGCACHE_FLAT, +}; + +static int soc_ops_test_init(struct kunit *test) +{ + struct soc_ops_test_priv *priv; + struct regmap *regmap; + struct device *dev; + + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->test = test; + + dev = kunit_device_register(test, "soc_ops_test_drv"); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + regmap = devm_regmap_init(dev, &mock_regmap_bus, priv, &mock_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* No actual hardware, we just use the cache */ + regcache_cache_only(regmap, true); + + priv->component.dev = dev; + priv->component.regmap = regmap; + mutex_init(&priv->component.io_mutex); + + test->priv = priv; + + return 0; +} + +static void soc_ops_test_exit(struct kunit *test) +{ + struct soc_ops_test_priv *priv = test->priv; + + kunit_device_unregister(test, priv->component.dev); +} + +static void info_test_desc(const struct info_test_param *param, char *desc) +{ + snprintf(desc, KUNIT_PARAM_DESC_SIZE, + "%s %s %s: ctl range: %ld->%ld, reg range: %d->%d(%d), sign: %d, inv: %d", + control_layout_str(param->layout), param->func_name, + control_type_str(param->uinfo.type), + param->uinfo.value.integer.min, param->uinfo.value.integer.max, + param->mc.min, param->mc.max, param->mc.platform_max, + param->mc.sign_bit, param->mc.invert); +} + +static void soc_ops_test_info(struct kunit *test) +{ + struct soc_ops_test_priv *priv = test->priv; + const struct info_test_param *param = test->param_value; + const struct snd_ctl_elem_info *target = ¶m->uinfo; + struct snd_ctl_elem_info result; + struct snd_kcontrol kctl = { + .private_data = &priv->component, + .private_value = (unsigned long)¶m->mc, + }; + int ret; + + strscpy(kctl.id.name, param->name, sizeof(kctl.id.name)); + + ret = param->info(&kctl, &result); + KUNIT_ASSERT_FALSE(test, ret); + + KUNIT_EXPECT_EQ(test, result.count, target->count); + KUNIT_EXPECT_EQ(test, result.type, target->type); + KUNIT_EXPECT_EQ(test, result.value.integer.min, target->value.integer.min); + KUNIT_EXPECT_EQ(test, result.value.integer.max, target->value.integer.max); +} + +static void access_test_desc(const struct access_test_param *param, char *desc) +{ + if (param->ret < 0) { + snprintf(desc, KUNIT_PARAM_DESC_SIZE, + "%s %s: %ld,%ld -> range: %d->%d(%d), sign: %d, inv: %d -> err: %d", + control_layout_str(param->layout), param->func_name, + param->lctl, param->rctl, + param->mc.min, param->mc.max, param->mc.platform_max, + param->mc.sign_bit, param->mc.invert, + param->ret); + } else { + snprintf(desc, KUNIT_PARAM_DESC_SIZE, + "%s %s: %ld,%ld -> range: %d->%d(%d), sign: %d, inv: %d -> %#x,%#x", + control_layout_str(param->layout), param->func_name, + param->lctl, param->rctl, + param->mc.min, param->mc.max, param->mc.platform_max, + param->mc.sign_bit, param->mc.invert, + param->lreg, param->rreg); + } +} + +static void soc_ops_test_access(struct kunit *test) +{ + struct soc_ops_test_priv *priv = test->priv; + const struct access_test_param *param = test->param_value; + struct snd_kcontrol kctl = { + .private_data = &priv->component, + .private_value = (unsigned long)¶m->mc, + }; + struct snd_ctl_elem_value result; + unsigned int val; + int ret; + + ret = regmap_write(priv->component.regmap, 0x0, param->init); + KUNIT_ASSERT_FALSE(test, ret); + ret = regmap_write(priv->component.regmap, 0x1, param->init); + KUNIT_ASSERT_FALSE(test, ret); + + result.value.integer.value[0] = param->lctl; + result.value.integer.value[1] = param->rctl; + + ret = param->put(&kctl, &result); + KUNIT_ASSERT_EQ(test, ret, param->ret); + if (ret < 0) + return; + + ret = regmap_read(priv->component.regmap, 0x0, &val); + KUNIT_ASSERT_FALSE(test, ret); + KUNIT_EXPECT_EQ(test, val, (param->init & ~param->lmask) | param->lreg); + + ret = regmap_read(priv->component.regmap, 0x1, &val); + KUNIT_ASSERT_FALSE(test, ret); + KUNIT_EXPECT_EQ(test, val, (param->init & ~param->rmask) | param->rreg); + + result.value.integer.value[0] = 0; + result.value.integer.value[1] = 0; + + ret = param->get(&kctl, &result); + KUNIT_ASSERT_GE(test, ret, 0); + + KUNIT_EXPECT_EQ(test, result.value.integer.value[0], param->lctl); + if (param->layout != SOC_OPS_TEST_SINGLE) + KUNIT_EXPECT_EQ(test, result.value.integer.value[1], param->rctl); + else + KUNIT_EXPECT_EQ(test, result.value.integer.value[1], 0); +} + +KUNIT_ARRAY_PARAM(all_info_tests, all_info_test_params, info_test_desc); +KUNIT_ARRAY_PARAM(all_access_tests, all_access_test_params, access_test_desc); + +static struct kunit_case soc_ops_test_cases[] = { + KUNIT_CASE_PARAM(soc_ops_test_info, all_info_tests_gen_params), + KUNIT_CASE_PARAM(soc_ops_test_access, all_access_tests_gen_params), + {} +}; + +static struct kunit_suite soc_ops_test_suite = { + .name = "soc-ops", + .init = soc_ops_test_init, + .exit = soc_ops_test_exit, + .test_cases = soc_ops_test_cases, +}; + +kunit_test_suites(&soc_ops_test_suite); + +MODULE_DESCRIPTION("ASoC soc-ops kunit test"); +MODULE_LICENSE("GPL"); From 534bfb330b2612199b2afaafc769ccb42bebb204 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:46 +0000 Subject: [PATCH 619/651] ASoC: ops: Minor formatting fixups No functional changes just tidying up some tabbing etc. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 106 ++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index cd5f927bcd4e..9039bf3b6fb4 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -37,7 +37,7 @@ * Returns 0 for success. */ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) + struct snd_ctl_elem_info *uinfo) { struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -56,7 +56,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_enum_double); * Returns 0 for success. */ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_enum_double); * Returns 0 for success. */ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; @@ -124,8 +124,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); * the given registervalue into a signed integer if sign_bit is non-zero. */ 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) + unsigned int reg, unsigned int mask, + unsigned int shift, unsigned int sign_bit, + int *signed_val) { int ret; unsigned int val; @@ -168,7 +169,7 @@ static void snd_soc_read_signed(struct snd_soc_component *component, * Returns 0 for success. */ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) + struct snd_ctl_elem_info *uinfo) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -247,7 +248,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx); * Returns 0 for success. */ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = @@ -300,7 +301,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw); * Returns 0 for success. */ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = @@ -362,9 +363,8 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, err = snd_soc_component_update_bits(component, reg2, val_mask, val2); /* Don't discard any error code or drop change flag */ - if (ret == 0 || err < 0) { + if (ret == 0 || err < 0) ret = err; - } } return ret; @@ -382,11 +382,11 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw); * Returns 0 for success. */ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; + (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; @@ -423,18 +423,17 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - + (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; + unsigned int val, val_mask; int max = mc->max; int min = mc->min; unsigned int mask = (1U << (fls(min + max) - 1)) - 1; int err = 0; int ret; - unsigned int val, val_mask; if (ucontrol->value.integer.value[0] < 0) return -EINVAL; @@ -465,13 +464,13 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, val2 = val2 << rshift; err = snd_soc_component_update_bits(component, reg2, val_mask, - val2); + val2); /* Don't discard any error code or drop change flag */ - if (ret == 0 || err < 0) { + if (ret == 0 || err < 0) ret = err; - } } + return ret; } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); @@ -487,7 +486,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); * returns 0 for success. */ int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) + struct snd_ctl_elem_info *uinfo) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -516,7 +515,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range); * Returns 0 for success. */ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -568,11 +567,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, val = val << shift; err = snd_soc_component_update_bits(component, rreg, val_mask, - val); + val); /* Don't discard any error code or drop change flag */ - if (ret == 0 || err < 0) { + if (ret == 0 || err < 0) ret = err; - } } return ret; @@ -589,7 +587,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); * Returns 0 for success. */ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = @@ -663,8 +661,7 @@ static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) * * Return 0 for success, else error. */ -int snd_soc_limit_volume(struct snd_soc_card *card, - const char *name, int max) +int snd_soc_limit_volume(struct snd_soc_card *card, const char *name, int max) { struct snd_kcontrol *kctl; int ret = -EINVAL; @@ -675,12 +672,15 @@ int snd_soc_limit_volume(struct snd_soc_card *card, kctl = snd_soc_card_get_kcontrol(card, name); if (kctl) { - struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kctl->private_value; + if (max <= mc->max - mc->min) { mc->platform_max = max; ret = snd_soc_clip_to_platform_max(kctl); } } + return ret; } EXPORT_SYMBOL_GPL(snd_soc_limit_volume); @@ -740,8 +740,8 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_bytes *params = (void *)kcontrol->private_value; - int ret, len; unsigned int val, mask; + int ret, len; if (!component->regmap || !params->num_regs) return -EINVAL; @@ -772,15 +772,13 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, break; case 2: mask = ~params->mask; - ret = regmap_parse_val(component->regmap, - &mask, &mask); + ret = regmap_parse_val(component->regmap, &mask, &mask); if (ret != 0) return ret; ((u16 *)data)[0] &= mask; - ret = regmap_parse_val(component->regmap, - &val, &val); + ret = regmap_parse_val(component->regmap, &val, &val); if (ret != 0) return ret; @@ -788,15 +786,13 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, break; case 4: mask = ~params->mask; - ret = regmap_parse_val(component->regmap, - &mask, &mask); + ret = regmap_parse_val(component->regmap, &mask, &mask); if (ret != 0) return ret; ((u32 *)data)[0] &= mask; - ret = regmap_parse_val(component->regmap, - &val, &val); + ret = regmap_parse_val(component->regmap, &val, &val); if (ret != 0) return ret; @@ -812,7 +808,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, EXPORT_SYMBOL_GPL(snd_soc_bytes_put); int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *ucontrol) + struct snd_ctl_elem_info *ucontrol) { struct soc_bytes_ext *params = (void *)kcontrol->private_value; @@ -824,7 +820,7 @@ int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, EXPORT_SYMBOL_GPL(snd_soc_bytes_info_ext); int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag, - unsigned int size, unsigned int __user *tlv) + unsigned int size, unsigned int __user *tlv) { struct soc_bytes_ext *params = (void *)kcontrol->private_value; unsigned int count = size < params->max ? size : params->max; @@ -840,6 +836,7 @@ int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag, ret = params->put(kcontrol, tlv, count); break; } + return ret; } EXPORT_SYMBOL_GPL(snd_soc_bytes_tlv_callback); @@ -856,10 +853,11 @@ EXPORT_SYMBOL_GPL(snd_soc_bytes_tlv_callback); * Returns 0 for success. */ int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) + struct snd_ctl_elem_info *uinfo) { struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; uinfo->value.integer.min = mc->min; @@ -883,7 +881,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx); * Returns 0 for success. */ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mreg_control *mc = @@ -891,17 +889,18 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; - unsigned int regwmask = (1UL<invert; - unsigned long mask = (1UL<nbits)-1; + unsigned long mask = (1UL << mc->nbits) - 1; long min = mc->min; long max = mc->max; long val = 0; unsigned int i; for (i = 0; i < regcount; i++) { - unsigned int regval = snd_soc_component_read(component, regbase+i); - val |= (regval & regwmask) << (regwshift*(regcount-i-1)); + unsigned int regval = snd_soc_component_read(component, regbase + i); + + val |= (regval & regwmask) << (regwshift * (regcount - i - 1)); } val &= mask; if (min < 0 && val > max) @@ -928,7 +927,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx); * Returns 0 for success. */ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mreg_control *mc = @@ -936,9 +935,9 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; - unsigned int regwmask = (1UL<invert; - unsigned long mask = (1UL<nbits)-1; + unsigned long mask = (1UL << mc->nbits) - 1; long max = mc->max; long val = ucontrol->value.integer.value[0]; int ret = 0; @@ -950,10 +949,13 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, val = max - val; val &= mask; for (i = 0; i < regcount; i++) { - unsigned int regval = (val >> (regwshift*(regcount-i-1))) & regwmask; - unsigned int regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; - int err = snd_soc_component_update_bits(component, regbase+i, + unsigned int regval = (val >> (regwshift * (regcount - i - 1))) & + regwmask; + unsigned int regmask = (mask >> (regwshift * (regcount - i - 1))) & + regwmask; + int err = snd_soc_component_update_bits(component, regbase + i, regmask, regval); + if (err < 0) return err; if (err > 0) @@ -974,7 +976,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx); * Returns 0 for success. */ int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = @@ -1007,7 +1009,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_strobe); * Returns 1 for success. */ int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = From 7f978180673b4f3b68fcc66fc1f1d74a1fc5a93a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:47 +0000 Subject: [PATCH 620/651] ASoC: ops: Update comments for xr_sx control helpers Update the comments for the xr_sx control helper functions to better clarify the difference between these and the normal sx helpers. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 9039bf3b6fb4..dac55138210d 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -846,9 +846,10 @@ EXPORT_SYMBOL_GPL(snd_soc_bytes_tlv_callback); * @kcontrol: mreg control * @uinfo: control element information * - * Callback to provide information of a control that can - * span multiple codec registers which together - * forms a single signed value in a MSB/LSB manner. + * Callback to provide information of a control that can span multiple + * codec registers which together forms a single signed value. Note + * that unlike the non-xr variant of sx controls these may or may not + * include the sign bit, depending on nbits, and there is no shift. * * Returns 0 for success. */ @@ -872,11 +873,12 @@ EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx); * @kcontrol: mreg control * @ucontrol: control element information * - * Callback to get the value of a control that can span - * multiple codec registers which together forms a single - * signed value in a MSB/LSB manner. The control supports - * specifying total no of bits used to allow for bitfields - * across the multiple codec registers. + * Callback to get the value of a control that can span multiple codec + * registers which together forms a single signed value. The control + * supports specifying total no of bits used to allow for bitfields + * across the multiple codec registers. Note that unlike the non-xr + * variant of sx controls these may or may not include the sign bit, + * depending on nbits, and there is no shift. * * Returns 0 for success. */ @@ -918,11 +920,12 @@ EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx); * @kcontrol: mreg control * @ucontrol: control element information * - * Callback to set the value of a control that can span - * multiple codec registers which together forms a single - * signed value in a MSB/LSB manner. The control supports - * specifying total no of bits used to allow for bitfields - * across the multiple codec registers. + * Callback to set the value of a control that can span multiple codec + * registers which together forms a single signed value. The control + * supports specifying total no of bits used to allow for bitfields + * across the multiple codec registers. Note that unlike the non-xr + * variant of sx controls these may or may not include the sign bit, + * depending on nbits, and there is no shift. * * Returns 0 for success. */ From c6002c1177cafb4462b6c188d2a62eb67f15165f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:48 +0000 Subject: [PATCH 621/651] ASoC: ops: Update mask generation to use GENMASK Use GENMASK to make the masks for the various control helper functions. Also factor out a shared helper function for the volsw and volsw_range controls since the same code is appropriate for each. Note this does add support for sign_bit into the volsw_range callbacks. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 46 +++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index dac55138210d..54945017e1f1 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -158,6 +158,20 @@ static void snd_soc_read_signed(struct snd_soc_component *component, *signed_val = ret; } +static int soc_mixer_mask(struct soc_mixer_control *mc) +{ + if (mc->sign_bit) + return GENMASK(mc->sign_bit, 0); + else + return GENMASK(fls(mc->max) - 1, 0); +} + +static int soc_mixer_sx_mask(struct soc_mixer_control *mc) +{ + // min + max will take us 1-bit over the size of the mask + return GENMASK(fls(mc->min + mc->max) - 2, 0); +} + /** * snd_soc_info_volsw - single mixer info callback * @kcontrol: mixer control @@ -260,13 +274,10 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, int max = mc->max; int min = mc->min; int sign_bit = mc->sign_bit; - unsigned int mask = (1ULL << fls(max)) - 1; + unsigned int mask = soc_mixer_mask(mc); unsigned int invert = mc->invert; int val; - if (sign_bit) - mask = BIT(sign_bit + 1) - 1; - snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); ucontrol->value.integer.value[0] = val - min; @@ -312,17 +323,13 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, unsigned int rshift = mc->rshift; int max = mc->max; int min = mc->min; - unsigned int sign_bit = mc->sign_bit; - unsigned int mask = (1 << fls(max)) - 1; + unsigned int mask = soc_mixer_mask(mc); unsigned int invert = mc->invert; int err, ret; bool type_2r = false; unsigned int val2 = 0; unsigned int val, val_mask; - if (sign_bit) - mask = BIT(sign_bit + 1) - 1; - if (ucontrol->value.integer.value[0] < 0) return -EINVAL; val = ucontrol->value.integer.value[0]; @@ -391,9 +398,8 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; - int max = mc->max; int min = mc->min; - unsigned int mask = (1U << (fls(min + max) - 1)) - 1; + unsigned int mask = soc_mixer_sx_mask(mc); unsigned int val; val = snd_soc_component_read(component, reg); @@ -431,7 +437,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, unsigned int val, val_mask; int max = mc->max; int min = mc->min; - unsigned int mask = (1U << (fls(min + max) - 1)) - 1; + unsigned int mask = soc_mixer_sx_mask(mc); int err = 0; int ret; @@ -525,7 +531,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, unsigned int shift = mc->shift; int min = mc->min; int max = mc->max; - unsigned int mask = (1 << fls(max)) - 1; + unsigned int mask = soc_mixer_mask(mc); unsigned int invert = mc->invert; unsigned int val, val_mask; int err, ret, tmp; @@ -597,7 +603,7 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, unsigned int shift = mc->shift; int min = mc->min; int max = mc->max; - unsigned int mask = (1 << fls(max)) - 1; + unsigned int mask = soc_mixer_mask(mc); unsigned int invert = mc->invert; unsigned int val; @@ -891,9 +897,9 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; - unsigned int regwmask = (1UL << regwshift) - 1; + unsigned int regwmask = GENMASK(regwshift - 1, 0); + unsigned long mask = GENMASK(mc->nbits - 1, 0); unsigned int invert = mc->invert; - unsigned long mask = (1UL << mc->nbits) - 1; long min = mc->min; long max = mc->max; long val = 0; @@ -938,9 +944,9 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; - unsigned int regwmask = (1UL << regwshift) - 1; + unsigned int regwmask = GENMASK(regwshift - 1, 0); + unsigned long mask = GENMASK(mc->nbits - 1, 0); unsigned int invert = mc->invert; - unsigned long mask = (1UL << mc->nbits) - 1; long max = mc->max; long val = ucontrol->value.integer.value[0]; int ret = 0; @@ -986,7 +992,7 @@ int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int shift = mc->shift; - unsigned int mask = 1 << shift; + unsigned int mask = BIT(shift); unsigned int invert = mc->invert != 0; unsigned int val; @@ -1019,7 +1025,7 @@ int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int shift = mc->shift; - unsigned int mask = 1 << shift; + unsigned int mask = BIT(shift); unsigned int invert = mc->invert != 0; unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; unsigned int val1 = (strobe ^ invert) ? mask : 0; From eeb76cb1fa0dcccf33091b04ba150076dfbeb6fd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:49 +0000 Subject: [PATCH 622/651] ASoC: ops: Factor out helper to check valid control values Most of the put handlers have identical code to verify the value passed in from user-space. Factor this out into a single helper function. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 82 ++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 54945017e1f1..53a141426a96 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -158,6 +158,20 @@ static void snd_soc_read_signed(struct snd_soc_component *component, *signed_val = ret; } +static int soc_mixer_valid_ctl(struct soc_mixer_control *mc, long val, int max) +{ + if (val < 0) + return -EINVAL; + + if (mc->platform_max && val > mc->platform_max) + return -EINVAL; + + if (val > max) + return -EINVAL; + + return 0; +} + static int soc_mixer_mask(struct soc_mixer_control *mc) { if (mc->sign_bit) @@ -330,26 +344,24 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, unsigned int val2 = 0; unsigned int val, val_mask; - if (ucontrol->value.integer.value[0] < 0) - return -EINVAL; + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], + mc->max - mc->min); + if (ret) + return ret; + val = ucontrol->value.integer.value[0]; - if (mc->platform_max && val > mc->platform_max) - return -EINVAL; - if (val > max - min) - return -EINVAL; val = (val + min) & mask; if (invert) val = max - val; val_mask = mask << shift; val = val << shift; if (snd_soc_volsw_is_stereo(mc)) { - if (ucontrol->value.integer.value[1] < 0) - return -EINVAL; + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], + mc->max - mc->min); + if (ret) + return ret; + val2 = ucontrol->value.integer.value[1]; - if (mc->platform_max && val2 > mc->platform_max) - return -EINVAL; - if (val2 > max - min) - return -EINVAL; val2 = (val2 + min) & mask; if (invert) val2 = max - val2; @@ -435,19 +447,16 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; unsigned int val, val_mask; - int max = mc->max; int min = mc->min; unsigned int mask = soc_mixer_sx_mask(mc); int err = 0; int ret; - if (ucontrol->value.integer.value[0] < 0) - return -EINVAL; + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], mc->max); + if (ret) + return ret; + val = ucontrol->value.integer.value[0]; - if (mc->platform_max && val > mc->platform_max) - return -EINVAL; - if (val > max) - return -EINVAL; val_mask = mask << shift; val = (val + min) & mask; val = val << shift; @@ -458,13 +467,14 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, ret = err; if (snd_soc_volsw_is_stereo(mc)) { - unsigned int val2 = ucontrol->value.integer.value[1]; + unsigned int val2; - if (mc->platform_max && val2 > mc->platform_max) - return -EINVAL; - if (val2 > max) - return -EINVAL; + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], + mc->max); + if (ret) + return ret; + val2 = ucontrol->value.integer.value[1]; val_mask = mask << rshift; val2 = (val2 + min) & mask; val2 = val2 << rshift; @@ -534,15 +544,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, unsigned int mask = soc_mixer_mask(mc); unsigned int invert = mc->invert; unsigned int val, val_mask; - int err, ret, tmp; + int err, ret; - tmp = ucontrol->value.integer.value[0]; - if (tmp < 0) - return -EINVAL; - if (mc->platform_max && tmp > mc->platform_max) - return -EINVAL; - if (tmp > mc->max - mc->min) - return -EINVAL; + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], + mc->max - mc->min); + if (ret) + return ret; if (invert) val = (max - ucontrol->value.integer.value[0]) & mask; @@ -557,13 +564,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, ret = err; if (snd_soc_volsw_is_stereo(mc)) { - tmp = ucontrol->value.integer.value[1]; - if (tmp < 0) - return -EINVAL; - if (mc->platform_max && tmp > mc->platform_max) - return -EINVAL; - if (tmp > mc->max - mc->min) - return -EINVAL; + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], + mc->max - mc->min); + if (ret) + return ret; if (invert) val = (max - ucontrol->value.integer.value[1]) & mask; From 1522aacd0114069b7f01f047b9e5b159399af295 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:50 +0000 Subject: [PATCH 623/651] ASoC: ops: Replace snd_soc_read_signed() with new helper The current snd_soc_read_signed() helper is only used from snd_soc_get_volsw() and can be implemented more simply with sign_extend. Remove snd_soc_read_signed() and add a new soc_mixer_reg_to_ctl() helper. This new helper does not include the reading of the register, but does include min and max handling. This allows the helper to replace more of the duplicated code and makes it easier to process the differences between single, double register and double shift style controls. It is worth noting this adds support for sign_bit into the _range and sx callbacks and the invert option to sx callbacks. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 134 ++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 93 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 53a141426a96..af4e67817317 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -110,52 +110,20 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); -/** - * snd_soc_read_signed - Read a codec register and interpret as signed value - * @component: component - * @reg: Register to read - * @mask: Mask to use after shifting the register value - * @shift: Right shift of register value - * @sign_bit: Bit that describes if a number is negative or not. - * @signed_val: Pointer to where the read value should be stored - * - * 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. - */ -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) +static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_val, + unsigned int mask, unsigned int shift, int max) { - int ret; - unsigned int val; + int val = (reg_val >> shift) & mask; - val = snd_soc_component_read(component, reg); - val = (val >> shift) & mask; + if (mc->sign_bit) + val = sign_extend32(val, mc->sign_bit); - if (!sign_bit) { - *signed_val = val; - return; - } + val -= mc->min; - /* non-negative number */ - if (!(val & BIT(sign_bit))) { - *signed_val = val; - return; - } + if (mc->invert) + val = max - val; - ret = val; - - /* - * The register most probably does not contain a full-sized int. - * Instead we have an arbitrary number of bits in a signed - * representation which has to be translated into a full-sized int. - * This is done by filling up all bits above the sign-bit. - */ - ret |= ~((int)(BIT(sign_bit) - 1)); - - *signed_val = ret; + return val & mask; } static int soc_mixer_valid_ctl(struct soc_mixer_control *mc, long val, int max) @@ -281,34 +249,25 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; - int max = mc->max; - int min = mc->min; - int sign_bit = mc->sign_bit; + int max = mc->max - mc->min; unsigned int mask = soc_mixer_mask(mc); - unsigned int invert = mc->invert; + unsigned int reg_val; int val; - snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); + reg_val = snd_soc_component_read(component, mc->reg); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); - ucontrol->value.integer.value[0] = val - min; - if (invert) - ucontrol->value.integer.value[0] = - max - ucontrol->value.integer.value[0]; + ucontrol->value.integer.value[0] = val; if (snd_soc_volsw_is_stereo(mc)) { - if (reg == reg2) - snd_soc_read_signed(component, reg, mask, rshift, sign_bit, &val); - else - snd_soc_read_signed(component, reg2, mask, shift, sign_bit, &val); + if (mc->reg == mc->rreg) { + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, max); + } else { + reg_val = snd_soc_component_read(component, mc->rreg); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); + } - ucontrol->value.integer.value[1] = val - min; - if (invert) - ucontrol->value.integer.value[1] = - max - ucontrol->value.integer.value[1]; + ucontrol->value.integer.value[1] = val; } return 0; @@ -408,18 +367,19 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; - int min = mc->min; unsigned int mask = soc_mixer_sx_mask(mc); - unsigned int val; + unsigned int reg_val; + int val; - val = snd_soc_component_read(component, reg); - ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; + reg_val = snd_soc_component_read(component, reg); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, mc->max); + + ucontrol->value.integer.value[0] = val; if (snd_soc_volsw_is_stereo(mc)) { - val = snd_soc_component_read(component, reg2); - val = ((val >> rshift) - min) & mask; + reg_val = snd_soc_component_read(component, reg2); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, mc->max); + ucontrol->value.integer.value[1] = val; } @@ -602,33 +562,21 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - int min = mc->min; - int max = mc->max; + int max = mc->max - mc->min; unsigned int mask = soc_mixer_mask(mc); - unsigned int invert = mc->invert; - unsigned int val; + unsigned int reg_val; + int val; - val = snd_soc_component_read(component, reg); - ucontrol->value.integer.value[0] = (val >> shift) & mask; - if (invert) - ucontrol->value.integer.value[0] = - max - ucontrol->value.integer.value[0]; - else - ucontrol->value.integer.value[0] = - ucontrol->value.integer.value[0] - min; + reg_val = snd_soc_component_read(component, mc->reg); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); + + ucontrol->value.integer.value[0] = val; if (snd_soc_volsw_is_stereo(mc)) { - val = snd_soc_component_read(component, rreg); - ucontrol->value.integer.value[1] = (val >> shift) & mask; - if (invert) - ucontrol->value.integer.value[1] = - max - ucontrol->value.integer.value[1]; - else - ucontrol->value.integer.value[1] = - ucontrol->value.integer.value[1] - min; + reg_val = snd_soc_component_read(component, mc->rreg); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); + + ucontrol->value.integer.value[1] = val; } return 0; From ed336066202c02f0b0e47d0cf08fd8f40a42351f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:51 +0000 Subject: [PATCH 624/651] ASoC: ops: Add control to register value helper Add a helper function to convert from control values to register values that can replace a lot of the duplicated code in the various put handlers. This also fixes a small issue in snd_soc_put_volsw where the value is converted to a control value before doing the invert, but the invert is done against the register max which will result in incorrect values for inverted controls with a non-zero minimum. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-8-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 97 ++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index af4e67817317..888afdd23f84 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -126,6 +126,20 @@ static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_v return val & mask; } +static unsigned int soc_mixer_ctl_to_reg(struct soc_mixer_control *mc, int val, + unsigned int mask, unsigned int shift, + int max) +{ + unsigned int reg_val; + + if (mc->invert) + val = max - val; + + reg_val = val + mc->min; + + return (reg_val & mask) << shift; +} + static int soc_mixer_valid_ctl(struct soc_mixer_control *mc, long val, int max) { if (val < 0) @@ -292,43 +306,35 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; - int max = mc->max; - int min = mc->min; + int max = mc->max - mc->min; unsigned int mask = soc_mixer_mask(mc); - unsigned int invert = mc->invert; int err, ret; bool type_2r = false; unsigned int val2 = 0; unsigned int val, val_mask; - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], - mc->max - mc->min); + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max); if (ret) return ret; - val = ucontrol->value.integer.value[0]; - val = (val + min) & mask; - if (invert) - val = max - val; - val_mask = mask << shift; - val = val << shift; + val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], + mask, mc->shift, max); + val_mask = mask << mc->shift; + if (snd_soc_volsw_is_stereo(mc)) { - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], - mc->max - mc->min); + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max); if (ret) return ret; - val2 = ucontrol->value.integer.value[1]; - val2 = (val2 + min) & mask; - if (invert) - val2 = max - val2; if (reg == reg2) { - val_mask |= mask << rshift; - val |= val2 << rshift; + val |= soc_mixer_ctl_to_reg(mc, + ucontrol->value.integer.value[1], + mask, mc->rshift, max); + val_mask |= mask << mc->rshift; } else { - val2 = val2 << shift; + val2 = soc_mixer_ctl_to_reg(mc, + ucontrol->value.integer.value[1], + mask, mc->shift, max); type_2r = true; } } @@ -404,10 +410,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; - unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; unsigned int val, val_mask; - int min = mc->min; unsigned int mask = soc_mixer_sx_mask(mc); int err = 0; int ret; @@ -416,10 +419,9 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, if (ret) return ret; - val = ucontrol->value.integer.value[0]; - val_mask = mask << shift; - val = (val + min) & mask; - val = val << shift; + val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], + mask, mc->shift, mc->max); + val_mask = mask << mc->shift; err = snd_soc_component_update_bits(component, reg, val_mask, val); if (err < 0) @@ -427,20 +429,17 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, ret = err; if (snd_soc_volsw_is_stereo(mc)) { - unsigned int val2; - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], mc->max); if (ret) return ret; - val2 = ucontrol->value.integer.value[1]; - val_mask = mask << rshift; - val2 = (val2 + min) & mask; - val2 = val2 << rshift; + val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[1], + mask, mc->rshift, mc->max); + val_mask = mask << mc->rshift; err = snd_soc_component_update_bits(component, reg2, val_mask, - val2); + val); /* Don't discard any error code or drop change flag */ if (ret == 0 || err < 0) @@ -498,12 +497,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); unsigned int reg = mc->reg; unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - int min = mc->min; - int max = mc->max; + int max = mc->max - mc->min; unsigned int mask = soc_mixer_mask(mc); - unsigned int invert = mc->invert; - unsigned int val, val_mask; + unsigned int val_mask = mask << mc->shift; + unsigned int val; int err, ret; ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], @@ -511,12 +508,8 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, if (ret) return ret; - if (invert) - val = (max - ucontrol->value.integer.value[0]) & mask; - else - val = ((ucontrol->value.integer.value[0] + min) & mask); - val_mask = mask << shift; - val = val << shift; + val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], + mask, mc->shift, max); err = snd_soc_component_update_bits(component, reg, val_mask, val); if (err < 0) @@ -525,16 +518,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, if (snd_soc_volsw_is_stereo(mc)) { ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], - mc->max - mc->min); + max); if (ret) return ret; - if (invert) - val = (max - ucontrol->value.integer.value[1]) & mask; - else - val = ((ucontrol->value.integer.value[1] + min) & mask); - val_mask = mask << shift; - val = val << shift; + val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[1], + mask, mc->shift, max); err = snd_soc_component_update_bits(component, rreg, val_mask, val); From 894a37c9de4b8a447ffa609d552e91ccb447c0a9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:52 +0000 Subject: [PATCH 625/651] ASoC: ops: Remove snd_soc_info_volsw_range() The only difference between snd_soc_info_volsw() and snd_soc_info_volsw_range() is that the later will not force a 2 value control to be of type integer if the name ends in "Volume". The kernel currently contains no users of snd_soc_info_volsw_range() that would return a boolean control with this code, so the risk is quite low and it seems appropriate that it should contain volume control detection. So remove snd_soc_info_volsw_range() and point its users at snd_soc_info_volsw(). Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc.h | 12 +++++------ sound/pci/hda/tas2781_hda_i2c.c | 2 +- sound/pci/hda/tas2781_hda_spi.c | 2 +- sound/soc/soc-ops.c | 36 +++------------------------------ sound/soc/soc-topology.c | 2 +- 5 files changed, 11 insertions(+), 43 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index d73fe26de166..b310f2c599f8 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -65,7 +65,7 @@ struct platform_device; .private_value = SOC_SINGLE_VALUE(reg, shift, 0, max, invert, 0) } #define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ - .info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \ + .info = snd_soc_info_volsw, .get = snd_soc_get_volsw_range, \ .put = snd_soc_put_volsw_range, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ @@ -90,7 +90,7 @@ struct platform_device; .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw_range, \ + .info = snd_soc_info_volsw, \ .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ @@ -116,7 +116,7 @@ struct platform_device; #define SOC_DOUBLE_R_RANGE(xname, reg_left, reg_right, xshift, xmin, \ xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ - .info = snd_soc_info_volsw_range, \ + .info = snd_soc_info_volsw, \ .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } @@ -164,7 +164,7 @@ struct platform_device; .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw_range, \ + .info = snd_soc_info_volsw, \ .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } @@ -266,7 +266,7 @@ struct platform_device; .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw_range, \ + .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\ @@ -569,8 +569,6 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index be9a90f643eb..50c5e5f26589 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -45,7 +45,7 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw_range, \ + .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = (unsigned long)&(struct soc_mixer_control) \ {.reg = xreg, .rreg = xreg, .shift = xshift, \ diff --git a/sound/pci/hda/tas2781_hda_spi.c b/sound/pci/hda/tas2781_hda_spi.c index 00676cbb2c8e..399f2e4c3b62 100644 --- a/sound/pci/hda/tas2781_hda_spi.c +++ b/sound/pci/hda/tas2781_hda_spi.c @@ -52,7 +52,7 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_READWRITE, \ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw_range, \ + .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = (unsigned long)&(struct soc_mixer_control) { \ .reg = xreg, .rreg = xreg, \ diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 888afdd23f84..1b52ba12df8d 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -169,12 +169,12 @@ static int soc_mixer_sx_mask(struct soc_mixer_control *mc) } /** - * snd_soc_info_volsw - single mixer info callback + * snd_soc_info_volsw - single mixer info callback with range. * @kcontrol: mixer control * @uinfo: control element information * - * Callback to provide information about a single mixer control, or a double - * mixer control that spans 2 registers. + * Callback to provide information, with a range, about a single mixer control, + * or a double mixer control that spans 2 registers. * * Returns 0 for success. */ @@ -450,36 +450,6 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); -/** - * snd_soc_info_volsw_range - single mixer info callback with range. - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information, within a range, about a single - * mixer control. - * - * returns 0 for success. - */ -int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int max; - - max = mc->max - mc->min; - if (mc->platform_max && mc->platform_max < max) - max = mc->platform_max; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = max; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range); - /** * snd_soc_put_volsw_range - single mixer put value callback with range. * @kcontrol: mixer control diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 2b86cc3311f7..9cbddfbbc556 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -132,7 +132,7 @@ static const struct snd_soc_tplg_kcontrol_ops io_ops[] = { {SND_SOC_TPLG_CTL_BYTES, snd_soc_bytes_get, snd_soc_bytes_put, snd_soc_bytes_info}, {SND_SOC_TPLG_CTL_RANGE, snd_soc_get_volsw_range, - snd_soc_put_volsw_range, snd_soc_info_volsw_range}, + snd_soc_put_volsw_range, snd_soc_info_volsw}, {SND_SOC_TPLG_CTL_VOLSW_XR_SX, snd_soc_get_xr_sx, snd_soc_put_xr_sx, snd_soc_info_xr_sx}, {SND_SOC_TPLG_CTL_STROBE, snd_soc_get_strobe, From fd7442561cfe9516b37cdb1d229dc1f811dc86cc Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:53 +0000 Subject: [PATCH 626/651] ASoC: ops: Remove snd_soc_get_volsw_range() With the addition of the soc_mixer_reg_to_ctl() helper it is now very clear that the only difference between snd_soc_get_volsw() and snd_soc_get_volsw_range() is that the former supports double controls with both values in the same register. As such we can combine both functions. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-10-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc.h | 10 ++++------ sound/soc/codecs/wm5110.c | 2 +- sound/soc/soc-ops.c | 42 +++------------------------------------ sound/soc/soc-topology.c | 2 +- 4 files changed, 9 insertions(+), 47 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index b310f2c599f8..b11c6cdb0201 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -65,7 +65,7 @@ struct platform_device; .private_value = SOC_SINGLE_VALUE(reg, shift, 0, max, invert, 0) } #define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ - .info = snd_soc_info_volsw, .get = snd_soc_get_volsw_range, \ + .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ .put = snd_soc_put_volsw_range, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ @@ -91,7 +91,7 @@ struct platform_device; SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ + .get = snd_soc_get_volsw, .put = snd_soc_put_volsw_range, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ @@ -117,7 +117,7 @@ struct platform_device; xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ + .get = snd_soc_get_volsw, .put = snd_soc_put_volsw_range, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \ @@ -165,7 +165,7 @@ struct platform_device; SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ + .get = snd_soc_get_volsw, .put = snd_soc_put_volsw_range, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_R_SX_TLV(xname, xreg, xrreg, xshift, xmin, xmax, tlv_array) \ @@ -571,8 +571,6 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); int snd_soc_limit_volume(struct snd_soc_card *card, const char *name, int max); int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 64eee0d2347d..c24b42c37578 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -477,7 +477,7 @@ static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol, */ snd_soc_dapm_mutex_lock(dapm); - ret = snd_soc_get_volsw_range(kcontrol, ucontrol); + ret = snd_soc_get_volsw(kcontrol, ucontrol); snd_soc_dapm_mutex_unlock(dapm); diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 1b52ba12df8d..fbda8e21c5a6 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -248,12 +248,12 @@ int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol, EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx); /** - * snd_soc_get_volsw - single mixer get callback + * snd_soc_get_volsw - single mixer get callback with range * @kcontrol: mixer control * @ucontrol: control element information * - * Callback to get the value of a single mixer control, or a double mixer - * control that spans 2 registers. + * Callback to get the value, within a range, of a single mixer control, or a + * double mixer control that spans 2 registers. * * Returns 0 for success. */ @@ -506,42 +506,6 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); -/** - * snd_soc_get_volsw_range - single mixer get callback with range - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to get the value, within a range, of a single mixer control. - * - * Returns 0 for success. - */ -int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int max = mc->max - mc->min; - unsigned int mask = soc_mixer_mask(mc); - unsigned int reg_val; - int val; - - reg_val = snd_soc_component_read(component, mc->reg); - val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); - - ucontrol->value.integer.value[0] = val; - - if (snd_soc_volsw_is_stereo(mc)) { - reg_val = snd_soc_component_read(component, mc->rreg); - val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); - - ucontrol->value.integer.value[1] = val; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); - static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 9cbddfbbc556..3c988925c512 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -131,7 +131,7 @@ static const struct snd_soc_tplg_kcontrol_ops io_ops[] = { snd_soc_put_enum_double, NULL}, {SND_SOC_TPLG_CTL_BYTES, snd_soc_bytes_get, snd_soc_bytes_put, snd_soc_bytes_info}, - {SND_SOC_TPLG_CTL_RANGE, snd_soc_get_volsw_range, + {SND_SOC_TPLG_CTL_RANGE, snd_soc_get_volsw, snd_soc_put_volsw_range, snd_soc_info_volsw}, {SND_SOC_TPLG_CTL_VOLSW_XR_SX, snd_soc_get_xr_sx, snd_soc_put_xr_sx, snd_soc_info_xr_sx}, From 7d5df968f95cee274740d5fa42e0798ffb59bd38 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:54 +0000 Subject: [PATCH 627/651] ASoC: ops: Remove snd_soc_put_volsw_range() With the addition of the soc_mixer_ctl_to_reg() helper it is now very clear that the only difference between snd_soc_put_volsw() and snd_soc_put_volsw_range() is that the former supports double controls with both values in the same register. As such we can combine both functions. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-11-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc.h | 10 +++---- sound/soc/codecs/wm5110.c | 2 +- sound/soc/soc-ops.c | 62 ++------------------------------------- sound/soc/soc-topology.c | 2 +- 4 files changed, 9 insertions(+), 67 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index b11c6cdb0201..952ed77b8c87 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -66,7 +66,7 @@ struct platform_device; #define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ - .put = snd_soc_put_volsw_range, \ + .put = snd_soc_put_volsw, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ @@ -91,7 +91,7 @@ struct platform_device; SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw, .put = snd_soc_put_volsw_range, \ + .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmin, xmax, xinvert, 0) } #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ @@ -117,7 +117,7 @@ struct platform_device; xmax, xinvert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw, .put = snd_soc_put_volsw_range, \ + .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \ @@ -165,7 +165,7 @@ struct platform_device; SNDRV_CTL_ELEM_ACCESS_READWRITE,\ .tlv.p = (tlv_array), \ .info = snd_soc_info_volsw, \ - .get = snd_soc_get_volsw, .put = snd_soc_put_volsw_range, \ + .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, \ xshift, xmin, xmax, xinvert) } #define SOC_DOUBLE_R_SX_TLV(xname, xreg, xrreg, xshift, xmin, xmax, tlv_array) \ @@ -569,8 +569,6 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); int snd_soc_limit_volume(struct snd_soc_card *card, const char *name, int max); int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index c24b42c37578..212eca675f27 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -497,7 +497,7 @@ static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol, */ snd_soc_dapm_mutex_lock(dapm); - ret = snd_soc_put_volsw_range(kcontrol, ucontrol); + ret = snd_soc_put_volsw(kcontrol, ucontrol); snd_soc_dapm_mutex_unlock(dapm); diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index fbda8e21c5a6..d26d9e050af1 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -289,12 +289,12 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, EXPORT_SYMBOL_GPL(snd_soc_get_volsw); /** - * snd_soc_put_volsw - single mixer put callback + * snd_soc_put_volsw - single mixer put callback with range * @kcontrol: mixer control * @ucontrol: control element information * - * Callback to set the value of a single mixer control, or a double mixer - * control that spans 2 registers. + * Callback to set the value , within a range, of a single mixer control, or + * a double mixer control that spans 2 registers. * * Returns 0 for success. */ @@ -450,62 +450,6 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); -/** - * snd_soc_put_volsw_range - single mixer put value callback with range. - * @kcontrol: mixer control - * @ucontrol: control element information - * - * Callback to set the value, within a range, for a single mixer control. - * - * Returns 0 for success. - */ -int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - int max = mc->max - mc->min; - unsigned int mask = soc_mixer_mask(mc); - unsigned int val_mask = mask << mc->shift; - unsigned int val; - int err, ret; - - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], - mc->max - mc->min); - if (ret) - return ret; - - val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], - mask, mc->shift, max); - - err = snd_soc_component_update_bits(component, reg, val_mask, val); - if (err < 0) - return err; - ret = err; - - if (snd_soc_volsw_is_stereo(mc)) { - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], - max); - if (ret) - return ret; - - val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[1], - mask, mc->shift, max); - - err = snd_soc_component_update_bits(component, rreg, val_mask, - val); - /* Don't discard any error code or drop change flag */ - if (ret == 0 || err < 0) - ret = err; - } - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); - static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 3c988925c512..7b0b8531bb32 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -132,7 +132,7 @@ static const struct snd_soc_tplg_kcontrol_ops io_ops[] = { {SND_SOC_TPLG_CTL_BYTES, snd_soc_bytes_get, snd_soc_bytes_put, snd_soc_bytes_info}, {SND_SOC_TPLG_CTL_RANGE, snd_soc_get_volsw, - snd_soc_put_volsw_range, snd_soc_info_volsw}, + snd_soc_put_volsw, snd_soc_info_volsw}, {SND_SOC_TPLG_CTL_VOLSW_XR_SX, snd_soc_get_xr_sx, snd_soc_put_xr_sx, snd_soc_info_xr_sx}, {SND_SOC_TPLG_CTL_STROBE, snd_soc_get_strobe, From 9dfcafe2037acc14265cead8d8a937a8bc4e01d8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:55 +0000 Subject: [PATCH 628/651] ASoC: ops: Factor out common code from info callbacks snd_soc_info_volsw() and snd_soc_info_volsw_sx() do very similar things, and have a lot of code in common. Already this is causing some issues as the detection of volume controls has been fixed in the normal callback but not the sx callback. Factor out a new helper containing the common code and leave the function specific bits behind in each callback. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-12-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 64 ++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index d26d9e050af1..29537dd3a063 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -168,6 +168,30 @@ static int soc_mixer_sx_mask(struct soc_mixer_control *mc) return GENMASK(fls(mc->min + mc->max) - 2, 0); } +static int soc_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo, + struct soc_mixer_control *mc, int max) +{ + if (mc->platform_max && mc->platform_max < max) + max = mc->platform_max; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + + if (max == 1) { + /* Even two value controls ending in Volume should be integer */ + const char *vol_string = strstr(kcontrol->id.name, " Volume"); + + if (!vol_string || strcmp(vol_string, " Volume")) + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + } + + uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = max; + + return 0; +} + /** * snd_soc_info_volsw - single mixer info callback with range. * @kcontrol: mixer control @@ -183,29 +207,8 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - const char *vol_string = NULL; - int max; - max = uinfo->value.integer.max = mc->max - mc->min; - if (mc->platform_max && mc->platform_max < max) - max = mc->platform_max; - - if (max == 1) { - /* Even two value controls ending in Volume should always be integer */ - vol_string = strstr(kcontrol->id.name, " Volume"); - if (vol_string && !strcmp(vol_string, " Volume")) - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - else - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - } else { - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - } - - uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = max; - - return 0; + return soc_info_volsw(kcontrol, uinfo, mc, mc->max - mc->min); } EXPORT_SYMBOL_GPL(snd_soc_info_volsw); @@ -227,23 +230,8 @@ int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - int max; - if (mc->platform_max) - max = mc->platform_max; - else - max = mc->max; - - if (max == 1 && !strstr(kcontrol->id.name, " Volume")) - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - else - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - - uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = max; - - return 0; + return soc_info_volsw(kcontrol, uinfo, mc, mc->max); } EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx); From 318e8794e05ca1879441a602e78c74f9d7e18309 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 18 Mar 2025 17:14:56 +0000 Subject: [PATCH 629/651] ASoC: ops: Factor out common code from put callbacks There are only two differences between snd_soc_put_volsw() and snd_soc_put_volsw_sx(). The maximum field is handled differently, and snd_soc_put_volsw() supports double controls with both values in the same register. Factor out the common code into a new helper and pass in the appropriate max value such that it is handled correctly for each control. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250318171459.3203730-13-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 138 +++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 85 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 29537dd3a063..0b62ffb2e222 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -192,6 +192,57 @@ static int soc_info_volsw(struct snd_kcontrol *kcontrol, return 0; } +static int soc_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, + struct soc_mixer_control *mc, int mask, int max) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + unsigned int val1, val_mask; + unsigned int val2 = 0; + bool double_r = false; + int ret; + + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max); + if (ret) + return ret; + + val1 = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], + mask, mc->shift, max); + val_mask = mask << mc->shift; + + if (snd_soc_volsw_is_stereo(mc)) { + ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max); + if (ret) + return ret; + + if (mc->reg == mc->rreg) { + val1 |= soc_mixer_ctl_to_reg(mc, + ucontrol->value.integer.value[1], + mask, mc->rshift, max); + val_mask |= mask << mc->rshift; + } else { + val2 = soc_mixer_ctl_to_reg(mc, + ucontrol->value.integer.value[1], + mask, mc->shift, max); + double_r = true; + } + } + + ret = snd_soc_component_update_bits(component, mc->reg, val_mask, val1); + if (ret < 0) + return ret; + + if (double_r) { + int err = snd_soc_component_update_bits(component, mc->rreg, + val_mask, val2); + /* Don't drop change flag */ + if (err) + return err; + } + + return ret; +} + /** * snd_soc_info_volsw - single mixer info callback with range. * @kcontrol: mixer control @@ -289,57 +340,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw); int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - int max = mc->max - mc->min; unsigned int mask = soc_mixer_mask(mc); - int err, ret; - bool type_2r = false; - unsigned int val2 = 0; - unsigned int val, val_mask; - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max); - if (ret) - return ret; - - val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], - mask, mc->shift, max); - val_mask = mask << mc->shift; - - if (snd_soc_volsw_is_stereo(mc)) { - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max); - if (ret) - return ret; - - if (reg == reg2) { - val |= soc_mixer_ctl_to_reg(mc, - ucontrol->value.integer.value[1], - mask, mc->rshift, max); - val_mask |= mask << mc->rshift; - } else { - val2 = soc_mixer_ctl_to_reg(mc, - ucontrol->value.integer.value[1], - mask, mc->shift, max); - type_2r = true; - } - } - err = snd_soc_component_update_bits(component, reg, val_mask, val); - if (err < 0) - return err; - ret = err; - - if (type_2r) { - err = snd_soc_component_update_bits(component, reg2, val_mask, - val2); - /* Don't discard any error code or drop change flag */ - if (ret == 0 || err < 0) - ret = err; - } - - return ret; + return soc_put_volsw(kcontrol, ucontrol, mc, mask, mc->max - mc->min); } EXPORT_SYMBOL_GPL(snd_soc_put_volsw); @@ -393,48 +398,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx); int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; - unsigned int val, val_mask; unsigned int mask = soc_mixer_sx_mask(mc); - int err = 0; - int ret; - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], mc->max); - if (ret) - return ret; - - val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0], - mask, mc->shift, mc->max); - val_mask = mask << mc->shift; - - err = snd_soc_component_update_bits(component, reg, val_mask, val); - if (err < 0) - return err; - ret = err; - - if (snd_soc_volsw_is_stereo(mc)) { - ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], - mc->max); - if (ret) - return ret; - - val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[1], - mask, mc->rshift, mc->max); - val_mask = mask << mc->rshift; - - err = snd_soc_component_update_bits(component, reg2, val_mask, - val); - - /* Don't discard any error code or drop change flag */ - if (ret == 0 || err < 0) - ret = err; - } - - return ret; + return soc_put_volsw(kcontrol, ucontrol, mc, mask, mc->max); } EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); From 83eddf0116b09186f909bc643f2093f266f204ea Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:28 +0100 Subject: [PATCH 630/651] irqdomain: sound: Switch to irq_domain_create_linear() irq_domain_add_linear() is going away as being obsolete now. Switch to the preferred irq_domain_create_linear(). That differs in the first parameter: It takes more generic struct fwnode_handle instead of struct device_node. Therefore, of_fwnode_handle() is added around the parameter. Note some of the users can likely use dev->fwnode directly instead of indirect of_fwnode_handle(dev->of_node). But dev->fwnode is not guaranteed to be set for all, so this has to be investigated on case to case basis (by people who can actually test with the HW). Signed-off-by: Jiri Slaby (SUSE) Cc: Liam Girdwood Cc: Mark Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Prasad Kumpatla Cc: linux-sound@vger.kernel.org Link: https://patch.msgid.link/20250319092951.37667-36-jirislaby@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd937x.c | 2 +- sound/soc/codecs/wcd938x.c | 2 +- sound/soc/codecs/wcd939x.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c index ff8bb01edf42..dd2045a5d26d 100644 --- a/sound/soc/codecs/wcd937x.c +++ b/sound/soc/codecs/wcd937x.c @@ -2480,7 +2480,7 @@ static const struct irq_domain_ops wcd_domain_ops = { static int wcd937x_irq_init(struct wcd937x_priv *wcd, struct device *dev) { - wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL); + wcd->virq = irq_domain_create_linear(NULL, 1, &wcd_domain_ops, NULL); if (!(wcd->virq)) { dev_err(dev, "%s: Failed to add IRQ domain\n", __func__); return -EINVAL; diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index b536e8bdc5a7..1ae498c32391 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -3025,7 +3025,7 @@ static const struct irq_domain_ops wcd_domain_ops = { static int wcd938x_irq_init(struct wcd938x_priv *wcd, struct device *dev) { - wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL); + wcd->virq = irq_domain_create_linear(NULL, 1, &wcd_domain_ops, NULL); if (!(wcd->virq)) { dev_err(dev, "%s: Failed to add IRQ domain\n", __func__); return -EINVAL; diff --git a/sound/soc/codecs/wcd939x.c b/sound/soc/codecs/wcd939x.c index 4a417a92514d..0a87a79772da 100644 --- a/sound/soc/codecs/wcd939x.c +++ b/sound/soc/codecs/wcd939x.c @@ -2975,7 +2975,7 @@ static const struct irq_domain_ops wcd_domain_ops = { static int wcd939x_irq_init(struct wcd939x_priv *wcd, struct device *dev) { - wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL); + wcd->virq = irq_domain_create_linear(NULL, 1, &wcd_domain_ops, NULL); if (!(wcd->virq)) { dev_err(dev, "%s: Failed to add IRQ domain\n", __func__); return -EINVAL; From 1e3cd64a29baa874b89180ac0744178ecb00f3cd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 19 Mar 2025 17:51:21 +0000 Subject: [PATCH 631/651] ASoC: ops: Factor out common code from get callbacks There are only two differences between snd_soc_get_volsw() and snd_soc_get_volsw_sx(). The maximum field is handled differently, and snd_soc_get_volsw() supports double controls with both values in the same register. Factor out the common code into a new helper and pass in the appropriate max value such that it is handled correctly for each control. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250319175123.3835849-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 68 +++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 0b62ffb2e222..1d7c28993a63 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -243,6 +243,33 @@ static int soc_put_volsw(struct snd_kcontrol *kcontrol, return ret; } +static int soc_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, + struct soc_mixer_control *mc, int mask, int max) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + unsigned int reg_val; + int val; + + reg_val = snd_soc_component_read(component, mc->reg); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); + + ucontrol->value.integer.value[0] = val; + + if (snd_soc_volsw_is_stereo(mc)) { + if (mc->reg == mc->rreg) { + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, max); + } else { + reg_val = snd_soc_component_read(component, mc->rreg); + val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); + } + + ucontrol->value.integer.value[1] = val; + } + + return 0; +} + /** * snd_soc_info_volsw - single mixer info callback with range. * @kcontrol: mixer control @@ -299,31 +326,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx); int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - int max = mc->max - mc->min; unsigned int mask = soc_mixer_mask(mc); - unsigned int reg_val; - int val; - reg_val = snd_soc_component_read(component, mc->reg); - val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); - - ucontrol->value.integer.value[0] = val; - - if (snd_soc_volsw_is_stereo(mc)) { - if (mc->reg == mc->rreg) { - val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, max); - } else { - reg_val = snd_soc_component_read(component, mc->rreg); - val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max); - } - - ucontrol->value.integer.value[1] = val; - } - - return 0; + return soc_get_volsw(kcontrol, ucontrol, mc, mask, mc->max - mc->min); } EXPORT_SYMBOL_GPL(snd_soc_get_volsw); @@ -361,28 +368,11 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw); int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int reg2 = mc->rreg; unsigned int mask = soc_mixer_sx_mask(mc); - unsigned int reg_val; - int val; - reg_val = snd_soc_component_read(component, reg); - val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, mc->max); - - ucontrol->value.integer.value[0] = val; - - if (snd_soc_volsw_is_stereo(mc)) { - reg_val = snd_soc_component_read(component, reg2); - val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, mc->max); - - ucontrol->value.integer.value[1] = val; - } - - return 0; + return soc_get_volsw(kcontrol, ucontrol, mc, mask, mc->max); } EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx); From 94dfe71f0a4eb0d7df542560c22961dedf45141d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 19 Mar 2025 17:51:22 +0000 Subject: [PATCH 632/651] ASoC: ops: Remove some unnecessary local variables Remove some local variables that aren't adding much in terms of clarity or space saving. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250319175123.3835849-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 1d7c28993a63..3ac5b3a62c81 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -664,9 +664,6 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; unsigned int regwmask = GENMASK(regwshift - 1, 0); unsigned long mask = GENMASK(mc->nbits - 1, 0); - unsigned int invert = mc->invert; - long min = mc->min; - long max = mc->max; long val = 0; unsigned int i; @@ -676,10 +673,10 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, val |= (regval & regwmask) << (regwshift * (regcount - i - 1)); } val &= mask; - if (min < 0 && val > max) + if (mc->min < 0 && val > mc->max) val |= ~mask; - if (invert) - val = max - val; + if (mc->invert) + val = mc->max - val; ucontrol->value.integer.value[0] = val; return 0; @@ -711,16 +708,14 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; unsigned int regwmask = GENMASK(regwshift - 1, 0); unsigned long mask = GENMASK(mc->nbits - 1, 0); - unsigned int invert = mc->invert; - long max = mc->max; long val = ucontrol->value.integer.value[0]; int ret = 0; unsigned int i; if (val < mc->min || val > mc->max) return -EINVAL; - if (invert) - val = max - val; + if (mc->invert) + val = mc->max - val; val &= mask; for (i = 0; i < regcount; i++) { unsigned int regval = (val >> (regwshift * (regcount - i - 1))) & @@ -755,17 +750,16 @@ int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int shift = mc->shift; - unsigned int mask = BIT(shift); unsigned int invert = mc->invert != 0; + unsigned int mask = BIT(mc->shift); unsigned int val; - val = snd_soc_component_read(component, reg); + val = snd_soc_component_read(component, mc->reg); val &= mask; - if (shift != 0 && val != 0) - val = val >> shift; + if (mc->shift != 0 && val != 0) + val = val >> mc->shift; + ucontrol->value.enumerated.item[0] = val ^ invert; return 0; @@ -788,19 +782,17 @@ int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int shift = mc->shift; - unsigned int mask = BIT(shift); - unsigned int invert = mc->invert != 0; unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; + unsigned int invert = mc->invert != 0; + unsigned int mask = BIT(mc->shift); unsigned int val1 = (strobe ^ invert) ? mask : 0; unsigned int val2 = (strobe ^ invert) ? 0 : mask; - int err; + int ret; - err = snd_soc_component_update_bits(component, reg, mask, val1); - if (err < 0) - return err; + ret = snd_soc_component_update_bits(component, mc->reg, mask, val1); + if (ret < 0) + return ret; - return snd_soc_component_update_bits(component, reg, mask, val2); + return snd_soc_component_update_bits(component, mc->reg, mask, val2); } EXPORT_SYMBOL_GPL(snd_soc_put_strobe); From 502a668fad12b6ca10bcbb615d62e61d3b669c99 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 19 Mar 2025 17:51:23 +0000 Subject: [PATCH 633/651] ASoC: ops: Apply platform_max after deciding control type It doesn't really make sense for the type of a control to change based on the platform_max field. platform_max allows a specific system to limit values of a control for safety but it seems reasonable the control type should remain the same between different systems, even if it is restricted down to just two values. Move the application of platform_max to after control type determination in soc_info_volsw(). Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250319175123.3835849-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 3ac5b3a62c81..8d4dd11c9aef 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -172,9 +172,6 @@ static int soc_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo, struct soc_mixer_control *mc, int max) { - if (mc->platform_max && mc->platform_max < max) - max = mc->platform_max; - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; if (max == 1) { @@ -185,6 +182,9 @@ static int soc_info_volsw(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; } + if (mc->platform_max && mc->platform_max < max) + max = mc->platform_max; + uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = max; From ee3d1f09e04643b1b48bd894de1de3c600a01c05 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 20 Mar 2025 11:57:20 +0100 Subject: [PATCH 634/651] ALSA: oxygen: Fix dependency on CONFIG_PM_SLEEP The conversion to EXPORT_SIMPLE_DEV_PM_OPS() also replaced the pm ops assignment with pm_ptr() macro, but this made difference from the original code; it had conditional with ifdef CONFIG_PM_SLEEP, while we have now with CONFIG_PM, instead. This seems causing build errors with randomconfig. For fixing the inconsistency, replace pm_ptr() with pm_sleep_ptr(). Fixes: 5ea0a2206b58 ("ALSA: oxygen: Convert to EXPORT_SIMPLE_DEV_PM_OPS()") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503201853.7kB0BPRw-lkp@intel.com/ Link: https://patch.msgid.link/20250320105721.10789-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 2 +- sound/pci/oxygen/se6x.c | 2 +- sound/pci/oxygen/virtuoso.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 6d0deea47ee6..ff7439634d76 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -855,7 +855,7 @@ static struct pci_driver oxygen_driver = { .id_table = oxygen_ids, .probe = generic_oxygen_probe, .driver = { - .pm = pm_ptr(&oxygen_pci_pm), + .pm = pm_sleep_ptr(&oxygen_pci_pm), }, }; diff --git a/sound/pci/oxygen/se6x.c b/sound/pci/oxygen/se6x.c index c1bb9dd1cd54..9d009015d97e 100644 --- a/sound/pci/oxygen/se6x.c +++ b/sound/pci/oxygen/se6x.c @@ -138,7 +138,7 @@ static struct pci_driver se6x_driver = { .id_table = se6x_ids, .probe = se6x_probe, .driver = { - .pm = pm_ptr(&oxygen_pci_pm), + .pm = pm_sleep_ptr(&oxygen_pci_pm), }, .shutdown = oxygen_pci_shutdown, }; diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 0bfe6d8dde3e..ded62199da7f 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -83,7 +83,7 @@ static struct pci_driver xonar_driver = { .id_table = xonar_ids, .probe = xonar_probe, .driver = { - .pm = pm_ptr(&oxygen_pci_pm), + .pm = pm_sleep_ptr(&oxygen_pci_pm), }, .shutdown = oxygen_pci_shutdown, }; From fd9582998b9a82ef53a34756de8a1fb86abac972 Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Wed, 19 Mar 2025 15:20:55 +0100 Subject: [PATCH 635/651] of: Add of_property_read_u16_index There is an of_property_read_u32_index and of_property_read_u64_index. This patch adds a similar helper for u16. Signed-off-by: Ernest Van Hoecke Signed-off-by: Francesco Dolcini Reviewed-by: Rob Herring (Arm) Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250319142059.46692-2-francesco@dolcini.it Signed-off-by: Mark Brown --- drivers/of/property.c | 33 +++++++++++++++++++++++++++++++++ include/linux/of.h | 9 +++++++++ 2 files changed, 42 insertions(+) diff --git a/drivers/of/property.c b/drivers/of/property.c index 208d922cc24c..c1feb631e383 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -147,6 +147,39 @@ static void *of_find_property_value_of_size(const struct device_node *np, return prop->value; } +/** + * of_property_read_u16_index - Find and read a u16 from a multi-value property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @index: index of the u16 in the list of values + * @out_value: pointer to return value, modified only if no error. + * + * Search for a property in a device node and read nth 16-bit value from + * it. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * The out_value is modified only if a valid u16 value can be decoded. + */ +int of_property_read_u16_index(const struct device_node *np, + const char *propname, + u32 index, u16 *out_value) +{ + const u16 *val = of_find_property_value_of_size(np, propname, + ((index + 1) * sizeof(*out_value)), + 0, NULL); + + if (IS_ERR(val)) + return PTR_ERR(val); + + *out_value = be16_to_cpup(((__be16 *)val) + index); + return 0; +} +EXPORT_SYMBOL_GPL(of_property_read_u16_index); + /** * of_property_read_u32_index - Find and read a u32 from a multi-value property. * diff --git a/include/linux/of.h b/include/linux/of.h index eaf0e2a2b75c..5e52d90f6408 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -314,6 +314,9 @@ extern struct property *of_find_property(const struct device_node *np, extern bool of_property_read_bool(const struct device_node *np, const char *propname); extern int of_property_count_elems_of_size(const struct device_node *np, const char *propname, int elem_size); +extern int of_property_read_u16_index(const struct device_node *np, + const char *propname, + u32 index, u16 *out_value); extern int of_property_read_u32_index(const struct device_node *np, const char *propname, u32 index, u32 *out_value); @@ -627,6 +630,12 @@ static inline int of_property_count_elems_of_size(const struct device_node *np, return -ENOSYS; } +static inline int of_property_read_u16_index(const struct device_node *np, + const char *propname, u32 index, u16 *out_value) +{ + return -ENOSYS; +} + static inline int of_property_read_u32_index(const struct device_node *np, const char *propname, u32 index, u32 *out_value) { From 2aa853248b6b6c76b9dd82353e45a4283f9c53ec Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Wed, 19 Mar 2025 15:20:56 +0100 Subject: [PATCH 636/651] ASoC: wm8904: Don't touch GPIO configs set to 0xFFFF When updating the GPIO registers, do nothing for all fields of gpio_cfg that are "0xFFFF". This "do nothing" flag used to be 0 to easily check whether the gpio_cfg field was actually set inside pdata or left empty (default). However, 0 is a valid configuration for these registers, while 0xFFFF is not. With this change, users can explicitly set them to 0. Not setting gpio_cfg in the platform data will now lead to setting all GPIO registers to 0 instead of leaving them unset. No one is using this platform data with this codec. The change gets the driver ready to properly set gpio_cfg from the DT. Datasheet: https://statics.cirrus.com/pubs/proDatasheet/WM8904_Rev4.1.pdf Signed-off-by: Ernest Van Hoecke Signed-off-by: Francesco Dolcini Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250319142059.46692-3-francesco@dolcini.it Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index aef82532f8cf..2082ff12d336 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2270,7 +2270,8 @@ static int wm8904_i2c_probe(struct i2c_client *i2c) /* Apply configuration from the platform data. */ if (wm8904->pdata) { for (i = 0; i < WM8904_GPIO_REGS; i++) { - if (!wm8904->pdata->gpio_cfg[i]) + /* 0xFFFF in this config means "don't touch" */ + if (wm8904->pdata->gpio_cfg[i] == 0xffff) continue; regmap_update_bits(wm8904->regmap, From bd552e937fc80faa70007f7a4cbbf7edd5a6629a Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Wed, 19 Mar 2025 15:20:57 +0100 Subject: [PATCH 637/651] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support Add two properties to select the IN1L/DMICDAT1 and IN2R/DMICDAT2 functionality: - wlf,in1l-as-dmicdat1 - wlf,in1r-as-dmicdat2 Add a property to describe the GPIO configuration registers, that can be used to set the four multifunction pins: - wlf,gpio-cfg Add a property to describe the mic bias control registers: - wlf,micbias-cfg Add two properties to describe the Dynamic Range Controller (DRC), allowing multiple named configurations where each config sets the 4 DRC registers (R40-R43): - wlf,drc-cfg-regs - wlf,drc-cfg-names Add three properties to describe the equalizer (ReTune Mobile), allowing multiple named configurations (associated with a samplerate) that set the 24 (R134-R157) EQ registers: - wlf,retune-mobile-cfg-regs - wlf,retune-mobile-cfg-hz - wlf,retune-mobile-cfg-rates The set of names and configurations for DRC and ReTune Mobile are specified by system integrators. The names are exposed directly to userspace as options that can be selected at runtime. Adding the DRC and ReTune Mobile data to the DT eases the transition from pdata, which has handled them this way for over a decade. The parameters filled in here are almost certainly specific tuning for the hardware so it makes sense to ship them with the hardware description. Datasheet: https://statics.cirrus.com/pubs/proDatasheet/WM8904_Rev4.1.pdf Signed-off-by: Ernest Van Hoecke Signed-off-by: Francesco Dolcini Reviewed-by: Charles Keepax Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250319142059.46692-4-francesco@dolcini.it Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/wlf,wm8904.yaml | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml index 329260cf0fa0..3029a868e5e1 100644 --- a/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml +++ b/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml @@ -38,6 +38,82 @@ properties: DCVDD-supply: true MICVDD-supply: true + wlf,in1l-as-dmicdat1: + type: boolean + description: + Use IN1L/DMICDAT1 as DMICDAT1, enabling the DMIC input path. + Can be used separately or together with wlf,in1r-as-dmicdat2. + + wlf,in1r-as-dmicdat2: + type: boolean + description: + Use IN1R/DMICDAT2 as DMICDAT2, enabling the DMIC input path. + Can be used separately or together with wlf,in1l-as-dmicdat1. + + wlf,gpio-cfg: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 4 + maxItems: 4 + description: + Default register values for R121/122/123/124 (GPIO Control). + If any entry has the value 0xFFFF, the related register won't be set. + default: [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF] + + wlf,micbias-cfg: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 2 + maxItems: 2 + description: + Default register values for R6/R7 (Mic Bias Control). + default: [0, 0] + + wlf,drc-cfg-names: + $ref: /schemas/types.yaml#/definitions/string-array + description: + List of strings for the available DRC modes. + If absent, DRC is disabled. + + wlf,drc-cfg-regs: + $ref: /schemas/types.yaml#/definitions/uint16-matrix + description: + Sets of default register values for R40/41/42/43 (DRC). + Each set corresponds to a DRC mode, so the number of sets should equal + the length of wlf,drc-cfg-names. + If absent, DRC is disabled. + items: + minItems: 4 + maxItems: 4 + + wlf,retune-mobile-cfg-names: + $ref: /schemas/types.yaml#/definitions/non-unique-string-array + description: + List of strings for the available retune modes. + If absent, retune is disabled. + + wlf,retune-mobile-cfg-hz: + description: + The list must be the same length as wlf,retune-mobile-cfg-names. + If absent, retune is disabled. + + wlf,retune-mobile-cfg-regs: + $ref: /schemas/types.yaml#/definitions/uint16-matrix + description: + Sets of default register values for R134/.../157 (EQ). + Each set corresponds to a retune mode, so the number of sets should equal + the length of wlf,retune-mobile-cfg-names. + If absent, retune is disabled. + items: + minItems: 24 + maxItems: 24 + +dependencies: + wlf,drc-cfg-names: [ 'wlf,drc-cfg-regs' ] + wlf,drc-cfg-regs: [ 'wlf,drc-cfg-names' ] + + wlf,retune-mobile-cfg-names: [ 'wlf,retune-mobile-cfg-hz', 'wlf,retune-mobile-cfg-regs' ] + wlf,retune-mobile-cfg-regs: [ 'wlf,retune-mobile-cfg-names', 'wlf,retune-mobile-cfg-hz' ] + wlf,retune-mobile-cfg-hz: [ 'wlf,retune-mobile-cfg-names', 'wlf,retune-mobile-cfg-regs' ] + required: - compatible - reg @@ -70,5 +146,58 @@ examples: DBVDD-supply = <®_1p8v>; DCVDD-supply = <®_1p8v>; MICVDD-supply = <®_1p8v>; + + wlf,drc-cfg-names = "default", "peaklimiter", "tradition", "soft", + "music"; + /* + * Config registers per name, respectively: + * KNEE_IP = 0, KNEE_OP = 0, HI_COMP = 1, LO_COMP = 1 + * KNEE_IP = -24, KNEE_OP = -6, HI_COMP = 1/4, LO_COMP = 1 + * KNEE_IP = -42, KNEE_OP = -3, HI_COMP = 0, LO_COMP = 1 + * KNEE_IP = -45, KNEE_OP = -9, HI_COMP = 1/8, LO_COMP = 1 + * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1 + */ + wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>, + /bits/ 16 <0x04af 0x324b 0x0010 0x0408>, + /bits/ 16 <0x04af 0x324b 0x0028 0x0704>, + /bits/ 16 <0x04af 0x324b 0x0018 0x078c>, + /bits/ 16 <0x04af 0x324b 0x0010 0x050e>; + + /* GPIO1 = DMIC_CLK, don't touch others */ + wlf,gpio-cfg = <0x0018>, <0xffff>, <0xffff>, <0xffff>; + + /* Use IN1R as DMICDAT2, leave IN1L as an analog input path */ + wlf,in1r-as-dmicdat2; + + wlf,retune-mobile-cfg-names = "bassboost", "bassboost", "treble"; + wlf,retune-mobile-cfg-hz = <48000>, <44100>, <48000>; + /* + * Config registers per name, respectively: + * EQ_ENA, 100 Hz, 300 Hz, 875 Hz, 2400 Hz, 6900 Hz + * 1, +6 dB, +3 dB, 0 dB, 0 dB, 0 dB + * 1, +6 dB, +3 dB, 0 dB, 0 dB, 0 dB + * 1, -2 dB, -2 dB, 0 dB, 0 dB, +3 dB + * Each one uses the defaults for ReTune Mobile registers 140-157 + */ + wlf,retune-mobile-cfg-regs = /bits/ 16 <0x1 0x12 0xf 0xc 0xc 0xc + 0x0fca 0x0400 0x00d8 0x1eb5 + 0xf145 0x0bd5 0x0075 0x1c58 + 0xf3d3 0x0a54 0x0568 0x168e + 0xf829 0x07ad 0x1103 0x0564 + 0x0559 0x4000>, + + /bits/ 16 <0x1 0x12 0xf 0xc 0xc 0xc + 0x0fca 0x0400 0x00d8 0x1eb5 + 0xf145 0x0bd5 0x0075 0x1c58 + 0xf3d3 0x0a54 0x0568 0x168e + 0xf829 0x07ad 0x1103 0x0564 + 0x0559 0x4000>, + + /bits/ 16 <0x1 0xa 0xa 0xc 0xc 0xf + 0x0fca 0x0400 0x00d8 0x1eb5 + 0xf145 0x0bd5 0x0075 0x1c58 + 0xf3d3 0x0a54 0x0568 0x168e + 0xf829 0x07ad 0x1103 0x0564 + 0x0559 0x4000>; }; }; From afe66ef965317381fd2894c2eba144b38b791910 Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Wed, 19 Mar 2025 15:20:58 +0100 Subject: [PATCH 638/651] ASoC: wm8904: get platform data from DT Read in optional codec-specific properties from the device tree. The platform_data structure is not populated when using device trees. This change parses optional dts properties to populate it. - wlf,in1l-as-dmicdat1 - wlf,in1r-as-dmicdat2 - wlf,gpio-cfg - wlf,micbias-cfg - wlf,drc-cfg-regs - wlf,drc-cfg-names - wlf,retune-mobile-cfg-regs - wlf,retune-mobile-cfg-names - wlf,retune-mobile-cfg-hz Datasheet: https://statics.cirrus.com/pubs/proDatasheet/WM8904_Rev4.1.pdf Signed-off-by: Ernest Van Hoecke Signed-off-by: Francesco Dolcini Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250319142059.46692-5-francesco@dolcini.it Signed-off-by: Mark Brown --- include/sound/wm8904.h | 3 + sound/soc/codecs/wm8904.c | 189 +++++++++++++++++++++++++++++++++++++- 2 files changed, 191 insertions(+), 1 deletion(-) diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h index 88ac1870510e..8b2c16b524f7 100644 --- a/include/sound/wm8904.h +++ b/include/sound/wm8904.h @@ -151,6 +151,9 @@ struct wm8904_pdata { int num_retune_mobile_cfgs; struct wm8904_retune_mobile_cfg *retune_mobile_cfgs; + bool in1l_as_dmicdat1; + bool in1r_as_dmicdat2; + u32 gpio_cfg[WM8904_GPIO_REGS]; u32 mic_cfg[WM8904_MIC_REGS]; }; diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 2082ff12d336..bac54c8e45a9 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2168,6 +2168,184 @@ static const struct of_device_id wm8904_of_match[] = { MODULE_DEVICE_TABLE(of, wm8904_of_match); #endif +/** + * wm8904_read_cfg_reg_arr() - Reads a subarray from a DT u16 array + * + * @np: pointer to the device_node struct + * @regs_property: DT property of interest + * @size: size of subarrays within the array + * @idx: index of the subarray of interest + * @out: output + * + * Helper to read a subarray from a DT uint16-array, + * divided into equally sized arrays of size `size` + * + * Subset starts at `idx * size` and is of size `size` + * + * Return: 0 on success, negative error code otherwise + */ +static int wm8904_read_cfg_reg_arr(const struct device_node *np, + const char * const regs_property, + int size, int idx, + u16 * const out) +{ + int i, offset, ret; + + offset = idx * size; + + for (i = 0; i < size; i++) { + ret = of_property_read_u16_index(np, regs_property, i + offset, &out[i]); + if (ret) + return ret; + } + return 0; +} + +static int wm8904_parse_retune_cfg_regs(const struct device_node *np, + struct wm8904_pdata *pdata, int cfg_idx) +{ + return wm8904_read_cfg_reg_arr(np, "wlf,retune-mobile-cfg-regs", + WM8904_EQ_REGS, cfg_idx, + &pdata->retune_mobile_cfgs[cfg_idx].regs[0]); +} + +static int wm8904_parse_drc_cfg_regs(const struct device_node *np, + struct wm8904_pdata *pdata, int cfg_idx) +{ + return wm8904_read_cfg_reg_arr(np, "wlf,drc-cfg-regs", + WM8904_DRC_REGS, cfg_idx, + &pdata->drc_cfgs[cfg_idx].regs[0]); +} + +static int wm8904_parse_drc_cfg_from_of(struct i2c_client *i2c, + struct wm8904_pdata *pdata) +{ + const struct device_node *np = i2c->dev.of_node; + int i, n_cfgs; + + n_cfgs = of_property_count_strings(np, "wlf,drc-cfg-names"); + if (n_cfgs == -EINVAL) + return 0; + + if (n_cfgs <= 0) { + dev_err(&i2c->dev, "Could not get wlf,drc-cfg-names length: %d", + n_cfgs); + return n_cfgs; + } + + pdata->drc_cfgs = devm_kzalloc(&i2c->dev, + n_cfgs * sizeof(struct wm8904_drc_cfg), + GFP_KERNEL); + if (!pdata->drc_cfgs) + return -ENOMEM; + + for (i = 0; i < n_cfgs; i++) { + if (wm8904_parse_drc_cfg_regs(np, pdata, i)) { + dev_err(&i2c->dev, + "Invalid 'wlf,drc-cfg-regs[%i,:]'\n", i); + return -EINVAL; + } + + if (of_property_read_string_index(np, "wlf,drc-cfg-names", i, + &pdata->drc_cfgs[i].name)) { + dev_err(&i2c->dev, + "Invalid 'wlf,drc-cfg-names[%i]'\n", i); + return -EINVAL; + } + } + + pdata->num_drc_cfgs = n_cfgs; + return 0; +} + +static int wm8904_parse_retune_cfg_from_of(struct i2c_client *i2c, + struct wm8904_pdata *pdata) +{ + const struct device_node *np = i2c->dev.of_node; + int i, n_cfgs; + + n_cfgs = of_property_count_strings(np, "wlf,retune-mobile-cfg-names"); + if (n_cfgs == -EINVAL) + return 0; + + if (n_cfgs <= 0) { + dev_err(&i2c->dev, + "Could not get wlf,retune-mobile-cfg-names length: %d", + n_cfgs); + return n_cfgs; + } + + pdata->retune_mobile_cfgs = devm_kzalloc(&i2c->dev, + n_cfgs * sizeof(struct wm8904_retune_mobile_cfg), + GFP_KERNEL); + if (!pdata->retune_mobile_cfgs) + return -ENOMEM; + + for (i = 0; i < n_cfgs; i++) { + if (wm8904_parse_retune_cfg_regs(np, pdata, i)) { + dev_err(&i2c->dev, + "Invalid 'wlf,retune-mobile-cfg-regs[%i,:]'\n", i); + return -EINVAL; + } + + if (of_property_read_u32_index(np, "wlf,retune-mobile-cfg-hz", i, + &pdata->retune_mobile_cfgs[i].rate)) { + dev_err(&i2c->dev, + "Invalid 'wlf,retune-mobile-cfg-hz[%i]'\n", i); + return -EINVAL; + } + + if (of_property_read_string_index(np, "wlf,retune-mobile-cfg-names", i, + &pdata->retune_mobile_cfgs[i].name)) { + dev_err(&i2c->dev, + "Invalid 'wlf,retune-mobile-cfg-names[%i]'\n", i); + return -EINVAL; + } + } + + pdata->num_retune_mobile_cfgs = n_cfgs; + return 0; +} + +static int wm8904_set_pdata_from_of(struct i2c_client *i2c, + struct wm8904_priv *wm8904) +{ + const struct device_node *np = i2c->dev.of_node; + struct wm8904_pdata *pdata; + int ret, i; + + pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->in1l_as_dmicdat1 = + of_property_read_bool(np, "wlf,in1l-as-dmicdat1"); + + pdata->in1r_as_dmicdat2 = + of_property_read_bool(np, "wlf,in1r-as-dmicdat2"); + + /* If absent, default to 0xFFFF for GPIO config (i.e.: don't set) */ + for (i = 0; i < WM8904_GPIO_REGS; i++) + pdata->gpio_cfg[i] = 0xFFFF; + + of_property_read_u32_array(np, "wlf,gpio-cfg", pdata->gpio_cfg, + ARRAY_SIZE(pdata->gpio_cfg)); + + of_property_read_u32_array(np, "wlf,micbias-cfg", pdata->mic_cfg, + ARRAY_SIZE(pdata->mic_cfg)); + + ret = wm8904_parse_drc_cfg_from_of(i2c, pdata); + if (ret) + return ret; + + ret = wm8904_parse_retune_cfg_from_of(i2c, pdata); + if (ret) + return ret; + + wm8904->pdata = pdata; + return 0; +} + static const struct i2c_device_id wm8904_i2c_id[]; static int wm8904_i2c_probe(struct i2c_client *i2c) @@ -2199,7 +2377,16 @@ static int wm8904_i2c_probe(struct i2c_client *i2c) wm8904->devtype = (uintptr_t)i2c_get_match_data(i2c); i2c_set_clientdata(i2c, wm8904); - wm8904->pdata = i2c->dev.platform_data; + + if (i2c->dev.of_node) { + ret = wm8904_set_pdata_from_of(i2c, wm8904); + if (ret) { + dev_err(&i2c->dev, "Failed to set platform data from of: %d\n", ret); + return ret; + } + } else { + wm8904->pdata = i2c->dev.platform_data; + } for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) wm8904->supplies[i].supply = wm8904_supply_names[i]; From b6612c8fc3a2c279196050ecc13c77a7863d83eb Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Wed, 19 Mar 2025 15:20:59 +0100 Subject: [PATCH 639/651] ASoC: wm8904: add DMIC support The WM8904 codec supports both ADC and DMIC inputs. Get input pin functionality from the platform data and add the necessary controls depending on the possible additional routing. The ADC and DMIC share the IN1L/DMICDAT1 and IN1R/DMICDAT2 pins. This leads to a few scenarios requiring different DAPM routing: - When both are connected to an analog input, only the ADC is used. - When one line is a DMIC and the other an analog input, the DMIC source is set from the platform data and a mux is added to select whether to use the ADC or DMIC. - When both are connected to a DMIC, another mux is added to this to select the DMIC source. Note that we still need to be able to select the ADC system for use with the IN2L, IN2R, IN3L and IN3R pins. Signed-off-by: Ernest Van Hoecke Signed-off-by: Francesco Dolcini Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20250319142059.46692-6-francesco@dolcini.it Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 125 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index bac54c8e45a9..1c49e600eb6f 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -844,6 +844,26 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, return 0; } +static const char * const dmic_text[] = { + "DMIC1", "DMIC2" +}; + +static SOC_ENUM_SINGLE_DECL(dmic_enum, WM8904_DIGITAL_MICROPHONE_0, + WM8904_DMIC_SRC_SHIFT, dmic_text); + +static const struct snd_kcontrol_new dmic_mux = + SOC_DAPM_ENUM("DMIC Mux", dmic_enum); + +static const char * const cin_text[] = { + "ADC", "DMIC" +}; + +static SOC_ENUM_SINGLE_DECL(cin_enum, WM8904_DIGITAL_MICROPHONE_0, + WM8904_DMIC_ENA_SHIFT, cin_text); + +static const struct snd_kcontrol_new cin_mux = + SOC_DAPM_ENUM("Capture Input", cin_enum); + static const char *input_mode_text[] = { "Single-Ended", "Differential Line", "Differential Mic" }; @@ -963,6 +983,15 @@ SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0), }; +static const struct snd_soc_dapm_widget wm8904_dmic_dapm_widgets[] = { +SND_SOC_DAPM_MUX("DMIC Mux", SND_SOC_NOPM, 0, 0, &dmic_mux), +}; + +static const struct snd_soc_dapm_widget wm8904_cin_dapm_widgets[] = { +SND_SOC_DAPM_MUX("Left Capture Input", SND_SOC_NOPM, 0, 0, &cin_mux), +SND_SOC_DAPM_MUX("Right Capture Input", SND_SOC_NOPM, 0, 0, &cin_mux), +}; + static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0), @@ -1101,12 +1130,45 @@ static const struct snd_soc_dapm_route adc_intercon[] = { { "AIFOUTR", NULL, "AIFOUTR Mux" }, { "ADCL", NULL, "CLK_DSP" }, - { "ADCL", NULL, "Left Capture PGA" }, - { "ADCR", NULL, "CLK_DSP" }, +}; + +/* No DMICs, always connect PGAs */ +static const struct snd_soc_dapm_route cin_nodmic_con[] = { + { "ADCL", NULL, "Left Capture PGA" }, { "ADCR", NULL, "Right Capture PGA" }, }; +/* DMIC system in use: mux between ADC and DMICDAT1, 2 or both */ +static const struct snd_soc_dapm_route cin_adc_dmic_con[] = { + { "Left Capture Input", "ADC", "Left Capture PGA" }, + { "Right Capture Input", "ADC", "Right Capture PGA" }, + + { "ADCL", NULL, "Left Capture Input" }, + { "ADCR", NULL, "Right Capture Input" }, +}; + +/* IN1L as DMICDAT1 */ +static const struct snd_soc_dapm_route cin_dmic1_con[] = { + { "Left Capture Input", "DMIC", "IN1L" }, + { "Right Capture Input", "DMIC", "IN1L" }, +}; + +/* IN1R as DMICDAT2 */ +static const struct snd_soc_dapm_route cin_dmic2_con[] = { + { "Left Capture Input", "DMIC", "IN1R" }, + { "Right Capture Input", "DMIC", "IN1R" }, +}; + +/* DMICDAT1 and DMICDAT2: mux between them, ADC still used for IN2 and IN3 */ +static const struct snd_soc_dapm_route cin_2dmics_con[] = { + { "DMIC Mux", "DMIC1", "IN1L" }, + { "DMIC Mux", "DMIC2", "IN1R" }, + + { "Left Capture Input", "DMIC", "DMIC Mux" }, + { "Right Capture Input", "DMIC", "DMIC Mux" }, +}; + static const struct snd_soc_dapm_route dac_intercon[] = { { "DACL Mux", "Left", "AIFINL" }, { "DACL Mux", "Right", "AIFINR" }, @@ -2050,18 +2112,70 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_component *componen "Failed to add ReTune Mobile control: %d\n", ret); } +static void wm8904_handle_dmic_pdata(struct snd_soc_component *component) +{ + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component); + struct wm8904_pdata *pdata = wm8904->pdata; + unsigned int dmic_src; + + if (!pdata->in1l_as_dmicdat1 && !pdata->in1r_as_dmicdat2) { + snd_soc_dapm_add_routes(dapm, cin_nodmic_con, + ARRAY_SIZE(cin_nodmic_con)); + snd_soc_component_update_bits(component, WM8904_DIGITAL_MICROPHONE_0, + WM8904_DMIC_ENA_MASK, 0); + return; + } + + /* Need a control and routing to switch between DMIC and ADC */ + snd_soc_dapm_new_controls(dapm, wm8904_cin_dapm_widgets, + ARRAY_SIZE(wm8904_cin_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, cin_adc_dmic_con, + ARRAY_SIZE(cin_adc_dmic_con)); + + if (pdata->in1l_as_dmicdat1 && pdata->in1r_as_dmicdat2) { + /* Need a control and routing to mux between DMICDAT1 and 2 */ + dev_dbg(component->dev, "DMICDAT1 and DMICDAT2 in use\n"); + snd_soc_dapm_new_controls(dapm, wm8904_dmic_dapm_widgets, + ARRAY_SIZE(wm8904_dmic_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, cin_2dmics_con, + ARRAY_SIZE(cin_2dmics_con)); + return; + } + + /* Either DMICDAT1 or DMICDAT2 is in use, not both */ + if (pdata->in1l_as_dmicdat1) { + dmic_src = 0; + snd_soc_dapm_add_routes(dapm, cin_dmic1_con, + ARRAY_SIZE(cin_dmic1_con)); + } else { + dmic_src = 1; + snd_soc_dapm_add_routes(dapm, cin_dmic2_con, + ARRAY_SIZE(cin_dmic2_con)); + } + dev_dbg(component->dev, "DMIC_SRC (0 or 1): %d\n", dmic_src); + snd_soc_component_update_bits(component, WM8904_DIGITAL_MICROPHONE_0, + WM8904_DMIC_SRC_MASK, + dmic_src << WM8904_DMIC_SRC_SHIFT); +} + static void wm8904_handle_pdata(struct snd_soc_component *component) { + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component); struct wm8904_pdata *pdata = wm8904->pdata; int ret, i; if (!pdata) { + snd_soc_dapm_add_routes(dapm, cin_nodmic_con, + ARRAY_SIZE(cin_nodmic_con)); snd_soc_add_component_controls(component, wm8904_eq_controls, - ARRAY_SIZE(wm8904_eq_controls)); + ARRAY_SIZE(wm8904_eq_controls)); return; } + wm8904_handle_dmic_pdata(component); + dev_dbg(component->dev, "%d DRC configurations\n", pdata->num_drc_cfgs); if (pdata->num_drc_cfgs) { @@ -2117,10 +2231,11 @@ static int wm8904_probe(struct snd_soc_component *component) return -EINVAL; } - wm8904_handle_pdata(component); - wm8904_add_widgets(component); + /* This can add dependent widgets, so it is done after add_widgets */ + wm8904_handle_pdata(component); + return 0; } From 6271b746e40ebaf24dc54be5f4248f5a61618871 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 19 Mar 2025 09:56:31 -0500 Subject: [PATCH 640/651] ASoC: dmic: Fix NULL pointer dereference Regulator support was introduced in commit d3321a20b5111 ("ASoC: dmic: add regulator support"). During probe `dmic->vref` is initialized with devm_regulator_get_optional() but in the error flow doesn't get cleared in the case that PTR_ERR(dmic->vref) is -ENODEV. This leads to the following NULL pointer deref. ``` Oops: Oops: 0000 [#1] SMP NOPTI CPU: 7 UID: 1000 PID: 1587 Comm: wireplumber Not tainted 6.14.0-rc7-next-20250318 #1 PREEMPT(voluntary) RIP: 0010:regulator_enable+0x17/0x70 RSP: 0018:ffffcc10c1fe7a38 EFLAGS: 00010282 RAX: ffff8bccc1c25010 RBX: ffffffffffffffed RCX: 0000000000000000 RDX: 0000000000000002 RSI: ffffcc10c1fe7a38 RDI: ffffffffffffffed RBP: ffffcc10c1fe7a68 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff8bcccd51f800 R13: ffffffffc1086e88 R14: 0000000000000001 R15: 0000000000000001 FS: 00007f927bc35800(0000) GS:ffff8bd44f09f000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000065 CR3: 00000001332c6000 CR4: 0000000000750ef0 PKRU: 55555554 Call Trace: ? show_regs+0x6c/0x80 ? __die+0x24/0x80 ? page_fault_oops+0x154/0x570 ? hrtimer_start_range_ns+0x142/0x4e0 ? timerqueue_del+0x31/0x50 ? do_user_addr_fault+0x4ac/0x880 ? exc_page_fault+0x82/0x1d0 ? asm_exc_page_fault+0x27/0x30 ? regulator_enable+0x17/0x70 ? __schedule+0x491/0x16b0 dmic_aif_event+0x82/0xa0 [snd_soc_dmic] ``` Adjust the error flow to explicitly set it back to NULL to avoid calling regulator_enable() with garbage data. Reported-by: Akshata V Unkal Fixes: d3321a20b5111 ("ASoC: dmic: add regulator support") Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20250319145636.2401680-1-superm1@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/dmic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 5d3c3f17c6d8..61e1bf1b3c9e 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -114,8 +114,12 @@ static int dmic_component_probe(struct snd_soc_component *component) return -ENOMEM; dmic->vref = devm_regulator_get_optional(component->dev, "vref"); - if (IS_ERR(dmic->vref) && PTR_ERR(dmic->vref) != -ENODEV) - return dev_err_probe(component->dev, PTR_ERR(dmic->vref), "Failed to get vref\n"); + if (IS_ERR(dmic->vref)) { + if (PTR_ERR(dmic->vref) != -ENODEV) + return dev_err_probe(component->dev, PTR_ERR(dmic->vref), + "Failed to get vref\n"); + dmic->vref = NULL; + } dmic->gpio_en = devm_gpiod_get_optional(component->dev, "dmicen", GPIOD_OUT_LOW); From 24489150c5d9afea54c6909ba05c4dbdd8846dc0 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Thu, 20 Mar 2025 12:53:00 +0100 Subject: [PATCH 641/651] ASoC: SOF: mediatek: Commonize duplicated functions In order to reduce duplication, move the ADSP mailbox callbacks handle_reply(), handle_request(), and other common SOF callbacks send_msg(), get_bar_index(), pcm_hw_params() and pcm_pointer() to the mtk-adsp-common.c file. This cleanup brings no functional differences. Signed-off-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20250320115300.137410-1-angelogioacchino.delregno@collabora.com Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8186/mt8186.c | 105 ++---------------- sound/soc/sof/mediatek/mt8195/mt8195.c | 105 ++---------------- sound/soc/sof/mediatek/mtk-adsp-common.c | 130 +++++++++++++++++++++++ sound/soc/sof/mediatek/mtk-adsp-common.h | 10 ++ 4 files changed, 152 insertions(+), 198 deletions(-) diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c index 18144d9504e1..7ff080452cbe 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186.c @@ -22,7 +22,6 @@ #include #include "../../ops.h" #include "../../sof-of-dev.h" -#include "../../sof-audio.h" #include "../adsp_helper.h" #include "../mtk-adsp-common.h" #include "mt8186.h" @@ -38,53 +37,9 @@ static int mt8186_get_window_offset(struct snd_sof_dev *sdev, u32 id) return MBOX_OFFSET; } -static int mt8186_send_msg(struct snd_sof_dev *sdev, - struct snd_sof_ipc_msg *msg) -{ - struct adsp_priv *priv = sdev->pdata->hw_pdata; - - sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, - msg->msg_size); - - return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ); -} - -static void mt8186_dsp_handle_reply(struct mtk_adsp_ipc *ipc) -{ - struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); - unsigned long flags; - - spin_lock_irqsave(&priv->sdev->ipc_lock, flags); - snd_sof_ipc_process_reply(priv->sdev, 0); - spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); -} - -static void mt8186_dsp_handle_request(struct mtk_adsp_ipc *ipc) -{ - struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); - u32 p; /* panic code */ - int ret; - - /* Read the message from the debug box. */ - sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, - &p, sizeof(p)); - - /* Check to see if the message is a panic code 0x0dead*** */ - if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { - snd_sof_dsp_panic(priv->sdev, p, true); - } else { - snd_sof_ipc_msgs_rx(priv->sdev); - - /* tell DSP cmd is done */ - ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP); - if (ret) - dev_err(priv->dev, "request send ipc failed"); - } -} - static const struct mtk_adsp_ipc_ops dsp_ops = { - .handle_reply = mt8186_dsp_handle_reply, - .handle_request = mt8186_dsp_handle_request, + .handle_reply = mtk_adsp_handle_reply, + .handle_request = mtk_adsp_handle_request, }; static int platform_parse_resource(struct platform_device *pdev, void *data) @@ -381,54 +336,6 @@ static int mt8186_dsp_resume(struct snd_sof_dev *sdev) return ret; } -/* on mt8186 there is 1 to 1 match between type and BAR idx */ -static int mt8186_get_bar_index(struct snd_sof_dev *sdev, u32 type) -{ - return type; -} - -static int mt8186_pcm_hw_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_sof_platform_stream_params *platform_params) -{ - platform_params->cont_update_posn = 1; - - return 0; -} - -static snd_pcm_uframes_t mt8186_pcm_pointer(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream) -{ - int ret; - snd_pcm_uframes_t pos; - struct snd_sof_pcm *spcm; - struct sof_ipc_stream_posn posn; - struct snd_sof_pcm_stream *stream; - struct snd_soc_component *scomp = sdev->component; - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - - spcm = snd_sof_find_spcm_dai(scomp, rtd); - if (!spcm) { - dev_warn_ratelimited(sdev->dev, "warn: can't find PCM with DAI ID %d\n", - rtd->dai_link->id); - return 0; - } - - stream = &spcm->stream[substream->stream]; - ret = snd_sof_ipc_msg_data(sdev, stream, &posn, sizeof(posn)); - if (ret < 0) { - dev_warn(sdev->dev, "failed to read stream position: %d\n", ret); - return 0; - } - - memcpy(&stream->posn, &posn, sizeof(posn)); - pos = spcm->stream[substream->stream].posn.host_posn; - pos = bytes_to_frames(substream->runtime, pos); - - return pos; -} - static void mt8186_adsp_dump(struct snd_sof_dev *sdev, u32 flags) { u32 dbg_pc, dbg_data, dbg_inst, dbg_ls0stat, dbg_status, faultinfo; @@ -505,19 +412,19 @@ static const struct snd_sof_dsp_ops sof_mt8186_ops = { .read64 = sof_io_read64, /* ipc */ - .send_msg = mt8186_send_msg, + .send_msg = mtk_adsp_send_msg, .get_mailbox_offset = mt8186_get_mailbox_offset, .get_window_offset = mt8186_get_window_offset, .ipc_msg_data = sof_ipc_msg_data, .set_stream_data_offset = sof_set_stream_data_offset, /* misc */ - .get_bar_index = mt8186_get_bar_index, + .get_bar_index = mtk_adsp_get_bar_index, /* stream callbacks */ .pcm_open = sof_stream_pcm_open, - .pcm_hw_params = mt8186_pcm_hw_params, - .pcm_pointer = mt8186_pcm_pointer, + .pcm_hw_params = mtk_adsp_stream_pcm_hw_params, + .pcm_pointer = mtk_adsp_stream_pcm_pointer, .pcm_close = sof_stream_pcm_close, /* firmware loading */ diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 821f43a3974a..3b3582d74510 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -22,7 +22,6 @@ #include #include "../../ops.h" #include "../../sof-of-dev.h" -#include "../../sof-audio.h" #include "../adsp_helper.h" #include "../mtk-adsp-common.h" #include "mt8195.h" @@ -38,53 +37,9 @@ static int mt8195_get_window_offset(struct snd_sof_dev *sdev, u32 id) return MBOX_OFFSET; } -static int mt8195_send_msg(struct snd_sof_dev *sdev, - struct snd_sof_ipc_msg *msg) -{ - struct adsp_priv *priv = sdev->pdata->hw_pdata; - - sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, - msg->msg_size); - - return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ); -} - -static void mt8195_dsp_handle_reply(struct mtk_adsp_ipc *ipc) -{ - struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); - unsigned long flags; - - spin_lock_irqsave(&priv->sdev->ipc_lock, flags); - snd_sof_ipc_process_reply(priv->sdev, 0); - spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); -} - -static void mt8195_dsp_handle_request(struct mtk_adsp_ipc *ipc) -{ - struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); - u32 p; /* panic code */ - int ret; - - /* Read the message from the debug box. */ - sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, - &p, sizeof(p)); - - /* Check to see if the message is a panic code 0x0dead*** */ - if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { - snd_sof_dsp_panic(priv->sdev, p, true); - } else { - snd_sof_ipc_msgs_rx(priv->sdev); - - /* tell DSP cmd is done */ - ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP); - if (ret) - dev_err(priv->dev, "request send ipc failed"); - } -} - static const struct mtk_adsp_ipc_ops dsp_ops = { - .handle_reply = mt8195_dsp_handle_reply, - .handle_request = mt8195_dsp_handle_request, + .handle_reply = mtk_adsp_handle_reply, + .handle_request = mtk_adsp_handle_request, }; static int platform_parse_resource(struct platform_device *pdev, void *data) @@ -400,54 +355,6 @@ static int mt8195_dsp_resume(struct snd_sof_dev *sdev) return ret; } -/* on mt8195 there is 1 to 1 match between type and BAR idx */ -static int mt8195_get_bar_index(struct snd_sof_dev *sdev, u32 type) -{ - return type; -} - -static int mt8195_pcm_hw_params(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_sof_platform_stream_params *platform_params) -{ - platform_params->cont_update_posn = 1; - - return 0; -} - -static snd_pcm_uframes_t mt8195_pcm_pointer(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream) -{ - int ret; - snd_pcm_uframes_t pos; - struct snd_sof_pcm *spcm; - struct sof_ipc_stream_posn posn; - struct snd_sof_pcm_stream *stream; - struct snd_soc_component *scomp = sdev->component; - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - - spcm = snd_sof_find_spcm_dai(scomp, rtd); - if (!spcm) { - dev_warn_ratelimited(sdev->dev, "warn: can't find PCM with DAI ID %d\n", - rtd->dai_link->id); - return 0; - } - - stream = &spcm->stream[substream->stream]; - ret = snd_sof_ipc_msg_data(sdev, stream, &posn, sizeof(posn)); - if (ret < 0) { - dev_warn(sdev->dev, "failed to read stream position: %d\n", ret); - return 0; - } - - memcpy(&stream->posn, &posn, sizeof(posn)); - pos = spcm->stream[substream->stream].posn.host_posn; - pos = bytes_to_frames(substream->runtime, pos); - - return pos; -} - static void mt8195_adsp_dump(struct snd_sof_dev *sdev, u32 flags) { u32 dbg_pc, dbg_data, dbg_bus0, dbg_bus1, dbg_inst; @@ -529,19 +436,19 @@ static const struct snd_sof_dsp_ops sof_mt8195_ops = { .read64 = sof_io_read64, /* ipc */ - .send_msg = mt8195_send_msg, + .send_msg = mtk_adsp_send_msg, .get_mailbox_offset = mt8195_get_mailbox_offset, .get_window_offset = mt8195_get_window_offset, .ipc_msg_data = sof_ipc_msg_data, .set_stream_data_offset = sof_set_stream_data_offset, /* misc */ - .get_bar_index = mt8195_get_bar_index, + .get_bar_index = mtk_adsp_get_bar_index, /* stream callbacks */ .pcm_open = sof_stream_pcm_open, - .pcm_hw_params = mt8195_pcm_hw_params, - .pcm_pointer = mt8195_pcm_pointer, + .pcm_hw_params = mtk_adsp_stream_pcm_hw_params, + .pcm_pointer = mtk_adsp_stream_pcm_pointer, .pcm_close = sof_stream_pcm_close, /* firmware loading */ diff --git a/sound/soc/sof/mediatek/mtk-adsp-common.c b/sound/soc/sof/mediatek/mtk-adsp-common.c index 20bcf5590eb8..01bbadb160ff 100644 --- a/sound/soc/sof/mediatek/mtk-adsp-common.c +++ b/sound/soc/sof/mediatek/mtk-adsp-common.c @@ -12,8 +12,11 @@ */ #include +#include #include #include "../ops.h" +#include "../sof-audio.h" +#include "adsp_helper.h" #include "mtk-adsp-common.h" /** @@ -81,5 +84,132 @@ void mtk_adsp_dump(struct snd_sof_dev *sdev, u32 flags) } EXPORT_SYMBOL(mtk_adsp_dump); +/** + * mtk_adsp_send_msg - Send message to Audio DSP + * @sdev: SOF device + * @msg: SOF IPC Message to send + */ +int mtk_adsp_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + + sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, + msg->msg_size); + + return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ); +} +EXPORT_SYMBOL(mtk_adsp_send_msg); + +/** + * mtk_adsp_handle_reply - Handle reply from the Audio DSP through Mailbox + * @ipc: ADSP IPC handle + */ +void mtk_adsp_handle_reply(struct mtk_adsp_ipc *ipc) +{ + struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); + unsigned long flags; + + spin_lock_irqsave(&priv->sdev->ipc_lock, flags); + snd_sof_ipc_process_reply(priv->sdev, 0); + spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); +} +EXPORT_SYMBOL(mtk_adsp_handle_reply); + +/** + * mtk_adsp_handle_request - Handle request from the Audio DSP through Mailbox + * @ipc: ADSP IPC handle + */ +void mtk_adsp_handle_request(struct mtk_adsp_ipc *ipc) +{ + struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc); + u32 panic_code; + int ret; + + /* Read the message from the debug box. */ + sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, + &panic_code, sizeof(panic_code)); + + /* Check to see if the message is a panic code 0x0dead*** */ + if ((panic_code & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { + snd_sof_dsp_panic(priv->sdev, panic_code, true); + } else { + snd_sof_ipc_msgs_rx(priv->sdev); + + /* Tell DSP cmd is done */ + ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP); + if (ret) + dev_err(priv->dev, "request send ipc failed"); + } +} +EXPORT_SYMBOL(mtk_adsp_handle_request); + +/** + * mtk_adsp_get_bar_index - Map section type with BAR idx + * @sdev: SOF device + * @type: Section type as described by snd_sof_fw_blk_type + * + * MediaTek Audio DSPs have a 1:1 match between type and BAR idx + */ +int mtk_adsp_get_bar_index(struct snd_sof_dev *sdev, u32 type) +{ + return type; +} +EXPORT_SYMBOL(mtk_adsp_get_bar_index); + +/** + * mtk_adsp_stream_pcm_hw_params - Platform specific host stream hw params + * @sdev: SOF device + * @substream: PCM Substream + * @params: hw params + * @platform_params: Platform specific SOF stream parameters + */ +int mtk_adsp_stream_pcm_hw_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_sof_platform_stream_params *platform_params) +{ + platform_params->cont_update_posn = 1; + return 0; +} +EXPORT_SYMBOL(mtk_adsp_stream_pcm_hw_params); + +/** + * mtk_adsp_stream_pcm_pointer - Get host stream pointer + * @sdev: SOF device + * @substream: PCM substream + */ +snd_pcm_uframes_t mtk_adsp_stream_pcm_pointer(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *scomp = sdev->component; + struct snd_sof_pcm_stream *stream; + struct sof_ipc_stream_posn posn; + struct snd_sof_pcm *spcm; + snd_pcm_uframes_t pos; + int ret; + + spcm = snd_sof_find_spcm_dai(scomp, rtd); + if (!spcm) { + dev_warn_ratelimited(sdev->dev, "warn: can't find PCM with DAI ID %d\n", + rtd->dai_link->id); + return 0; + } + + stream = &spcm->stream[substream->stream]; + ret = snd_sof_ipc_msg_data(sdev, stream, &posn, sizeof(posn)); + if (ret < 0) { + dev_warn(sdev->dev, "failed to read stream position: %d\n", ret); + return 0; + } + + memcpy(&stream->posn, &posn, sizeof(posn)); + pos = spcm->stream[substream->stream].posn.host_posn; + pos = bytes_to_frames(substream->runtime, pos); + + return pos; +} +EXPORT_SYMBOL(mtk_adsp_stream_pcm_pointer); + MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("SOF helpers for MTK ADSP platforms"); diff --git a/sound/soc/sof/mediatek/mtk-adsp-common.h b/sound/soc/sof/mediatek/mtk-adsp-common.h index 612cff1f38f7..dc36b91d6779 100644 --- a/sound/soc/sof/mediatek/mtk-adsp-common.h +++ b/sound/soc/sof/mediatek/mtk-adsp-common.h @@ -7,4 +7,14 @@ #define MTK_ADSP_STACK_DUMP_SIZE 32 void mtk_adsp_dump(struct snd_sof_dev *sdev, u32 flags); +int mtk_adsp_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); +void mtk_adsp_handle_reply(struct mtk_adsp_ipc *ipc); +void mtk_adsp_handle_request(struct mtk_adsp_ipc *ipc); +int mtk_adsp_get_bar_index(struct snd_sof_dev *sdev, u32 type); +int mtk_adsp_stream_pcm_hw_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_sof_platform_stream_params *platform_params); +snd_pcm_uframes_t mtk_adsp_stream_pcm_pointer(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream); #endif From 0b1b5161648f35fb96967fb9d80965614657a84e Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Fri, 21 Mar 2025 18:49:13 +0800 Subject: [PATCH 642/651] ALSA: hda/realtek: fix micmute LEDs on HP Laptops with ALC3315 More HP laptops with Realtek HDA codec ALC3315 with combined CS35L56 Amplifiers need quirk ALC285_FIXUP_HP_GPIO_LED to fix the micmute LED. Signed-off-by: Chris Chiu Reviewed-by: Simon Trimmer Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250321104914.544233-1-chris.chiu@canonical.com --- sound/pci/hda/patch_realtek.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ccc3b864d133..7662b6cc17db 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10691,13 +10691,27 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8d01, "HP ZBook Power 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8d84, "HP EliteBook X G1i", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d85, "HP EliteBook 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d86, "HP Elite X360 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d8c, "HP EliteBook 13 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d8d, "HP Elite X360 13 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d8e, "HP EliteBook 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d8f, "HP EliteBook 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d90, "HP EliteBook 16 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8d91, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8de8, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2), SND_PCI_QUIRK(0x103c, 0x8de9, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2), + SND_PCI_QUIRK(0x103c, 0x8e14, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e15, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e16, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e17, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e18, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e19, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e1a, "HP ZBook Firefly 14 G12A", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e1b, "HP EliteBook G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e1c, "HP EliteBook G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e2c, "HP EliteBook 16 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x1054, "ASUS G614FH/FM/FP", ALC287_FIXUP_CS35L41_I2C_2), From 78f4ca3c6f6fd305b9af8c51470643617df85e11 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Fri, 21 Mar 2025 18:49:14 +0800 Subject: [PATCH 643/651] ALSA: hda/realtek: fix micmute LEDs on HP Laptops with ALC3247 More HP EliteBook with Realtek HDA codec ALC3247 with combined CS35L56 Amplifiers need quirk ALC236_FIXUP_HP_GPIO_LED to fix the micmute LED. Signed-off-by: Chris Chiu Reviewed-by: Simon Trimmer Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250321104914.544233-2-chris.chiu@canonical.com --- sound/pci/hda/patch_realtek.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7662b6cc17db..50e1c947a77c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10702,6 +10702,11 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8de8, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2), SND_PCI_QUIRK(0x103c, 0x8de9, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2), + SND_PCI_QUIRK(0x103c, 0x8dec, "HP EliteBook 640 G12", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8dee, "HP EliteBook 660 G12", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8df0, "HP EliteBook 630 G12", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8dfc, "HP EliteBook 645 G12", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8dfe, "HP EliteBook 665 G12", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e14, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e15, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e16, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), From 5a4dd520ef8a94ecf81ac77b90d6a03e91c100a9 Mon Sep 17 00:00:00 2001 From: Syed Saba kareem Date: Fri, 21 Mar 2025 17:55:03 +0530 Subject: [PATCH 644/651] ASoC: amd: yc: update quirk data for new Lenovo model Update Quirk data for new Lenovo model 83J2 for YC platform. Signed-off-by: Syed Saba kareem Link: https://patch.msgid.link/20250321122507.190193-1-syed.sabakareem@amd.com Reported-by: Reiner Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219887 Tested-by: Reiner Reviewed-by: Mario Limonciello Signed-off-by: Mark Brown --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index a7637056972a..eded178f0b13 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -339,6 +339,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83J2"), + } + }, { .driver_data = &acp6x_card, .matches = { From 9ef52d529bb75071e03cf85078f724d69c4abe89 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 21 Mar 2025 13:53:24 +0000 Subject: [PATCH 645/651] ASoC: SDCA: Correct handling of selected mode DisCo property mipi-sdca-ge-selectedmode-controls-affected is actually required by the specification so the code should return an error if it is missing. Reported-by: Maciej Strozek Fixes: 13fe7497af19 ("ASoC: SDCA: Add support for GE Entity properties") Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20250321135324.380237-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sdca/sdca_functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index c8efdc5301b5..493f390f087a 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -1159,7 +1159,7 @@ static int find_sdca_entity_ge(struct device *dev, num_affected = fwnode_property_count_u8(entity_node, "mipi-sdca-ge-selectedmode-controls-affected"); - if (!num_affected || num_affected == -EINVAL) { + if (!num_affected) { return 0; } else if (num_affected < 0) { dev_err(dev, "%s: failed to read affected controls: %d\n", From 3424c8f53bc63c87712a7fc22dc13d0cc85fb0d6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 21 Mar 2025 18:26:52 +0100 Subject: [PATCH 646/651] ALSA: timer: Don't take register_mutex with copy_from/to_user() The infamous mmap_lock taken in copy_from/to_user() can be often problematic when it's called inside another mutex, as they might lead to deadlocks. In the case of ALSA timer code, the bad pattern is with guard(mutex)(®ister_mutex) that covers copy_from/to_user() -- which was mistakenly introduced at converting to guard(), and it had been carefully worked around in the past. This patch fixes those pieces simply by moving copy_from/to_user() out of the register mutex lock again. Fixes: 3923de04c817 ("ALSA: pcm: oss: Use guard() for setup") Reported-by: syzbot+2b96f44164236dda0f3b@syzkaller.appspotmail.com Closes: https://lore.kernel.org/67dd86c8.050a0220.25ae54.0059.GAE@google.com Link: https://patch.msgid.link/20250321172653.14310-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/timer.c | 147 ++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 70 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index fbada79380f9..d774b9b71ce2 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1515,91 +1515,97 @@ static void snd_timer_user_copy_id(struct snd_timer_id *id, struct snd_timer *ti id->subdevice = timer->tmr_subdevice; } -static int snd_timer_user_next_device(struct snd_timer_id __user *_tid) +static void get_next_device(struct snd_timer_id *id) { - struct snd_timer_id id; struct snd_timer *timer; struct list_head *p; - if (copy_from_user(&id, _tid, sizeof(id))) - return -EFAULT; - guard(mutex)(®ister_mutex); - if (id.dev_class < 0) { /* first item */ + if (id->dev_class < 0) { /* first item */ if (list_empty(&snd_timer_list)) - snd_timer_user_zero_id(&id); + snd_timer_user_zero_id(id); else { timer = list_entry(snd_timer_list.next, struct snd_timer, device_list); - snd_timer_user_copy_id(&id, timer); + snd_timer_user_copy_id(id, timer); } } else { - switch (id.dev_class) { + switch (id->dev_class) { case SNDRV_TIMER_CLASS_GLOBAL: - id.device = id.device < 0 ? 0 : id.device + 1; + id->device = id->device < 0 ? 0 : id->device + 1; list_for_each(p, &snd_timer_list) { timer = list_entry(p, struct snd_timer, device_list); if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) { - snd_timer_user_copy_id(&id, timer); + snd_timer_user_copy_id(id, timer); break; } - if (timer->tmr_device >= id.device) { - snd_timer_user_copy_id(&id, timer); + if (timer->tmr_device >= id->device) { + snd_timer_user_copy_id(id, timer); break; } } if (p == &snd_timer_list) - snd_timer_user_zero_id(&id); + snd_timer_user_zero_id(id); break; case SNDRV_TIMER_CLASS_CARD: case SNDRV_TIMER_CLASS_PCM: - if (id.card < 0) { - id.card = 0; + if (id->card < 0) { + id->card = 0; } else { - if (id.device < 0) { - id.device = 0; + if (id->device < 0) { + id->device = 0; } else { - if (id.subdevice < 0) - id.subdevice = 0; - else if (id.subdevice < INT_MAX) - id.subdevice++; + if (id->subdevice < 0) + id->subdevice = 0; + else if (id->subdevice < INT_MAX) + id->subdevice++; } } list_for_each(p, &snd_timer_list) { timer = list_entry(p, struct snd_timer, device_list); - if (timer->tmr_class > id.dev_class) { - snd_timer_user_copy_id(&id, timer); + if (timer->tmr_class > id->dev_class) { + snd_timer_user_copy_id(id, timer); break; } - if (timer->tmr_class < id.dev_class) + if (timer->tmr_class < id->dev_class) continue; - if (timer->card->number > id.card) { - snd_timer_user_copy_id(&id, timer); + if (timer->card->number > id->card) { + snd_timer_user_copy_id(id, timer); break; } - if (timer->card->number < id.card) + if (timer->card->number < id->card) continue; - if (timer->tmr_device > id.device) { - snd_timer_user_copy_id(&id, timer); + if (timer->tmr_device > id->device) { + snd_timer_user_copy_id(id, timer); break; } - if (timer->tmr_device < id.device) + if (timer->tmr_device < id->device) continue; - if (timer->tmr_subdevice > id.subdevice) { - snd_timer_user_copy_id(&id, timer); + if (timer->tmr_subdevice > id->subdevice) { + snd_timer_user_copy_id(id, timer); break; } - if (timer->tmr_subdevice < id.subdevice) + if (timer->tmr_subdevice < id->subdevice) continue; - snd_timer_user_copy_id(&id, timer); + snd_timer_user_copy_id(id, timer); break; } if (p == &snd_timer_list) - snd_timer_user_zero_id(&id); + snd_timer_user_zero_id(id); break; default: - snd_timer_user_zero_id(&id); + snd_timer_user_zero_id(id); } } +} + +static int snd_timer_user_next_device(struct snd_timer_id __user *_tid) +{ + struct snd_timer_id id; + + if (copy_from_user(&id, _tid, sizeof(id))) + return -EFAULT; + scoped_guard(mutex, ®ister_mutex) + get_next_device(&id); if (copy_to_user(_tid, &id, sizeof(*_tid))) return -EFAULT; return 0; @@ -1620,23 +1626,24 @@ static int snd_timer_user_ginfo(struct file *file, tid = ginfo->tid; memset(ginfo, 0, sizeof(*ginfo)); ginfo->tid = tid; - guard(mutex)(®ister_mutex); - t = snd_timer_find(&tid); - if (!t) - return -ENODEV; - ginfo->card = t->card ? t->card->number : -1; - if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) - ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; - strscpy(ginfo->id, t->id, sizeof(ginfo->id)); - strscpy(ginfo->name, t->name, sizeof(ginfo->name)); - scoped_guard(spinlock_irq, &t->lock) - ginfo->resolution = snd_timer_hw_resolution(t); - if (t->hw.resolution_min > 0) { - ginfo->resolution_min = t->hw.resolution_min; - ginfo->resolution_max = t->hw.resolution_max; - } - list_for_each(p, &t->open_list_head) { - ginfo->clients++; + scoped_guard(mutex, ®ister_mutex) { + t = snd_timer_find(&tid); + if (!t) + return -ENODEV; + ginfo->card = t->card ? t->card->number : -1; + if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) + ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; + strscpy(ginfo->id, t->id, sizeof(ginfo->id)); + strscpy(ginfo->name, t->name, sizeof(ginfo->name)); + scoped_guard(spinlock_irq, &t->lock) + ginfo->resolution = snd_timer_hw_resolution(t); + if (t->hw.resolution_min > 0) { + ginfo->resolution_min = t->hw.resolution_min; + ginfo->resolution_max = t->hw.resolution_max; + } + list_for_each(p, &t->open_list_head) { + ginfo->clients++; + } } if (copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) return -EFAULT; @@ -1674,31 +1681,31 @@ static int snd_timer_user_gstatus(struct file *file, struct snd_timer_gstatus gstatus; struct snd_timer_id tid; struct snd_timer *t; - int err = 0; if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus))) return -EFAULT; tid = gstatus.tid; memset(&gstatus, 0, sizeof(gstatus)); gstatus.tid = tid; - guard(mutex)(®ister_mutex); - t = snd_timer_find(&tid); - if (t != NULL) { - guard(spinlock_irq)(&t->lock); - gstatus.resolution = snd_timer_hw_resolution(t); - if (t->hw.precise_resolution) { - t->hw.precise_resolution(t, &gstatus.resolution_num, - &gstatus.resolution_den); + scoped_guard(mutex, ®ister_mutex) { + t = snd_timer_find(&tid); + if (t != NULL) { + guard(spinlock_irq)(&t->lock); + gstatus.resolution = snd_timer_hw_resolution(t); + if (t->hw.precise_resolution) { + t->hw.precise_resolution(t, &gstatus.resolution_num, + &gstatus.resolution_den); + } else { + gstatus.resolution_num = gstatus.resolution; + gstatus.resolution_den = 1000000000uL; + } } else { - gstatus.resolution_num = gstatus.resolution; - gstatus.resolution_den = 1000000000uL; + return -ENODEV; } - } else { - err = -ENODEV; } - if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) - err = -EFAULT; - return err; + if (copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) + return -EFAULT; + return 0; } static int snd_timer_user_tselect(struct file *file, From 29951021367f3a6f10e5b7a11c666fc914746f0c Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Fri, 21 Mar 2025 23:16:36 +0000 Subject: [PATCH 647/651] ALSA: hda/realtek: Add support for various HP Laptops using CS35L41 HDA Add support for HP Cadet, Clipper OmniBook, Turbine OmniBook, Trekker, Enstrom Onmibook, Piston Omnibook Laptops use 2 CS35L41 Amps with HDA, using Internal boost, with I2C Signed-off-by: Stefan Binding Link: https://patch.msgid.link/20250321231717.1232792-1-sbinding@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 50e1c947a77c..1acf0783c0f8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10700,6 +10700,15 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8d90, "HP EliteBook 16 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8d91, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8d9b, "HP 17 Turbine OmniBook 7 UMA", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8d9c, "HP 17 Turbine OmniBook 7 DIS", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8d9d, "HP 17 Turbine OmniBook X UMA", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8d9e, "HP 17 Turbine OmniBook X DIS", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8d9f, "HP 14 Cadet (x360)", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8da0, "HP 16 Clipper OmniBook 7(X360)", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8da1, "HP 16 Clipper OmniBook X", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8da7, "HP 14 Enstrom OmniBook X", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8da8, "HP 16 Piston OmniBook X", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8de8, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2), SND_PCI_QUIRK(0x103c, 0x8de9, "HP Gemtree", ALC245_FIXUP_TAS2781_SPI_2), SND_PCI_QUIRK(0x103c, 0x8dec, "HP EliteBook 640 G12", ALC236_FIXUP_HP_GPIO_LED), @@ -10707,6 +10716,9 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8df0, "HP EliteBook 630 G12", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8dfc, "HP EliteBook 645 G12", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8dfe, "HP EliteBook 665 G12", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e11, "HP Trekker", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e12, "HP Trekker", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e13, "HP Trekker", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8e14, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e15, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e16, "HP ZBook Firefly 14 G12", ALC285_FIXUP_HP_GPIO_LED), @@ -10717,6 +10729,11 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8e1b, "HP EliteBook G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e1c, "HP EliteBook G12", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8e2c, "HP EliteBook 16 G12", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8e36, "HP 14 Enstrom OmniBook X", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e37, "HP 16 Piston OmniBook X", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e60, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e61, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e62, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x1054, "ASUS G614FH/FM/FP", ALC287_FIXUP_CS35L41_I2C_2), From 829ee558f3527fd602c6e2e9f270959d1de09fe0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 24 Mar 2025 16:32:32 +0100 Subject: [PATCH 648/651] ALSA: hda/realtek: Fix built-in mic assignment on ASUS VivoBook X515UA ASUS VivoBook X515UA with PCI SSID 1043:106f had a default quirk pickup via pin table that applies ALC256_FIXUP_ASUS_MIC, but this adds a bogus built-in mic pin 0x13 enabled. This was no big problem because the pin 0x13 was assigned as the secondary mic, but the recent fix made the entries sorted, hence this bogus pin appeared now as the primary input and it broke. For fixing the bug, put the right quirk entry for this device pointing to ALC256_FIXUP_ASUS_MIC_NO_PRESENCE. Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort") Link: https://bugzilla.kernel.org/show_bug.cgi?id=219897 Link: https://patch.msgid.link/20250324153233.21195-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 26510ab6ce67..da8f21db607b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10770,6 +10770,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x1054, "ASUS G614FH/FM/FP", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1043, 0x106f, "ASUS VivoBook X515UA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1074, "ASUS G614PH/PM/PP", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x10a1, "ASUS UX391UA", ALC294_FIXUP_ASUS_SPK), SND_PCI_QUIRK(0x1043, 0x10a4, "ASUS TP3407SA", ALC287_FIXUP_TAS2781_I2C), From be8cd366beb80c709adbc7688ee72750f5aee3ff Mon Sep 17 00:00:00 2001 From: Andres Traumann Date: Tue, 25 Mar 2025 17:25:35 +0700 Subject: [PATCH 649/651] ALSA: hda/realtek: Bass speaker fixup for ASUS UM5606KA This patch applies the ALC294 bass speaker fixup (ALC294_FIXUP_BASS_SPEAKER_15), previously introduced in commit a7df7f909cec ("ALSA: hda: improve bass speaker support for ASUS Zenbook UM5606WA"), to the ASUS Zenbook UM5606KA. This hardware configuration matches ASUS Zenbook UM5606WA, where DAC NID 0x06 was removed from the bass speaker (NID 0x15), routing both speaker pins to DAC NID 0x03. This resolves the bass speaker routing issue, ensuring correct audio output on ASUS UM5606KA. Signed-off-by: Andres Traumann Cc: Link: https://patch.msgid.link/20250325102535.8172-1-andres.traumann.01@gmail.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index da8f21db607b..b4fe681ec3cb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10855,6 +10855,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1df3, "ASUS UM5606WA", ALC294_FIXUP_BASS_SPEAKER_15), + SND_PCI_QUIRK(0x1043, 0x1264, "ASUS UM5606KA", ALC294_FIXUP_BASS_SPEAKER_15), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), From 09e269f550f548a1249ba5282747fe67ba177608 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Tue, 25 Mar 2025 16:46:39 +0800 Subject: [PATCH 650/651] ALSA: hda: cs35l56: Remove unnecessary NULL check before release_firmware() release_firmware() checks for NULL pointers internally. Remove unneeded NULL check for fmw here. Signed-off-by: Chen Ni Link: https://patch.msgid.link/20250325084639.801054-1-nichen@iscas.ac.cn Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l56_hda.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/cs35l56_hda.c b/sound/pci/hda/cs35l56_hda.c index 4ef7878e8fd4..235d22049aa9 100644 --- a/sound/pci/hda/cs35l56_hda.c +++ b/sound/pci/hda/cs35l56_hda.c @@ -546,12 +546,10 @@ static void cs35l56_hda_release_firmware_files(const struct firmware *wmfw_firmw const struct firmware *coeff_firmware, char *coeff_filename) { - if (wmfw_firmware) - release_firmware(wmfw_firmware); + release_firmware(wmfw_firmware); kfree(wmfw_filename); - if (coeff_firmware) - release_firmware(coeff_firmware); + release_firmware(coeff_firmware); kfree(coeff_filename); } From 3a949fc08103c0ce3a1d0ef30459c7b3acc6a214 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Tue, 25 Mar 2025 16:49:39 +0800 Subject: [PATCH 651/651] ALSA: hda: tas2781-i2c: Remove unnecessary NULL check before release_firmware() release_firmware() checks for NULL pointers internally. Remove unneeded NULL check for fmw here. Signed-off-by: Chen Ni Link: https://patch.msgid.link/20250325084939.801117-1-nichen@iscas.ac.cn Signed-off-by: Takashi Iwai --- sound/pci/hda/tas2781_hda_i2c.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c index 50c5e5f26589..9ed49b0dbe6b 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -753,8 +753,7 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) out: mutex_unlock(&tas_hda->priv->codec_lock); - if (fmw) - release_firmware(fmw); + release_firmware(fmw); pm_runtime_mark_last_busy(tas_hda->dev); pm_runtime_put_autosuspend(tas_hda->dev); }