summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml78
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/firmware/cirrus/cs_dsp.c17
-rw-r--r--include/dt-bindings/sound/cs35l45.h57
-rw-r--r--include/linux/firmware/cirrus/cs_dsp.h1
-rw-r--r--include/sound/cs35l56.h266
-rw-r--r--sound/arm/pxa2xx-ac97.c6
-rw-r--r--sound/atmel/ac97c.c6
-rw-r--r--sound/drivers/mts64.c6
-rw-r--r--sound/drivers/portman2x4.c6
-rw-r--r--sound/mips/hal2.c5
-rw-r--r--sound/mips/sgio2audio.c5
-rw-r--r--sound/pci/hda/hda_tegra.c6
-rw-r--r--sound/ppc/powermac.c5
-rw-r--r--sound/sh/aica.c7
-rw-r--r--sound/sh/sh_dac_audio.c5
-rw-r--r--sound/soc/adi/axi-i2s.c6
-rw-r--r--sound/soc/adi/axi-spdif.c6
-rw-r--r--sound/soc/amd/acp-pcm-dma.c6
-rw-r--r--sound/soc/amd/acp/acp-rembrandt.c13
-rw-r--r--sound/soc/amd/acp/acp-renoir.c5
-rw-r--r--sound/soc/amd/ps/ps-pdm-dma.c5
-rw-r--r--sound/soc/amd/raven/acp3x-pcm-dma.c5
-rw-r--r--sound/soc/amd/renoir/acp3x-pdm-dma.c5
-rw-r--r--sound/soc/amd/vangogh/acp5x-pcm-dma.c5
-rw-r--r--sound/soc/amd/yc/acp6x-pdm-dma.c5
-rw-r--r--sound/soc/apple/mca.c5
-rw-r--r--sound/soc/atmel/atmel-i2s.c6
-rw-r--r--sound/soc/atmel/atmel_wm8904.c6
-rw-r--r--sound/soc/atmel/mchp-i2s-mcc.c6
-rw-r--r--sound/soc/atmel/mchp-pdmc.c6
-rw-r--r--sound/soc/atmel/mchp-spdifrx.c6
-rw-r--r--sound/soc/atmel/mchp-spdiftx.c6
-rw-r--r--sound/soc/atmel/mikroe-proto.c6
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c6
-rw-r--r--sound/soc/atmel/sam9x5_wm8731.c6
-rw-r--r--sound/soc/atmel/tse850-pcm5142.c6
-rw-r--r--sound/soc/au1x/ac97c.c6
-rw-r--r--sound/soc/au1x/i2sc.c6
-rw-r--r--sound/soc/au1x/psc-ac97.c6
-rw-r--r--sound/soc/au1x/psc-i2s.c6
-rw-r--r--sound/soc/bcm/bcm63xx-i2s-whistler.c5
-rw-r--r--sound/soc/bcm/cygnus-ssp.c6
-rw-r--r--sound/soc/cirrus/edb93xx.c6
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c5
-rw-r--r--sound/soc/codecs/Kconfig44
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/cs35l41.c1
-rw-r--r--sound/soc/codecs/cs35l45-i2c.c3
-rw-r--r--sound/soc/codecs/cs35l45-spi.c5
-rw-r--r--sound/soc/codecs/cs35l45-tables.c135
-rw-r--r--sound/soc/codecs/cs35l45.c630
-rw-r--r--sound/soc/codecs/cs35l45.h267
-rw-r--r--sound/soc/codecs/cs35l56-i2c.c83
-rw-r--r--sound/soc/codecs/cs35l56-sdw.c528
-rw-r--r--sound/soc/codecs/cs35l56-shared.c390
-rw-r--r--sound/soc/codecs/cs35l56-spi.c81
-rw-r--r--sound/soc/codecs/cs35l56.c1461
-rw-r--r--sound/soc/codecs/cs35l56.h77
-rw-r--r--sound/soc/codecs/cs47l15.c6
-rw-r--r--sound/soc/codecs/cs47l24.c6
-rw-r--r--sound/soc/codecs/cs47l35.c6
-rw-r--r--sound/soc/codecs/cs47l85.c6
-rw-r--r--sound/soc/codecs/cs47l90.c6
-rw-r--r--sound/soc/codecs/cs47l92.c6
-rw-r--r--sound/soc/codecs/inno_rk3036.c6
-rw-r--r--sound/soc/codecs/lpass-rx-macro.c6
-rw-r--r--sound/soc/codecs/lpass-tx-macro.c6
-rw-r--r--sound/soc/codecs/lpass-va-macro.c6
-rw-r--r--sound/soc/codecs/lpass-wsa-macro.c6
-rw-r--r--sound/soc/codecs/msm8916-wcd-analog.c6
-rw-r--r--sound/soc/codecs/msm8916-wcd-digital.c6
-rw-r--r--sound/soc/codecs/rk817_codec.c6
-rw-r--r--sound/soc/codecs/wcd938x.c6
-rw-r--r--sound/soc/codecs/wm5102.c6
-rw-r--r--sound/soc/codecs/wm5110.c6
-rw-r--r--sound/soc/codecs/wm8994.c6
-rw-r--r--sound/soc/codecs/wm8997.c6
-rw-r--r--sound/soc/codecs/wm8998.c6
-rw-r--r--sound/soc/codecs/wm_adsp.c63
-rw-r--r--sound/soc/codecs/wm_adsp.h3
-rw-r--r--sound/soc/dwc/dwc-i2s.c5
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c6
-rw-r--r--sound/soc/fsl/fsl_asrc.c6
-rw-r--r--sound/soc/fsl/fsl_aud2htx.c6
-rw-r--r--sound/soc/fsl/fsl_audmix.c6
-rw-r--r--sound/soc/fsl/fsl_dma.c6
-rw-r--r--sound/soc/fsl/fsl_easrc.c6
-rw-r--r--sound/soc/fsl/fsl_esai.c6
-rw-r--r--sound/soc/fsl/fsl_mqs.c5
-rw-r--r--sound/soc/fsl/fsl_rpmsg.c6
-rw-r--r--sound/soc/fsl/fsl_sai.c6
-rw-r--r--sound/soc/fsl/fsl_spdif.c6
-rw-r--r--sound/soc/fsl/fsl_ssi.c6
-rw-r--r--sound/soc/fsl/fsl_xcvr.c5
-rw-r--r--sound/soc/fsl/imx-audmux.c6
-rw-r--r--sound/soc/fsl/imx-pcm-rpmsg.c6
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c6
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c5
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c5
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c6
-rw-r--r--sound/soc/fsl/p1022_ds.c6
-rw-r--r--sound/soc/fsl/p1022_rdk.c6
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c6
-rw-r--r--sound/soc/generic/test-component.c6
-rw-r--r--sound/soc/img/img-i2s-in.c6
-rw-r--r--sound/soc/img/img-i2s-out.c6
-rw-r--r--sound/soc/img/img-parallel-out.c6
-rw-r--r--sound/soc/img/img-spdif-in.c6
-rw-r--r--sound/soc/img/img-spdif-out.c6
-rw-r--r--sound/soc/img/pistachio-internal-dac.c6
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c5
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c5
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c5
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c5
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c5
-rw-r--r--sound/soc/intel/boards/bytcr_wm5102.c5
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c6
-rw-r--r--sound/soc/intel/boards/sof_es8336.c6
-rw-r--r--sound/soc/intel/boards/sof_pcm512x.c6
-rw-r--r--sound/soc/intel/boards/sof_sdw.c6
-rw-r--r--sound/soc/intel/boards/sof_wm8804.c5
-rw-r--r--sound/soc/intel/catpt/device.c6
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.c6
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c6
-rw-r--r--sound/soc/mediatek/common/mtk-btcvsd.c5
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c6
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-afe-pcm.c6
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-afe-pcm.c5
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-afe-pcm.c6
-rw-r--r--sound/soc/mediatek/mt8188/mt8188-afe-pcm.c6
-rw-r--r--sound/soc/mediatek/mt8192/mt8192-afe-pcm.c5
-rw-r--r--sound/soc/mediatek/mt8195/mt8195-afe-pcm.c5
-rw-r--r--sound/soc/meson/aiu.c6
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c6
-rw-r--r--sound/soc/pxa/mmp-sspa.c7
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c5
-rw-r--r--sound/soc/qcom/qdsp6/q6routing.c6
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c6
-rw-r--r--sound/soc/rockchip/rockchip_pdm.c6
-rw-r--r--sound/soc/rockchip/rockchip_rt5645.c6
-rw-r--r--sound/soc/rockchip/rockchip_spdif.c6
-rw-r--r--sound/soc/samsung/arndale.c5
-rw-r--r--sound/soc/samsung/i2s.c8
-rw-r--r--sound/soc/samsung/odroid.c6
-rw-r--r--sound/soc/samsung/pcm.c6
-rw-r--r--sound/soc/samsung/snow.c6
-rw-r--r--sound/soc/samsung/spdif.c6
-rw-r--r--sound/soc/sh/fsi.c6
-rw-r--r--sound/soc/sh/hac.c5
-rw-r--r--sound/soc/sh/rcar/core.c6
-rw-r--r--sound/soc/sh/rz-ssi.c6
-rw-r--r--sound/soc/sh/siu_dai.c5
-rw-r--r--sound/soc/sof/ipc4-control.c13
-rw-r--r--sound/soc/sprd/sprd-mcdt.c6
-rw-r--r--sound/soc/stm/stm32_adfsdm.c6
-rw-r--r--sound/soc/stm/stm32_i2s.c6
-rw-r--r--sound/soc/stm/stm32_sai_sub.c6
-rw-r--r--sound/soc/stm/stm32_spdifrx.c6
-rw-r--r--sound/soc/sunxi/sun4i-codec.c6
-rw-r--r--sound/soc/sunxi/sun4i-i2s.c6
-rw-r--r--sound/soc/sunxi/sun4i-spdif.c6
-rw-r--r--sound/soc/sunxi/sun50i-dmic.c6
-rw-r--r--sound/soc/sunxi/sun8i-codec.c6
-rw-r--r--sound/soc/tegra/tegra186_asrc.c6
-rw-r--r--sound/soc/tegra/tegra186_dspk.c6
-rw-r--r--sound/soc/tegra/tegra20_ac97.c6
-rw-r--r--sound/soc/tegra/tegra20_i2s.c6
-rw-r--r--sound/soc/tegra/tegra210_admaif.c6
-rw-r--r--sound/soc/tegra/tegra210_adx.c6
-rw-r--r--sound/soc/tegra/tegra210_ahub.c6
-rw-r--r--sound/soc/tegra/tegra210_amx.c6
-rw-r--r--sound/soc/tegra/tegra210_dmic.c6
-rw-r--r--sound/soc/tegra/tegra210_i2s.c6
-rw-r--r--sound/soc/tegra/tegra210_mixer.c6
-rw-r--r--sound/soc/tegra/tegra210_mvc.c6
-rw-r--r--sound/soc/tegra/tegra210_ope.c6
-rw-r--r--sound/soc/tegra/tegra210_sfc.c6
-rw-r--r--sound/soc/tegra/tegra30_ahub.c6
-rw-r--r--sound/soc/tegra/tegra30_i2s.c6
-rw-r--r--sound/soc/ti/ams-delta.c5
-rw-r--r--sound/soc/ti/davinci-i2s.c6
-rw-r--r--sound/soc/ti/davinci-mcasp.c6
-rw-r--r--sound/soc/ti/omap-hdmi.c5
-rw-r--r--sound/soc/ti/omap-mcbsp.c6
-rw-r--r--sound/soc/uniphier/evea.c6
-rw-r--r--sound/soc/ux500/mop500.c6
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c6
-rw-r--r--sound/soc/xilinx/xlnx_formatter_pcm.c5
-rw-r--r--sound/soc/xilinx/xlnx_spdif.c5
-rw-r--r--sound/soc/xtensa/xtfpga-i2s.c5
-rw-r--r--sound/sparc/cs4231.c6
-rw-r--r--sound/sparc/dbri.c6
193 files changed, 4523 insertions, 684 deletions
diff --git a/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml b/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
index b79990cf4f9f..2ab74f995685 100644
--- a/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
+++ b/Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
@@ -50,6 +50,74 @@ properties:
maximum: 3
default: 2
+patternProperties:
+ "^cirrus,gpio-ctrl[1-3]$":
+ description:
+ GPIO pins configuration.
+ type: object
+ additionalProperties: false
+ properties:
+ gpio-dir:
+ description:
+ GPIO pin direction. Valid only when 'gpio-ctrl' is 1
+ 0 = Output
+ 1 = Input
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ minimum: 0
+ maximum: 1
+ default: 1
+ gpio-lvl:
+ description:
+ GPIO level. Valid only when 'gpio-ctrl' is 1 and 'gpio-dir' is 0
+ 0 = Low
+ 1 = High
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ minimum: 0
+ maximum: 1
+ default: 0
+ gpio-op-cfg:
+ description:
+ GPIO level. Valid only when 'gpio-ctrl' is 1 and 'gpio-dir' is 0
+ 0 = CMOS
+ 1 = Open Drain
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ minimum: 0
+ maximum: 1
+ default: 0
+ gpio-pol:
+ description:
+ GPIO output polarity select. Valid only when 'gpio-ctrl' is 1
+ and 'gpio-dir' is 0
+ 0 = Non-inverted, Active High
+ 1 = Inverted, Active Low
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ minimum: 0
+ maximum: 1
+ default: 0
+ gpio-ctrl:
+ description:
+ Defines the function of the GPIO pin.
+ GPIO1
+ 0 = High impedance input
+ 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ 2 = Pin acts as MDSYNC, direction controlled by MDSYNC
+ 3-7 = Reserved
+ GPIO2
+ 0 = High impedance input
+ 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ 2 = Pin acts as open drain INT
+ 3 = Reserved
+ 4 = Pin acts as push-pull output INT. Active low.
+ 5 = Pin acts as push-pull output INT. Active high.
+ 6,7 = Reserved
+ GPIO3
+ 0 = High impedance input
+ 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ 2-7 = Reserved
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ minimum: 0
+ maximum: 7
+ default: 0
required:
- compatible
- reg
@@ -74,5 +142,15 @@ examples:
reset-gpios = <&gpio 110 0>;
cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
CS35L45_ASP_TX_HIZ_DISABLED)>;
+ cirrus,gpio-ctrl1 {
+ gpio-ctrl = <0x2>;
+ };
+ cirrus,gpio-ctrl2 {
+ gpio-ctrl = <0x2>;
+ };
+ cirrus,gpio-ctrl3 {
+ gpio-ctrl = <0x1>;
+ gpio-dir = <0x1>;
+ };
};
};
diff --git a/MAINTAINERS b/MAINTAINERS
index 02fe90adf0af..e52938f962b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4905,6 +4905,7 @@ L: patches@opensource.cirrus.com
S: Maintained
F: Documentation/devicetree/bindings/sound/cirrus,cs*
F: include/dt-bindings/sound/cs*
+F: include/sound/cs*
F: sound/pci/hda/cs*
F: sound/pci/hda/hda_cs_dsp_ctl.*
F: sound/soc/codecs/cs*
diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c
index f558b390fbfe..513136a924cf 100644
--- a/drivers/firmware/cirrus/cs_dsp.c
+++ b/drivers/firmware/cirrus/cs_dsp.c
@@ -301,6 +301,7 @@ struct cs_dsp_ops {
static const struct cs_dsp_ops cs_dsp_adsp1_ops;
static const struct cs_dsp_ops cs_dsp_adsp2_ops[];
static const struct cs_dsp_ops cs_dsp_halo_ops;
+static const struct cs_dsp_ops cs_dsp_halo_ao_ops;
struct cs_dsp_buf {
struct list_head list;
@@ -1300,6 +1301,9 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware,
int regions = 0;
int ret, offset, type;
+ if (!firmware)
+ return 0;
+
ret = -EINVAL;
pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
@@ -2821,7 +2825,10 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_init, FW_CS_DSP);
*/
int cs_dsp_halo_init(struct cs_dsp *dsp)
{
- dsp->ops = &cs_dsp_halo_ops;
+ if (dsp->no_core_startstop)
+ dsp->ops = &cs_dsp_halo_ao_ops;
+ else
+ dsp->ops = &cs_dsp_halo_ops;
return cs_dsp_common_init(dsp);
}
@@ -3187,6 +3194,14 @@ static const struct cs_dsp_ops cs_dsp_halo_ops = {
.stop_core = cs_dsp_halo_stop_core,
};
+static const struct cs_dsp_ops cs_dsp_halo_ao_ops = {
+ .parse_sizes = cs_dsp_adsp2_parse_sizes,
+ .validate_version = cs_dsp_halo_validate_version,
+ .setup_algs = cs_dsp_halo_setup_algs,
+ .region_to_reg = cs_dsp_halo_region_to_reg,
+ .show_fw_status = cs_dsp_halo_show_fw_status,
+};
+
/**
* cs_dsp_chunk_write() - Format data to a DSP memory chunk
* @ch: Pointer to the chunk structure
diff --git a/include/dt-bindings/sound/cs35l45.h b/include/dt-bindings/sound/cs35l45.h
index 076da4b2c28d..25386af18445 100644
--- a/include/dt-bindings/sound/cs35l45.h
+++ b/include/dt-bindings/sound/cs35l45.h
@@ -17,4 +17,61 @@
#define CS35L45_ASP_TX_HIZ_UNUSED 0x1
#define CS35L45_ASP_TX_HIZ_DISABLED 0x2
+/*
+ * Optional GPIOX Sub-nodes:
+ * The cs35l45 node can have up to three "cirrus,gpio-ctrlX" ('X' = [1,2,3])
+ * sub-nodes for configuring the GPIO pins.
+ *
+ * - gpio-dir : GPIO pin direction. Valid only when 'gpio-ctrl'
+ * is 1.
+ * 0 = Output
+ * 1 = Input (Default)
+ *
+ * - gpio-lvl : GPIO level. Valid only when 'gpio-ctrl' is 1 and 'gpio-dir' is 0.
+ *
+ * 0 = Low (Default)
+ * 1 = High
+ *
+ * - gpio-op-cfg : GPIO output configuration. Valid only when 'gpio-ctrl' is 1
+ * and 'gpio-dir' is 0.
+ *
+ * 0 = CMOS (Default)
+ * 1 = Open Drain
+ *
+ * - gpio-pol : GPIO output polarity select. Valid only when 'gpio-ctrl' is 1
+ * and 'gpio-dir' is 0.
+ *
+ * 0 = Non-inverted, Active High (Default)
+ * 1 = Inverted, Active Low
+ *
+ * - gpio-invert : Defines the polarity of the GPIO pin if configured
+ * as input.
+ *
+ * 0 = Not inverted (Default)
+ * 1 = Inverted
+ *
+ * - gpio-ctrl : Defines the function of the GPIO pin.
+ *
+ * GPIO1:
+ * 0 = High impedance input (Default)
+ * 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ * 2 = Pin acts as MDSYNC, direction controlled by MDSYNC
+ * 3-7 = Reserved
+ *
+ * GPIO2:
+ * 0 = High impedance input (Default)
+ * 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ * 2 = Pin acts as open drain INT
+ * 3 = Reserved
+ * 4 = Pin acts as push-pull output INT. Active low.
+ * 5 = Pin acts as push-pull output INT. Active high.
+ * 6,7 = Reserved
+ *
+ * GPIO3:
+ * 0 = High impedance input (Default)
+ * 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ * 2-7 = Reserved
+ */
+#define CS35L45_NUM_GPIOS 0x3
+
#endif /* DT_CS35L45_H */
diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h
index cad828e21c72..29cd11d5a3cf 100644
--- a/include/linux/firmware/cirrus/cs_dsp.h
+++ b/include/linux/firmware/cirrus/cs_dsp.h
@@ -156,6 +156,7 @@ struct cs_dsp {
unsigned int sysclk_reg;
unsigned int sysclk_mask;
unsigned int sysclk_shift;
+ bool no_core_startstop;
struct list_head alg_regions;
diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h
new file mode 100644
index 000000000000..5f8ea2dfaa21
--- /dev/null
+++ b/include/sound/cs35l56.h
@@ -0,0 +1,266 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Common definitions for Cirrus Logic CS35L56 smart amp
+ *
+ * Copyright (C) 2023 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#ifndef __CS35L56_H
+#define __CS35L56_H
+
+#include <linux/firmware/cirrus/cs_dsp.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
+
+#define CS35L56_DEVID 0x0000000
+#define CS35L56_REVID 0x0000004
+#define CS35L56_RELID 0x000000C
+#define CS35L56_OTPID 0x0000010
+#define CS35L56_SFT_RESET 0x0000020
+#define CS35L56_GLOBAL_ENABLES 0x0002014
+#define CS35L56_BLOCK_ENABLES 0x0002018
+#define CS35L56_BLOCK_ENABLES2 0x000201C
+#define CS35L56_REFCLK_INPUT 0x0002C04
+#define CS35L56_GLOBAL_SAMPLE_RATE 0x0002C0C
+#define CS35L56_ASP1_ENABLES1 0x0004800
+#define CS35L56_ASP1_CONTROL1 0x0004804
+#define CS35L56_ASP1_CONTROL2 0x0004808
+#define CS35L56_ASP1_CONTROL3 0x000480C
+#define CS35L56_ASP1_FRAME_CONTROL1 0x0004810
+#define CS35L56_ASP1_FRAME_CONTROL5 0x0004820
+#define CS35L56_ASP1_DATA_CONTROL1 0x0004830
+#define CS35L56_ASP1_DATA_CONTROL5 0x0004840
+#define CS35L56_DACPCM1_INPUT 0x0004C00
+#define CS35L56_DACPCM2_INPUT 0x0004C08
+#define CS35L56_ASP1TX1_INPUT 0x0004C20
+#define CS35L56_ASP1TX2_INPUT 0x0004C24
+#define CS35L56_ASP1TX3_INPUT 0x0004C28
+#define CS35L56_ASP1TX4_INPUT 0x0004C2C
+#define CS35L56_DSP1RX1_INPUT 0x0004C40
+#define CS35L56_DSP1RX2_INPUT 0x0004C44
+#define CS35L56_SWIRE_DP3_CH1_INPUT 0x0004C70
+#define CS35L56_SWIRE_DP3_CH2_INPUT 0x0004C74
+#define CS35L56_SWIRE_DP3_CH3_INPUT 0x0004C78
+#define CS35L56_SWIRE_DP3_CH4_INPUT 0x0004C7C
+#define CS35L56_SWIRE_DP3_CH5_INPUT 0x0004C80
+#define CS35L56_SWIRE_DP3_CH6_INPUT 0x0004C84
+#define CS35L56_IRQ1_CFG 0x000E000
+#define CS35L56_IRQ1_STATUS 0x000E004
+#define CS35L56_IRQ1_EINT_1 0x000E010
+#define CS35L56_IRQ1_EINT_2 0x000E014
+#define CS35L56_IRQ1_EINT_4 0x000E01C
+#define CS35L56_IRQ1_EINT_8 0x000E02C
+#define CS35L56_IRQ1_EINT_18 0x000E054
+#define CS35L56_IRQ1_EINT_20 0x000E05C
+#define CS35L56_IRQ1_MASK_1 0x000E090
+#define CS35L56_IRQ1_MASK_2 0x000E094
+#define CS35L56_IRQ1_MASK_4 0x000E09C
+#define CS35L56_IRQ1_MASK_8 0x000E0AC
+#define CS35L56_IRQ1_MASK_18 0x000E0D4
+#define CS35L56_IRQ1_MASK_20 0x000E0DC
+#define CS35L56_DSP_VIRTUAL1_MBOX_1 0x0011020
+#define CS35L56_DSP_VIRTUAL1_MBOX_2 0x0011024
+#define CS35L56_DSP_VIRTUAL1_MBOX_3 0x0011028
+#define CS35L56_DSP_VIRTUAL1_MBOX_4 0x001102C
+#define CS35L56_DSP_VIRTUAL1_MBOX_5 0x0011030
+#define CS35L56_DSP_VIRTUAL1_MBOX_6 0x0011034
+#define CS35L56_DSP_VIRTUAL1_MBOX_7 0x0011038
+#define CS35L56_DSP_VIRTUAL1_MBOX_8 0x001103C
+#define CS35L56_DSP_RESTRICT_STS1 0x00190F0
+#define CS35L56_DSP1_XMEM_PACKED_0 0x2000000
+#define CS35L56_DSP1_XMEM_PACKED_6143 0x2005FFC
+#define CS35L56_DSP1_XMEM_UNPACKED32_0 0x2400000
+#define CS35L56_DSP1_XMEM_UNPACKED32_4095 0x2403FFC
+#define CS35L56_DSP1_SYS_INFO_ID 0x25E0000
+#define CS35L56_DSP1_SYS_INFO_END 0x25E004C
+#define CS35L56_DSP1_AHBM_WINDOW_DEBUG_0 0x25E2040
+#define CS35L56_DSP1_AHBM_WINDOW_DEBUG_1 0x25E2044
+#define CS35L56_DSP1_XMEM_UNPACKED24_0 0x2800000
+#define CS35L56_DSP1_HALO_STATE_A1 0x2801E58
+#define CS35L56_DSP1_HALO_STATE 0x28021E0
+#define CS35L56_DSP1_PM_CUR_STATE_A1 0x2804000
+#define CS35L56_DSP1_PM_CUR_STATE 0x2804308
+#define CS35L56_DSP1_XMEM_UNPACKED24_8191 0x2807FFC
+#define CS35L56_DSP1_CORE_BASE 0x2B80000
+#define CS35L56_DSP1_SCRATCH1 0x2B805C0
+#define CS35L56_DSP1_SCRATCH2 0x2B805C8
+#define CS35L56_DSP1_SCRATCH3 0x2B805D0
+#define CS35L56_DSP1_SCRATCH4 0x2B805D8
+#define CS35L56_DSP1_YMEM_PACKED_0 0x2C00000
+#define CS35L56_DSP1_YMEM_PACKED_4604 0x2C047F0
+#define CS35L56_DSP1_YMEM_UNPACKED32_0 0x3000000
+#define CS35L56_DSP1_YMEM_UNPACKED32_3070 0x3002FF8
+#define CS35L56_DSP1_YMEM_UNPACKED24_0 0x3400000
+#define CS35L56_MAIN_RENDER_USER_MUTE 0x3400024
+#define CS35L56_MAIN_RENDER_USER_VOLUME 0x340002C
+#define CS35L56_MAIN_POSTURE_NUMBER 0x3400094
+#define CS35L56_TRANSDUCER_ACTUAL_PS 0x3400150
+#define CS35L56_DSP1_YMEM_UNPACKED24_6141 0x3405FF4
+#define CS35L56_DSP1_PMEM_0 0x3800000
+#define CS35L56_DSP1_PMEM_5114 0x3804FE8
+
+/* DEVID */
+#define CS35L56_DEVID_MASK 0x00FFFFFF
+
+/* REVID */
+#define CS35L56_AREVID_MASK 0x000000F0
+#define CS35L56_MTLREVID_MASK 0x0000000F
+#define CS35L56_REVID_B0 0x000000B0
+
+/* ASP_ENABLES1 */
+#define CS35L56_ASP_RX2_EN_SHIFT 17
+#define CS35L56_ASP_RX1_EN_SHIFT 16
+#define CS35L56_ASP_TX4_EN_SHIFT 3
+#define CS35L56_ASP_TX3_EN_SHIFT 2
+#define CS35L56_ASP_TX2_EN_SHIFT 1
+#define CS35L56_ASP_TX1_EN_SHIFT 0
+
+/* ASP_CONTROL1 */
+#define CS35L56_ASP_BCLK_FREQ_MASK 0x0000003F
+#define CS35L56_ASP_BCLK_FREQ_SHIFT 0
+
+/* ASP_CONTROL2 */
+#define CS35L56_ASP_RX_WIDTH_MASK 0xFF000000
+#define CS35L56_ASP_RX_WIDTH_SHIFT 24
+#define CS35L56_ASP_TX_WIDTH_MASK 0x00FF0000
+#define CS35L56_ASP_TX_WIDTH_SHIFT 16
+#define CS35L56_ASP_FMT_MASK 0x00000700
+#define CS35L56_ASP_FMT_SHIFT 8
+#define CS35L56_ASP_BCLK_INV_MASK 0x00000040
+#define CS35L56_ASP_FSYNC_INV_MASK 0x00000004
+
+/* ASP_CONTROL3 */
+#define CS35L56_ASP1_DOUT_HIZ_CTRL_MASK 0x00000003
+
+/* ASP_DATA_CONTROL1 */
+#define CS35L56_ASP_TX_WL_MASK 0x0000003F
+
+/* ASP_DATA_CONTROL5 */
+#define CS35L56_ASP_RX_WL_MASK 0x0000003F
+
+/* ASPTXn_INPUT */
+#define CS35L56_ASP_TXn_SRC_MASK 0x0000007F
+
+/* SWIRETX[1..7]_SRC SDWTXn INPUT */
+#define CS35L56_SWIRETXn_SRC_MASK 0x0000007F
+
+/* IRQ1_STATUS */
+#define CS35L56_IRQ1_STS_MASK 0x00000001
+
+/* IRQ1_EINT_1 */
+#define CS35L56_AMP_SHORT_ERR_EINT1_MASK 0x80000000
+
+/* IRQ1_EINT_2 */
+#define CS35L56_DSP_VIRTUAL2_MBOX_WR_EINT1_MASK 0x00200000
+
+/* IRQ1_EINT_4 */
+#define CS35L56_OTP_BOOT_DONE_MASK 0x00000002
+
+/* IRQ1_EINT_8 */
+#define CS35L56_TEMP_ERR_EINT1_MASK 0x80000000
+
+/* Mixer input sources */
+#define CS35L56_INPUT_SRC_NONE 0x00
+#define CS35L56_INPUT_SRC_ASP1RX1 0x08
+#define CS35L56_INPUT_SRC_ASP1RX2 0x09
+#define CS35L56_INPUT_SRC_VMON 0x18
+#define CS35L56_INPUT_SRC_IMON 0x19
+#define CS35L56_INPUT_SRC_ERR_VOL 0x20
+#define CS35L56_INPUT_SRC_CLASSH 0x21
+#define CS35L56_INPUT_SRC_VDDBMON 0x28
+#define CS35L56_INPUT_SRC_VBSTMON 0x29
+#define CS35L56_INPUT_SRC_DSP1TX1 0x32
+#define CS35L56_INPUT_SRC_DSP1TX2 0x33
+#define CS35L56_INPUT_SRC_DSP1TX3 0x34
+#define CS35L56_INPUT_SRC_DSP1TX4 0x35
+#define CS35L56_INPUT_SRC_DSP1TX5 0x36
+#define CS35L56_INPUT_SRC_DSP1TX6 0x37
+#define CS35L56_INPUT_SRC_DSP1TX7 0x38
+#define CS35L56_INPUT_SRC_DSP1TX8 0x39
+#define CS35L56_INPUT_SRC_TEMPMON 0x3A
+#define CS35L56_INPUT_SRC_INTERPOLATOR 0x40
+#define CS35L56_INPUT_SRC_SWIRE_RX1 0x44
+#define CS35L56_INPUT_SRC_SWIRE_RX2 0x45
+#define CS35L56_INPUT_SRC_SWIRE_RX3 0x46
+#define CS35L56_INPUT_MASK 0x7F
+
+#define CS35L56_NUM_INPUT_SRC 22
+
+/* ASP formats */
+#define CS35L56_ASP_FMT_DSP_A 0
+#define CS35L56_ASP_FMT_I2S 2
+
+/* ASP HiZ modes */
+#define CS35L56_ASP_UNUSED_HIZ_OFF_HIZ 3
+
+/* MAIN_RENDER_ACTUAL_PS */
+#define CS35L56_PS0 0
+#define CS35L56_PS3 3
+
+/* CS35L56_DSP_RESTRICT_STS1 */
+#define CS35L56_RESTRICTED_MASK 0x7
+
+/* CS35L56_MAIN_RENDER_USER_MUTE */
+#define CS35L56_MAIN_RENDER_USER_MUTE_MASK 1
+
+/* CS35L56_MAIN_RENDER_USER_VOLUME */
+#define CS35L56_MAIN_RENDER_USER_VOLUME_MIN -400
+#define CS35L56_MAIN_RENDER_USER_VOLUME_MAX 400
+#define CS35L56_MAIN_RENDER_USER_VOLUME_MASK 0x0000FFC0
+#define CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT 6
+#define CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT 9
+
+/* CS35L56_MAIN_POSTURE_NUMBER */
+#define CS35L56_MAIN_POSTURE_MIN 0
+#define CS35L56_MAIN_POSTURE_MAX 255
+#define CS35L56_MAIN_POSTURE_MASK CS35L56_MAIN_POSTURE_MAX
+
+/* Software Values */
+#define CS35L56_HALO_STATE_SHUTDOWN 1
+#define CS35L56_HALO_STATE_BOOT_DONE 2
+
+#define CS35L56_MBOX_CMD_AUDIO_PLAY 0x0B000001
+#define CS35L56_MBOX_CMD_AUDIO_PAUSE 0x0B000002
+#define CS35L56_MBOX_CMD_HIBERNATE_NOW 0x02000001
+#define CS35L56_MBOX_CMD_WAKEUP 0x02000002
+#define CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE 0x02000003
+#define CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE 0x02000004
+#define CS35L56_MBOX_CMD_SHUTDOWN 0x02000005
+#define CS35L56_MBOX_CMD_SYSTEM_RESET 0x02000007
+
+#define CS35L56_MBOX_TIMEOUT_US 5000
+#define CS35L56_MBOX_POLL_US 250
+
+#define CS35L56_PS0_POLL_US 500
+#define CS35L56_PS0_TIMEOUT_US 50000
+#define CS35L56_PS3_POLL_US 500
+#define CS35L56_PS3_TIMEOUT_US 300000
+
+#define CS35L56_CONTROL_PORT_READY_US 2200
+#define CS35L56_HALO_STATE_POLL_US 1000
+#define CS35L56_HALO_STATE_TIMEOUT_US 50000
+#define CS35L56_HIBERNATE_WAKE_POLL_US 500
+#define CS35L56_HIBERNATE_WAKE_TIMEOUT_US 5000
+#define CS35L56_RESET_PULSE_MIN_US 1100
+
+#define CS35L56_SDW1_PLAYBACK_PORT 1
+#define CS35L56_SDW1_CAPTURE_PORT 3
+
+#define CS35L56_NUM_BULK_SUPPLIES 3
+#define CS35L56_NUM_DSP_REGIONS 5
+
+extern struct regmap_config cs35l56_regmap_i2c;
+extern struct regmap_config cs35l56_regmap_spi;
+extern struct regmap_config cs35l56_regmap_sdw;
+
+extern const struct cs_dsp_region cs35l56_dsp1_regions[CS35L56_NUM_DSP_REGIONS];
+extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
+extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
+
+void cs35l56_patch(struct device *dev, struct regmap *regmap, u8 revid);
+void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap);
+int cs35l56_get_bclk_freq_id(unsigned int freq);
+void cs35l56_fill_supply_names(struct regulator_bulk_data *data);
+
+#endif /* ifndef __CS35L56_H */
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index c162086455ad..2d83ad91f968 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -262,7 +262,7 @@ err_dev:
return ret;
}
-static int pxa2xx_ac97_remove(struct platform_device *dev)
+static void pxa2xx_ac97_remove(struct platform_device *dev)
{
struct snd_card *card = platform_get_drvdata(dev);
@@ -270,13 +270,11 @@ static int pxa2xx_ac97_remove(struct platform_device *dev)
snd_card_free(card);
pxa2xx_ac97_hw_remove(dev);
}
-
- return 0;
}
static struct platform_driver pxa2xx_ac97_driver = {
.probe = pxa2xx_ac97_probe,
- .remove = pxa2xx_ac97_remove,
+ .remove_new = pxa2xx_ac97_remove,
.driver = {
.name = "pxa2xx-ac97",
#ifdef CONFIG_PM_SLEEP
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 66ecbd4d034e..c8912b8a1dc5 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -843,7 +843,7 @@ static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume
#define ATMEL_AC97C_PM_OPS NULL
#endif
-static int atmel_ac97c_remove(struct platform_device *pdev)
+static void atmel_ac97c_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
struct atmel_ac97c *chip = get_chip(card);
@@ -858,13 +858,11 @@ static int atmel_ac97c_remove(struct platform_device *pdev)
free_irq(chip->irq, chip);
snd_card_free(card);
-
- return 0;
}
static struct platform_driver atmel_ac97c_driver = {
.probe = atmel_ac97c_probe,
- .remove = atmel_ac97c_remove,
+ .remove_new = atmel_ac97c_remove,
.driver = {
.name = "atmel_ac97c",
.pm = ATMEL_AC97C_PM_OPS,
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index f0d34cf70c3e..5cfd0e99a13f 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -999,19 +999,17 @@ __err:
return err;
}
-static int snd_mts64_remove(struct platform_device *pdev)
+static void snd_mts64_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
if (card)
snd_card_free(card);
-
- return 0;
}
static struct platform_driver snd_mts64_driver = {
.probe = snd_mts64_probe,
- .remove = snd_mts64_remove,
+ .remove_new = snd_mts64_remove,
.driver = {
.name = PLATFORM_DRIVER,
}
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 52a656735365..a515c13a489f 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -795,20 +795,18 @@ __err:
return err;
}
-static int snd_portman_remove(struct platform_device *pdev)
+static void snd_portman_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
if (card)
snd_card_free(card);
-
- return 0;
}
static struct platform_driver snd_portman_driver = {
.probe = snd_portman_probe,
- .remove = snd_portman_remove,
+ .remove_new = snd_portman_remove,
.driver = {
.name = PLATFORM_DRIVER,
}
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index 9ac9b58d7c8c..3c26334227bb 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -877,17 +877,16 @@ static int hal2_probe(struct platform_device *pdev)
return 0;
}
-static int hal2_remove(struct platform_device *pdev)
+static void hal2_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
snd_card_free(card);
- return 0;
}
static struct platform_driver hal2_driver = {
.probe = hal2_probe,
- .remove = hal2_remove,
+ .remove_new = hal2_remove,
.driver = {
.name = "sgihal2",
}
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index 989f656e2de7..a8551ccdd1bf 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -908,17 +908,16 @@ static int snd_sgio2audio_probe(struct platform_device *pdev)
return 0;
}
-static int snd_sgio2audio_remove(struct platform_device *pdev)
+static void snd_sgio2audio_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
snd_card_free(card);
- return 0;
}
static struct platform_driver sgio2audio_driver = {
.probe = snd_sgio2audio_probe,
- .remove = snd_sgio2audio_remove,
+ .remove_new = snd_sgio2audio_remove,
.driver = {
.name = "sgio2audio",
}
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index c2bf86781894..9d0ab043880b 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -580,12 +580,10 @@ static void hda_tegra_probe_work(struct work_struct *work)
return; /* no error return from async probe */
}
-static int hda_tegra_remove(struct platform_device *pdev)
+static void hda_tegra_remove(struct platform_device *pdev)
{
snd_card_free(dev_get_drvdata(&pdev->dev));
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static void hda_tegra_shutdown(struct platform_device *pdev)
@@ -607,7 +605,7 @@ static struct platform_driver tegra_platform_hda = {
.of_match_table = hda_tegra_match,
},
.probe = hda_tegra_probe,
- .remove = hda_tegra_remove,
+ .remove_new = hda_tegra_remove,
.shutdown = hda_tegra_shutdown,
};
module_platform_driver(tegra_platform_hda);
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index db414b61157e..e17af46abddd 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -130,10 +130,9 @@ __error:
}
-static int snd_pmac_remove(struct platform_device *devptr)
+static void snd_pmac_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -161,7 +160,7 @@ static SIMPLE_DEV_PM_OPS(snd_pmac_pm, snd_pmac_driver_suspend, snd_pmac_driver_r
static struct platform_driver snd_pmac_driver = {
.probe = snd_pmac_probe,
- .remove = snd_pmac_remove,
+ .remove_new = snd_pmac_remove,
.driver = {
.name = SND_PMAC_DRIVER,
.pm = SND_PMAC_PM_OPS,
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 6e9d6bd67369..320ac792c7fe 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -539,15 +539,12 @@ static int add_aicamixer_controls(struct snd_card_aica *dreamcastcard)
return 0;
}
-static int snd_aica_remove(struct platform_device *devptr)
+static void snd_aica_remove(struct platform_device *devptr)
{
struct snd_card_aica *dreamcastcard;
dreamcastcard = platform_get_drvdata(devptr);
- if (unlikely(!dreamcastcard))
- return -ENODEV;
snd_card_free(dreamcastcard->card);
kfree(dreamcastcard);
- return 0;
}
static int snd_aica_probe(struct platform_device *devptr)
@@ -594,7 +591,7 @@ static int snd_aica_probe(struct platform_device *devptr)
static struct platform_driver snd_aica_driver = {
.probe = snd_aica_probe,
- .remove = snd_aica_remove,
+ .remove_new = snd_aica_remove,
.driver = {
.name = SND_AICA_DRIVER,
},
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index 8ebd972846ac..8cf571955c9d 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -257,10 +257,9 @@ static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
/* driver .remove -- destructor */
-static int snd_sh_dac_remove(struct platform_device *devptr)
+static void snd_sh_dac_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
- return 0;
}
/* free -- it has been defined by create */
@@ -403,7 +402,7 @@ probe_error:
*/
static struct platform_driver sh_dac_driver = {
.probe = snd_sh_dac_probe,
- .remove = snd_sh_dac_remove,
+ .remove_new = snd_sh_dac_remove,
.driver = {
.name = "dac_audio",
},
diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c
index b1342351bff4..d5b6f5187f8e 100644
--- a/sound/soc/adi/axi-i2s.c
+++ b/sound/soc/adi/axi-i2s.c
@@ -274,13 +274,11 @@ err_clk_disable:
return ret;
}
-static int axi_i2s_dev_remove(struct platform_device *pdev)
+static void axi_i2s_dev_remove(struct platform_device *pdev)
{
struct axi_i2s *i2s = platform_get_drvdata(pdev);
clk_disable_unprepare(i2s->clk);
-
- return 0;
}
static const struct of_device_id axi_i2s_of_match[] = {
@@ -295,7 +293,7 @@ static struct platform_driver axi_i2s_driver = {
.of_match_table = axi_i2s_of_match,
},
.probe = axi_i2s_probe,
- .remove = axi_i2s_dev_remove,
+ .remove_new = axi_i2s_dev_remove,
};
module_platform_driver(axi_i2s_driver);
diff --git a/sound/soc/adi/axi-spdif.c b/sound/soc/adi/axi-spdif.c
index 51b968ea21da..e4c99bbc9cdd 100644
--- a/sound/soc/adi/axi-spdif.c
+++ b/sound/soc/adi/axi-spdif.c
@@ -239,13 +239,11 @@ err_clk_disable:
return ret;
}
-static int axi_spdif_dev_remove(struct platform_device *pdev)
+static void axi_spdif_dev_remove(struct platform_device *pdev)
{
struct axi_spdif *spdif = platform_get_drvdata(pdev);
clk_disable_unprepare(spdif->clk);
-
- return 0;
}
static const struct of_device_id axi_spdif_of_match[] = {
@@ -260,7 +258,7 @@ static struct platform_driver axi_spdif_driver = {
.of_match_table = axi_spdif_of_match,
},
.probe = axi_spdif_probe,
- .remove = axi_spdif_dev_remove,
+ .remove_new = axi_spdif_dev_remove,
};
module_platform_driver(axi_spdif_driver);
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index 198358d28ea9..d41df316da58 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -1323,7 +1323,7 @@ static int acp_audio_probe(struct platform_device *pdev)
return status;
}
-static int acp_audio_remove(struct platform_device *pdev)
+static void acp_audio_remove(struct platform_device *pdev)
{
int status;
struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev);
@@ -1332,8 +1332,6 @@ static int acp_audio_remove(struct platform_device *pdev)
if (status)
dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static int acp_pcm_resume(struct device *dev)
@@ -1428,7 +1426,7 @@ static const struct dev_pm_ops acp_pm_ops = {
static struct platform_driver acp_dma_driver = {
.probe = acp_audio_probe,
- .remove = acp_audio_remove,
+ .remove_new = acp_audio_remove,
.driver = {
.name = DRV_NAME,
.pm = &acp_pm_ops,
diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c
index 2b57c0ca4e99..5c455cc04113 100644
--- a/sound/soc/amd/acp/acp-rembrandt.c
+++ b/sound/soc/amd/acp/acp-rembrandt.c
@@ -366,28 +366,21 @@ static int rembrandt_audio_probe(struct platform_device *pdev)
return 0;
}
-static int rembrandt_audio_remove(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;
-
- chip = dev_get_platdata(&pdev->dev);
- if (!chip || !chip->base) {
- dev_err(&pdev->dev, "ACP chip data is NULL\n");
- return -ENODEV;
- }
+ struct acp_chip_info *chip = dev_get_platdata(dev);
rmb_acp_deinit(chip->base);
acp6x_disable_interrupts(adata);
acp_platform_unregister(dev);
- return 0;
}
static struct platform_driver rembrandt_driver = {
.probe = rembrandt_audio_probe,
- .remove = rembrandt_audio_remove,
+ .remove_new = rembrandt_audio_remove,
.driver = {
.name = "acp_asoc_rembrandt",
},
diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c
index 2a89a0d2e601..b3cbc7f19ec5 100644
--- a/sound/soc/amd/acp/acp-renoir.c
+++ b/sound/soc/amd/acp/acp-renoir.c
@@ -313,7 +313,7 @@ static int renoir_audio_probe(struct platform_device *pdev)
return 0;
}
-static int renoir_audio_remove(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);
@@ -329,12 +329,11 @@ static int renoir_audio_remove(struct platform_device *pdev)
dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret));
acp_platform_unregister(dev);
- return 0;
}
static struct platform_driver renoir_driver = {
.probe = renoir_audio_probe,
- .remove = renoir_audio_remove,
+ .remove_new = renoir_audio_remove,
.driver = {
.name = "acp_asoc_renoir",
},
diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c
index 454dab062e4f..46b91327168f 100644
--- a/sound/soc/amd/ps/ps-pdm-dma.c
+++ b/sound/soc/amd/ps/ps-pdm-dma.c
@@ -399,10 +399,9 @@ static int acp63_pdm_audio_probe(struct platform_device *pdev)
return 0;
}
-static int acp63_pdm_audio_remove(struct platform_device *pdev)
+static void acp63_pdm_audio_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static int __maybe_unused acp63_pdm_resume(struct device *dev)
@@ -451,7 +450,7 @@ static const struct dev_pm_ops acp63_pdm_pm_ops = {
static struct platform_driver acp63_pdm_dma_driver = {
.probe = acp63_pdm_audio_probe,
- .remove = acp63_pdm_audio_remove,
+ .remove_new = acp63_pdm_audio_remove,
.driver = {
.name = "acp_ps_pdm_dma",
.pm = &acp63_pdm_pm_ops,
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index 6aec11cf0a6a..7362dd15ad30 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -421,10 +421,9 @@ static int acp3x_audio_probe(struct platform_device *pdev)
return 0;
}
-static int acp3x_audio_remove(struct platform_device *pdev)
+static void acp3x_audio_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static int acp3x_resume(struct device *dev)
@@ -509,7 +508,7 @@ static const struct dev_pm_ops acp3x_pm_ops = {
static struct platform_driver acp3x_dma_driver = {
.probe = acp3x_audio_probe,
- .remove = acp3x_audio_remove,
+ .remove_new = acp3x_audio_remove,
.driver = {
.name = "acp3x_rv_i2s_dma",
.pm = &acp3x_pm_ops,
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index 0d8b693aecc9..4e299f96521f 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -435,10 +435,9 @@ static int acp_pdm_audio_probe(struct platform_device *pdev)
return 0;
}
-static int acp_pdm_audio_remove(struct platform_device *pdev)
+static void acp_pdm_audio_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static int acp_pdm_resume(struct device *dev)
@@ -489,7 +488,7 @@ static const struct dev_pm_ops acp_pdm_pm_ops = {
static struct platform_driver acp_pdm_dma_driver = {
.probe = acp_pdm_audio_probe,
- .remove = acp_pdm_audio_remove,
+ .remove_new = acp_pdm_audio_remove,
.driver = {
.name = "acp_rn_pdm_dma",
.pm = &acp_pdm_pm_ops,
diff --git a/sound/soc/amd/vangogh/acp5x-pcm-dma.c b/sound/soc/amd/vangogh/acp5x-pcm-dma.c
index d36bb718370f..29901ee4bfe3 100644
--- a/sound/soc/amd/vangogh/acp5x-pcm-dma.c
+++ b/sound/soc/amd/vangogh/acp5x-pcm-dma.c
@@ -415,10 +415,9 @@ static int acp5x_audio_probe(struct platform_device *pdev)
return 0;
}
-static int acp5x_audio_remove(struct platform_device *pdev)
+static void acp5x_audio_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static int __maybe_unused acp5x_pcm_resume(struct device *dev)
@@ -500,7 +499,7 @@ static const struct dev_pm_ops acp5x_pm_ops = {
static struct platform_driver acp5x_dma_driver = {
.probe = acp5x_audio_probe,
- .remove = acp5x_audio_remove,
+ .remove_new = acp5x_audio_remove,
.driver = {
.name = "acp5x_i2s_dma",
.pm = &acp5x_pm_ops,
diff --git a/sound/soc/amd/yc/acp6x-pdm-dma.c b/sound/soc/amd/yc/acp6x-pdm-dma.c
index 294dd7fb43c9..d818eba48546 100644
--- a/sound/soc/amd/yc/acp6x-pdm-dma.c
+++ b/sound/soc/amd/yc/acp6x-pdm-dma.c
@@ -388,10 +388,9 @@ static int acp6x_pdm_audio_probe(struct platform_device *pdev)
return 0;
}
-static int acp6x_pdm_audio_remove(struct platform_device *pdev)
+static void acp6x_pdm_audio_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static int __maybe_unused acp6x_pdm_resume(struct device *dev)
@@ -440,7 +439,7 @@ static const struct dev_pm_ops acp6x_pdm_pm_ops = {
static struct platform_driver acp6x_pdm_dma_driver = {
.probe = acp6x_pdm_audio_probe,
- .remove = acp6x_pdm_audio_remove,
+ .remove_new = acp6x_pdm_audio_remove,
.driver = {
.name = "acp_yc_pdm_dma",
.pm = &acp6x_pdm_pm_ops,
diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
index 64750db9b963..ce77934f3eef 100644
--- a/sound/soc/apple/mca.c
+++ b/sound/soc/apple/mca.c
@@ -1159,13 +1159,12 @@ err_release:
return ret;
}
-static int apple_mca_remove(struct platform_device *pdev)
+static void apple_mca_remove(struct platform_device *pdev)
{
struct mca_data *mca = platform_get_drvdata(pdev);
snd_soc_unregister_component(&pdev->dev);
apple_mca_release(mca);
- return 0;
}
static const struct of_device_id apple_mca_of_match[] = {
@@ -1180,7 +1179,7 @@ static struct platform_driver apple_mca_driver = {
.of_match_table = apple_mca_of_match,
},
.probe = apple_mca_probe,
- .remove = apple_mca_remove,
+ .remove_new = apple_mca_remove,
};
module_platform_driver(apple_mca_driver);
diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
index 425d66edbf86..49930baf5e4d 100644
--- a/sound/soc/atmel/atmel-i2s.c
+++ b/sound/soc/atmel/atmel-i2s.c
@@ -717,13 +717,11 @@ static int atmel_i2s_probe(struct platform_device *pdev)
return 0;
}
-static int atmel_i2s_remove(struct platform_device *pdev)
+static void atmel_i2s_remove(struct platform_device *pdev)
{
struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);
clk_disable_unprepare(dev->pclk);
-
- return 0;
}
static struct platform_driver atmel_i2s_driver = {
@@ -732,7 +730,7 @@ static struct platform_driver atmel_i2s_driver = {
.of_match_table = of_match_ptr(atmel_i2s_dt_ids),
},
.probe = atmel_i2s_probe,
- .remove = atmel_i2s_remove,
+ .remove_new = atmel_i2s_remove,
};
module_platform_driver(atmel_i2s_driver);
diff --git a/sound/soc/atmel/atmel_wm8904.c b/sound/soc/atmel/atmel_wm8904.c
index 9c974c4e187d..00e98136bec2 100644
--- a/sound/soc/atmel/atmel_wm8904.c
+++ b/sound/soc/atmel/atmel_wm8904.c
@@ -161,7 +161,7 @@ err_set_audio:
return ret;
}
-static int atmel_asoc_wm8904_remove(struct platform_device *pdev)
+static void atmel_asoc_wm8904_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
@@ -171,8 +171,6 @@ static int atmel_asoc_wm8904_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
atmel_ssc_put_audio(id);
-
- return 0;
}
#ifdef CONFIG_OF
@@ -190,7 +188,7 @@ static struct platform_driver atmel_asoc_wm8904_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = atmel_asoc_wm8904_probe,
- .remove = atmel_asoc_wm8904_remove,
+ .remove_new = atmel_asoc_wm8904_remove,
};
module_platform_driver(atmel_asoc_wm8904_driver);
diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c
index 6dfb96c576ff..7c83d48ca1a0 100644
--- a/sound/soc/atmel/mchp-i2s-mcc.c
+++ b/sound/soc/atmel/mchp-i2s-mcc.c
@@ -1088,13 +1088,11 @@ static int mchp_i2s_mcc_probe(struct platform_device *pdev)
return 0;
}
-static int mchp_i2s_mcc_remove(struct platform_device *pdev)
+static void mchp_i2s_mcc_remove(struct platform_device *pdev)
{
struct mchp_i2s_mcc_dev *dev = platform_get_drvdata(pdev);
clk_disable_unprepare(dev->pclk);
-
- return 0;
}
static struct platform_driver mchp_i2s_mcc_driver = {
@@ -1103,7 +1101,7 @@ static struct platform_driver mchp_i2s_mcc_driver = {
.of_match_table = of_match_ptr(mchp_i2s_mcc_dt_ids),
},
.probe = mchp_i2s_mcc_probe,
- .remove = mchp_i2s_mcc_remove,
+ .remove_new = mchp_i2s_mcc_remove,
};
module_platform_driver(mchp_i2s_mcc_driver);
diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c
index 81bfa98fd516..da23855a0e40 100644
--- a/sound/soc/atmel/mchp-pdmc.c
+++ b/sound/soc/atmel/mchp-pdmc.c
@@ -1129,7 +1129,7 @@ pm_runtime_suspend:
return ret;
}
-static int mchp_pdmc_remove(struct platform_device *pdev)
+static void mchp_pdmc_remove(struct platform_device *pdev)
{
struct mchp_pdmc *dd = platform_get_drvdata(pdev);
@@ -1137,8 +1137,6 @@ static int mchp_pdmc_remove(struct platform_device *pdev)
mchp_pdmc_runtime_suspend(dd->dev);
pm_runtime_disable(dd->dev);
-
- return 0;
}
static const struct of_device_id mchp_pdmc_of_match[] = {
@@ -1163,7 +1161,7 @@ static struct platform_driver mchp_pdmc_driver = {
.pm = pm_ptr(&mchp_pdmc_pm_ops),
},
.probe = mchp_pdmc_probe,
- .remove = mchp_pdmc_remove,
+ .remove_new = mchp_pdmc_remove,
};
module_platform_driver(mchp_pdmc_driver);
diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
index eb0c0ef4541e..ff6aba143aee 100644
--- a/sound/soc/atmel/mchp-spdifrx.c
+++ b/sound/soc/atmel/mchp-spdifrx.c
@@ -1183,20 +1183,18 @@ pm_runtime_disable:
return err;
}
-static int mchp_spdifrx_remove(struct platform_device *pdev)
+static void mchp_spdifrx_remove(struct platform_device *pdev)
{
struct mchp_spdifrx_dev *dev = platform_get_drvdata(pdev);
pm_runtime_disable(dev->dev);
if (!pm_runtime_status_suspended(dev->dev))
mchp_spdifrx_runtime_suspend(dev->dev);
-
- return 0;
}
static struct platform_driver mchp_spdifrx_driver = {
.probe = mchp_spdifrx_probe,
- .remove = mchp_spdifrx_remove,
+ .remove_new = mchp_spdifrx_remove,
.driver = {
.name = "mchp_spdifrx",
.of_match_table = of_match_ptr(mchp_spdifrx_dt_ids),
diff --git a/sound/soc/atmel/mchp-spdiftx.c b/sound/soc/atmel/mchp-spdiftx.c
index 02a2fa7a42dd..1d3e17119888 100644
--- a/sound/soc/atmel/mchp-spdiftx.c
+++ b/sound/soc/atmel/mchp-spdiftx.c
@@ -876,7 +876,7 @@ pm_runtime_suspend:
return err;
}
-static int mchp_spdiftx_remove(struct platform_device *pdev)
+static void mchp_spdiftx_remove(struct platform_device *pdev)
{
struct mchp_spdiftx_dev *dev = platform_get_drvdata(pdev);
@@ -884,13 +884,11 @@ static int mchp_spdiftx_remove(struct platform_device *pdev)
mchp_spdiftx_runtime_suspend(dev->dev);
pm_runtime_disable(dev->dev);
-
- return 0;
}
static struct platform_driver mchp_spdiftx_driver = {
.probe = mchp_spdiftx_probe,
- .remove = mchp_spdiftx_remove,
+ .remove_new = mchp_spdiftx_remove,
.driver = {
.name = "mchp_spdiftx",
.of_match_table = of_match_ptr(mchp_spdiftx_dt_ids),
diff --git a/sound/soc/atmel/mikroe-proto.c b/sound/soc/atmel/mikroe-proto.c
index 954460719aa3..30c87c2c1b0b 100644
--- a/sound/soc/atmel/mikroe-proto.c
+++ b/sound/soc/atmel/mikroe-proto.c
@@ -155,11 +155,9 @@ put_codec_node:
return ret;
}
-static int snd_proto_remove(struct platform_device *pdev)
+static void snd_proto_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&snd_proto);
-
- return 0;
}
static const struct of_device_id snd_proto_of_match[] = {
@@ -174,7 +172,7 @@ static struct platform_driver snd_proto_driver = {
.of_match_table = snd_proto_of_match,
},
.probe = snd_proto_probe,
- .remove = snd_proto_remove,
+ .remove_new = snd_proto_remove,
};
module_platform_driver(snd_proto_driver);
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 785b9d01d8af..baf38964b491 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -186,14 +186,12 @@ err:
return ret;
}
-static int at91sam9g20ek_audio_remove(struct platform_device *pdev)
+static void at91sam9g20ek_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
atmel_ssc_put_audio(0);
-
- return 0;
}
#ifdef CONFIG_OF
@@ -210,7 +208,7 @@ static struct platform_driver at91sam9g20ek_audio_driver = {
.of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids),
},
.probe = at91sam9g20ek_audio_probe,
- .remove = at91sam9g20ek_audio_remove,
+ .remove_new = at91sam9g20ek_audio_remove,
};
module_platform_driver(at91sam9g20ek_audio_driver);
diff --git a/sound/soc/atmel/sam9x5_wm8731.c b/sound/soc/atmel/sam9x5_wm8731.c
index 99310e40e7a6..cd1d59a90e02 100644
--- a/sound/soc/atmel/sam9x5_wm8731.c
+++ b/sound/soc/atmel/sam9x5_wm8731.c
@@ -176,14 +176,12 @@ out:
return ret;
}
-static int sam9x5_wm8731_driver_remove(struct platform_device *pdev)
+static void sam9x5_wm8731_driver_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct sam9x5_drvdata *priv = card->drvdata;
atmel_ssc_put_audio(priv->ssc_id);
-
- return 0;
}
static const struct of_device_id sam9x5_wm8731_of_match[] = {
@@ -198,7 +196,7 @@ static struct platform_driver sam9x5_wm8731_driver = {
.of_match_table = of_match_ptr(sam9x5_wm8731_of_match),
},
.probe = sam9x5_wm8731_driver_probe,
- .remove = sam9x5_wm8731_driver_remove,
+ .remove_new = sam9x5_wm8731_driver_remove,
};
module_platform_driver(sam9x5_wm8731_driver);
diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c
index ef537de7719c..efead272d92b 100644
--- a/sound/soc/atmel/tse850-pcm5142.c
+++ b/sound/soc/atmel/tse850-pcm5142.c
@@ -412,15 +412,13 @@ err_disable_ana:
return ret;
}
-static int tse850_remove(struct platform_device *pdev)
+static void tse850_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card);
regulator_disable(tse850->ana);
-
- return 0;
}
static const struct of_device_id tse850_dt_ids[] = {
@@ -435,7 +433,7 @@ static struct platform_driver tse850_driver = {
.of_match_table = of_match_ptr(tse850_dt_ids),
},
.probe = tse850_probe,
- .remove = tse850_remove,
+ .remove_new = tse850_remove,
};
module_platform_driver(tse850_driver);
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index b18512ca2578..a11d6841afc2 100644
--- a/sound/soc/au1x/ac97c.c
+++ b/sound/soc/au1x/ac97c.c
@@ -285,7 +285,7 @@ static int au1xac97c_drvprobe(struct platform_device *pdev)
return 0;
}
-static int au1xac97c_drvremove(struct platform_device *pdev)
+static void au1xac97c_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
@@ -294,8 +294,6 @@ static int au1xac97c_drvremove(struct platform_device *pdev)
WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
ac97c_workdata = NULL; /* MDEV */
-
- return 0;
}
#ifdef CONFIG_PM
@@ -338,7 +336,7 @@ static struct platform_driver au1xac97c_driver = {
.pm = AU1XPSCAC97_PMOPS,
},
.probe = au1xac97c_drvprobe,
- .remove = au1xac97c_drvremove,
+ .remove_new = au1xac97c_drvremove,
};
module_platform_driver(au1xac97c_driver);
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
index b15c8baa9ee4..064406080d72 100644
--- a/sound/soc/au1x/i2sc.c
+++ b/sound/soc/au1x/i2sc.c
@@ -270,15 +270,13 @@ static int au1xi2s_drvprobe(struct platform_device *pdev)
&au1xi2s_dai_driver, 1);
}
-static int au1xi2s_drvremove(struct platform_device *pdev)
+static void au1xi2s_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
snd_soc_unregister_component(&pdev->dev);
WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
-
- return 0;
}
#ifdef CONFIG_PM
@@ -315,7 +313,7 @@ static struct platform_driver au1xi2s_driver = {
.pm = AU1XI2SC_PMOPS,
},
.probe = au1xi2s_drvprobe,
- .remove = au1xi2s_drvremove,
+ .remove_new = au1xi2s_drvremove,
};
module_platform_driver(au1xi2s_driver);
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index b536394b9ca0..9fd91aea7d1a 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -421,7 +421,7 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
return 0;
}
-static int au1xpsc_ac97_drvremove(struct platform_device *pdev)
+static void au1xpsc_ac97_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
@@ -434,8 +434,6 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev)
wmb(); /* drain writebuffer */
au1xpsc_ac97_workdata = NULL; /* MDEV */
-
- return 0;
}
#ifdef CONFIG_PM
@@ -488,7 +486,7 @@ static struct platform_driver au1xpsc_ac97_driver = {
.pm = AU1XPSCAC97_PMOPS,
},
.probe = au1xpsc_ac97_drvprobe,
- .remove = au1xpsc_ac97_drvremove,
+ .remove_new = au1xpsc_ac97_drvremove,
};
module_platform_driver(au1xpsc_ac97_driver);
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 79b5ae4e494c..52734dec8247 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -344,7 +344,7 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
&au1xpsc_i2s_component, &wd->dai_drv, 1);
}
-static int au1xpsc_i2s_drvremove(struct platform_device *pdev)
+static void au1xpsc_i2s_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
@@ -352,8 +352,6 @@ static int au1xpsc_i2s_drvremove(struct platform_device *pdev)
wmb(); /* drain writebuffer */
__raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
wmb(); /* drain writebuffer */
-
- return 0;
}
#ifdef CONFIG_PM
@@ -406,7 +404,7 @@ static struct platform_driver au1xpsc_i2s_driver = {
.pm = AU1XPSCI2S_PMOPS,
},
.probe = au1xpsc_i2s_drvprobe,
- .remove = au1xpsc_i2s_drvremove,
+ .remove_new = au1xpsc_i2s_drvremove,
};
module_platform_driver(au1xpsc_i2s_driver);
diff --git a/sound/soc/bcm/bcm63xx-i2s-whistler.c b/sound/soc/bcm/bcm63xx-i2s-whistler.c
index 2da1384ffe91..18c51dbbc8dc 100644
--- a/sound/soc/bcm/bcm63xx-i2s-whistler.c
+++ b/sound/soc/bcm/bcm63xx-i2s-whistler.c
@@ -289,10 +289,9 @@ static int bcm63xx_i2s_dev_probe(struct platform_device *pdev)
return ret;
}
-static int bcm63xx_i2s_dev_remove(struct platform_device *pdev)
+static void bcm63xx_i2s_dev_remove(struct platform_device *pdev)
{
bcm63xx_soc_platform_remove(pdev);
- return 0;
}
#ifdef CONFIG_OF
@@ -308,7 +307,7 @@ static struct platform_driver bcm63xx_i2s_driver = {
.of_match_table = of_match_ptr(snd_soc_bcm_audio_match),
},
.probe = bcm63xx_i2s_dev_probe,
- .remove = bcm63xx_i2s_dev_remove,
+ .remove_new = bcm63xx_i2s_dev_remove,
};
module_platform_driver(bcm63xx_i2s_driver);
diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c
index 2a92e33e1fbf..8638bf22ef5c 100644
--- a/sound/soc/bcm/cygnus-ssp.c
+++ b/sound/soc/bcm/cygnus-ssp.c
@@ -1377,11 +1377,9 @@ static int cygnus_ssp_probe(struct platform_device *pdev)
return 0;
}
-static int cygnus_ssp_remove(struct platform_device *pdev)
+static void cygnus_ssp_remove(struct platform_device *pdev)
{
cygnus_soc_platform_unregister(&pdev->dev);
-
- return 0;
}
static const struct of_device_id cygnus_ssp_of_match[] = {
@@ -1392,7 +1390,7 @@ MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match);
static struct platform_driver cygnus_ssp_driver = {
.probe = cygnus_ssp_probe,
- .remove = cygnus_ssp_remove,
+ .remove_new = cygnus_ssp_remove,
.driver = {
.name = "cygnus-ssp",
.of_match_table = cygnus_ssp_of_match,
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index 385290202912..f49caab21a25 100644
--- a/sound/soc/cirrus/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
@@ -93,14 +93,12 @@ static int edb93xx_probe(struct platform_device *pdev)
return ret;
}
-static int edb93xx_remove(struct platform_device *pdev)
+static void edb93xx_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
ep93xx_i2s_release();
-
- return 0;
}
static struct platform_driver edb93xx_driver = {
@@ -108,7 +106,7 @@ static struct platform_driver edb93xx_driver = {
.name = "edb93xx-audio",
},
.probe = edb93xx_probe,
- .remove = edb93xx_remove,
+ .remove_new = edb93xx_remove,
};
module_platform_driver(edb93xx_driver);
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 70840f27d4a7..9760453d9d79 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -495,19 +495,18 @@ fail:
return err;
}
-static int ep93xx_i2s_remove(struct platform_device *pdev)
+static void ep93xx_i2s_remove(struct platform_device *pdev)
{
struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
clk_put(info->lrclk);
clk_put(info->sclk);
clk_put(info->mclk);
- return 0;
}
static struct platform_driver ep93xx_i2s_driver = {
.probe = ep93xx_i2s_probe,
- .remove = ep93xx_i2s_remove,
+ .remove_new = ep93xx_i2s_remove,
.driver = {
.name = "ep93xx-i2s",
},
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 07747565c3b5..03630d13d35f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -68,6 +68,9 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_CS35L41_I2C
imply SND_SOC_CS35L45_I2C
imply SND_SOC_CS35L45_SPI
+ imply SND_SOC_CS35L56_I2C
+ imply SND_SOC_CS35L56_SPI
+ imply SND_SOC_CS35L56_SDW
imply SND_SOC_CS42L42
imply SND_SOC_CS42L42_SDW
imply SND_SOC_CS42L51_I2C
@@ -364,6 +367,9 @@ config SND_SOC_WM_ADSP
default y if SND_SOC_WM2200=y
default y if SND_SOC_CS35L41_SPI=y
default y if SND_SOC_CS35L41_I2C=y
+ default y if SND_SOC_CS35L45_SPI=y
+ default y if SND_SOC_CS35L45_I2C=y
+ default y if SND_SOC_CS35L56=y
default m if SND_SOC_MADERA=m
default m if SND_SOC_CS47L24=m
default m if SND_SOC_WM5102=m
@@ -371,6 +377,9 @@ config SND_SOC_WM_ADSP
default m if SND_SOC_WM2200=m
default m if SND_SOC_CS35L41_SPI=m
default m if SND_SOC_CS35L41_I2C=m
+ default m if SND_SOC_CS35L45_SPI=m
+ default m if SND_SOC_CS35L45_I2C=m
+ default m if SND_SOC_CS35L56=m
config SND_SOC_AB8500_CODEC
tristate
@@ -711,6 +720,41 @@ config SND_SOC_CS35L45_I2C
Enable support for Cirrus Logic CS35L45 smart speaker amplifier
with I2C control.
+config SND_SOC_CS35L56
+ tristate
+
+config SND_SOC_CS35L56_SHARED
+ tristate
+
+config SND_SOC_CS35L56_I2C
+ tristate "Cirrus Logic CS35L56 CODEC (I2C)"
+ depends on I2C
+ depends on SOUNDWIRE || !SOUNDWIRE
+ select REGMAP_I2C
+ select SND_SOC_CS35L56
+ select SND_SOC_CS35L56_SHARED
+ help
+ Enable support for Cirrus Logic CS35L56 boosted amplifier with I2C control
+
+config SND_SOC_CS35L56_SPI
+ tristate "Cirrus Logic CS35L56 CODEC (SPI)"
+ depends on SPI_MASTER
+ depends on SOUNDWIRE || !SOUNDWIRE
+ select REGMAP_SPI
+ select SND_SOC_CS35L56
+ select SND_SOC_CS35L56_SHARED
+ help
+ Enable support for Cirrus Logic CS35L56 boosted amplifier with SPI control
+
+config SND_SOC_CS35L56_SDW
+ tristate "Cirrus Logic CS35L56 CODEC (SDW)"
+ depends on SOUNDWIRE
+ select REGMAP
+ select SND_SOC_CS35L56
+ select SND_SOC_CS35L56_SHARED
+ help
+ Enable support for Cirrus Logic CS35L56 boosted amplifier with SoundWire control
+
config SND_SOC_CS42L42_CORE
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f1ca18f7946c..25ebce58a0ba 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -66,6 +66,11 @@ snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o
snd-soc-cs35l45-objs := cs35l45.o cs35l45-tables.o
snd-soc-cs35l45-spi-objs := cs35l45-spi.o
snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o
+snd-soc-cs35l56-objs := cs35l56.o
+snd-soc-cs35l56-shared-objs := cs35l56-shared.o
+snd-soc-cs35l56-i2c-objs := cs35l56-i2c.o
+snd-soc-cs35l56-spi-objs := cs35l56-spi.o
+snd-soc-cs35l56-sdw-objs := cs35l56-sdw.o
snd-soc-cs42l42-objs := cs42l42.o
snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o
snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o
@@ -433,6 +438,11 @@ obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o
obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o
obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o
obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o
+obj-$(CONFIG_SND_SOC_CS35L56) += snd-soc-cs35l56.o
+obj-$(CONFIG_SND_SOC_CS35L56_SHARED) += snd-soc-cs35l56-shared.o
+obj-$(CONFIG_SND_SOC_CS35L56_I2C) += snd-soc-cs35l56-i2c.o
+obj-$(CONFIG_SND_SOC_CS35L56_SPI) += snd-soc-cs35l56-spi.o
+obj-$(CONFIG_SND_SOC_CS35L56_SDW) += snd-soc-cs35l56-sdw.o
obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o
obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o
obj-$(CONFIG_SND_SOC_CS42L42_SDW) += snd-soc-cs42l42-sdw.o
diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index 9ec01a5f09ca..6ac501f008ec 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -150,6 +150,7 @@ static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = {
{ 5644800, 16, 24 },
{ 6000000, 16, 24 },
{ 6144000, 16, 24 },
+ { 12288000, 0, 0 },
};
static int cs35l41_get_fs_mon_config_index(int freq)
diff --git a/sound/soc/codecs/cs35l45-i2c.c b/sound/soc/codecs/cs35l45-i2c.c
index 1117df4b2f11..562f73df7afa 100644
--- a/sound/soc/codecs/cs35l45-i2c.c
+++ b/sound/soc/codecs/cs35l45-i2c.c
@@ -32,6 +32,9 @@ static int cs35l45_i2c_probe(struct i2c_client *client)
}
cs35l45->dev = dev;
+ cs35l45->irq = client->irq;
+ cs35l45->bus_type = CONTROL_BUS_I2C;
+ cs35l45->i2c_addr = client->addr;
return cs35l45_probe(cs35l45);
}
diff --git a/sound/soc/codecs/cs35l45-spi.c b/sound/soc/codecs/cs35l45-spi.c
index ffaca07fb267..a00b23b4180c 100644
--- a/sound/soc/codecs/cs35l45-spi.c
+++ b/sound/soc/codecs/cs35l45-spi.c
@@ -23,6 +23,9 @@ static int cs35l45_spi_probe(struct spi_device *spi)
if (cs35l45 == NULL)
return -ENOMEM;
+ spi->max_speed_hz = CS35L45_SPI_MAX_FREQ;
+ spi_setup(spi);
+
spi_set_drvdata(spi, cs35l45);
cs35l45->regmap = devm_regmap_init_spi(spi, &cs35l45_spi_regmap);
if (IS_ERR(cs35l45->regmap)) {
@@ -32,6 +35,8 @@ static int cs35l45_spi_probe(struct spi_device *spi)
}
cs35l45->dev = dev;
+ cs35l45->irq = spi->irq;
+ cs35l45->bus_type = CONTROL_BUS_SPI;
return cs35l45_probe(cs35l45);
}
diff --git a/sound/soc/codecs/cs35l45-tables.c b/sound/soc/codecs/cs35l45-tables.c
index 4b1320a2e6e9..46610e64e818 100644
--- a/sound/soc/codecs/cs35l45-tables.c
+++ b/sound/soc/codecs/cs35l45-tables.c
@@ -43,6 +43,12 @@ EXPORT_SYMBOL_NS_GPL(cs35l45_apply_patch, SND_SOC_CS35L45);
static const struct reg_default cs35l45_defaults[] = {
{ CS35L45_BLOCK_ENABLES, 0x00003323 },
{ CS35L45_BLOCK_ENABLES2, 0x00000010 },
+ { CS35L45_SYNC_GPIO1, 0x00000007 },
+ { CS35L45_INTB_GPIO2_MCLK_REF, 0x00000005 },
+ { CS35L45_GPIO3, 0x00000005 },
+ { CS35L45_PWRMGT_CTL, 0x00000000 },
+ { CS35L45_WAKESRC_CTL, 0x00000008 },
+ { CS35L45_WKI2C_CTL, 0x00000030 },
{ CS35L45_REFCLK_INPUT, 0x00000510 },
{ CS35L45_GLOBAL_SAMPLE_RATE, 0x00000003 },
{ CS35L45_ASP_ENABLES1, 0x00000000 },
@@ -60,7 +66,53 @@ static const struct reg_default cs35l45_defaults[] = {
{ CS35L45_ASPTX3_INPUT, 0x00000020 },
{ CS35L45_ASPTX4_INPUT, 0x00000028 },
{ CS35L45_ASPTX5_INPUT, 0x00000048 },
+ { CS35L45_DSP1_RX1_RATE, 0x00000001 },
+ { CS35L45_DSP1_RX2_RATE, 0x00000001 },
+ { CS35L45_DSP1_RX3_RATE, 0x00000001 },
+ { CS35L45_DSP1_RX4_RATE, 0x00000001 },
+ { CS35L45_DSP1_RX5_RATE, 0x00000001 },
+ { CS35L45_DSP1_RX6_RATE, 0x00000001 },
+ { CS35L45_DSP1_RX7_RATE, 0x00000001 },
+ { CS35L45_DSP1_RX8_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX1_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX2_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX3_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX4_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX5_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX6_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX7_RATE, 0x00000001 },
+ { CS35L45_DSP1_TX8_RATE, 0x00000001 },
+ { CS35L45_DSP1RX1_INPUT, 0x00000008 },
+ { CS35L45_DSP1RX2_INPUT, 0x00000009 },
+ { CS35L45_DSP1RX3_INPUT, 0x00000018 },
+ { CS35L45_DSP1RX4_INPUT, 0x00000019 },
+ { CS35L45_DSP1RX5_INPUT, 0x00000020 },
+ { CS35L45_DSP1RX6_INPUT, 0x00000028 },
+ { CS35L45_DSP1RX7_INPUT, 0x0000003A },
+ { CS35L45_DSP1RX8_INPUT, 0x00000028 },
{ CS35L45_AMP_PCM_CONTROL, 0x00100000 },
+ { CS35L45_IRQ1_CFG, 0x00000000 },
+ { CS35L45_IRQ1_MASK_1, 0xBFEFFFBF },
+ { CS35L45_IRQ1_MASK_2, 0xFFFFFFFF },
+ { CS35L45_IRQ1_MASK_3, 0xFFFF87FF },
+ { CS35L45_IRQ1_MASK_4, 0xF8FFFFFF },
+ { CS35L45_IRQ1_MASK_5, 0x0EF80000 },
+ { CS35L45_IRQ1_MASK_6, 0x00000000 },
+ { CS35L45_IRQ1_MASK_7, 0xFFFFFF78 },
+ { CS35L45_IRQ1_MASK_8, 0x00003FFF },
+ { CS35L45_IRQ1_MASK_9, 0x00000000 },
+ { CS35L45_IRQ1_MASK_10, 0x00000000 },
+ { CS35L45_IRQ1_MASK_11, 0x00000000 },
+ { CS35L45_IRQ1_MASK_12, 0x00000000 },
+ { CS35L45_IRQ1_MASK_13, 0x00000000 },
+ { CS35L45_IRQ1_MASK_14, 0x00000001 },
+ { CS35L45_IRQ1_MASK_15, 0x00000000 },
+ { CS35L45_IRQ1_MASK_16, 0x00000000 },
+ { CS35L45_IRQ1_MASK_17, 0x00000000 },
+ { CS35L45_IRQ1_MASK_18, 0x3FE5D0FF },
+ { CS35L45_GPIO1_CTRL1, 0x81000001 },
+ { CS35L45_GPIO2_CTRL1, 0x81000001 },
+ { CS35L45_GPIO3_CTRL1, 0x81000001 },
};
static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
@@ -72,6 +124,13 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
case CS35L45_BLOCK_ENABLES:
case CS35L45_BLOCK_ENABLES2:
case CS35L45_ERROR_RELEASE:
+ case CS35L45_SYNC_GPIO1:
+ case CS35L45_INTB_GPIO2_MCLK_REF:
+ case CS35L45_GPIO3:
+ case CS35L45_PWRMGT_CTL:
+ case CS35L45_WAKESRC_CTL:
+ case CS35L45_WKI2C_CTL:
+ case CS35L45_PWRMGT_STS:
case CS35L45_REFCLK_INPUT:
case CS35L45_GLOBAL_SAMPLE_RATE:
case CS35L45_ASP_ENABLES1:
@@ -89,9 +148,59 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
case CS35L45_ASPTX3_INPUT:
case CS35L45_ASPTX4_INPUT:
case CS35L45_ASPTX5_INPUT:
+ case CS35L45_DSP1RX1_INPUT:
+ case CS35L45_DSP1RX2_INPUT:
+ case CS35L45_DSP1RX3_INPUT:
+ case CS35L45_DSP1RX4_INPUT:
+ case CS35L45_DSP1RX5_INPUT:
+ case CS35L45_DSP1RX6_INPUT:
+ case CS35L45_DSP1RX7_INPUT:
+ case CS35L45_DSP1RX8_INPUT:
case CS35L45_AMP_PCM_CONTROL:
case CS35L45_AMP_PCM_HPF_TST:
- case CS35L45_IRQ1_EINT_4:
+ case CS35L45_IRQ1_CFG:
+ case CS35L45_IRQ1_STATUS:
+ case CS35L45_IRQ1_EINT_1 ... CS35L45_IRQ1_EINT_18:
+ case CS35L45_IRQ1_STS_1 ... CS35L45_IRQ1_STS_18:
+ case CS35L45_IRQ1_MASK_1 ... CS35L45_IRQ1_MASK_18:
+ case CS35L45_GPIO_STATUS1:
+ case CS35L45_GPIO1_CTRL1:
+ case CS35L45_GPIO2_CTRL1:
+ case CS35L45_GPIO3_CTRL1:
+ case CS35L45_DSP_MBOX_1:
+ case CS35L45_DSP_MBOX_2:
+ case CS35L45_DSP_VIRT1_MBOX_1 ... CS35L45_DSP_VIRT1_MBOX_4:
+ case CS35L45_DSP_VIRT2_MBOX_1 ... CS35L45_DSP_VIRT2_MBOX_4:
+ case CS35L45_DSP1_SYS_ID:
+ case CS35L45_DSP1_CLOCK_FREQ:
+ case CS35L45_DSP1_RX1_RATE:
+ case CS35L45_DSP1_RX2_RATE:
+ case CS35L45_DSP1_RX3_RATE:
+ case CS35L45_DSP1_RX4_RATE:
+ case CS35L45_DSP1_RX5_RATE:
+ case CS35L45_DSP1_RX6_RATE:
+ case CS35L45_DSP1_RX7_RATE:
+ case CS35L45_DSP1_RX8_RATE:
+ case CS35L45_DSP1_TX1_RATE:
+ case CS35L45_DSP1_TX2_RATE:
+ case CS35L45_DSP1_TX3_RATE:
+ case CS35L45_DSP1_TX4_RATE:
+ case CS35L45_DSP1_TX5_RATE:
+ case CS35L45_DSP1_TX6_RATE:
+ case CS35L45_DSP1_TX7_RATE:
+ case CS35L45_DSP1_TX8_RATE:
+ case CS35L45_DSP1_SCRATCH1:
+ case CS35L45_DSP1_SCRATCH2:
+ case CS35L45_DSP1_SCRATCH3:
+ case CS35L45_DSP1_SCRATCH4:
+ case CS35L45_DSP1_CCM_CORE_CONTROL:
+ case CS35L45_DSP1_XMEM_PACK_0 ... CS35L45_DSP1_XMEM_PACK_4607:
+ case CS35L45_DSP1_XMEM_UNPACK32_0 ... CS35L45_DSP1_XMEM_UNPACK32_3071:
+ case CS35L45_DSP1_XMEM_UNPACK24_0 ... CS35L45_DSP1_XMEM_UNPACK24_6143:
+ case CS35L45_DSP1_YMEM_PACK_0 ... CS35L45_DSP1_YMEM_PACK_1532:
+ case CS35L45_DSP1_YMEM_UNPACK32_0 ... CS35L45_DSP1_YMEM_UNPACK32_1022:
+ case CS35L45_DSP1_YMEM_UNPACK24_0 ... CS35L45_DSP1_YMEM_UNPACK24_2043:
+ case CS35L45_DSP1_PMEM_0 ... CS35L45_DSP1_PMEM_3834:
return true;
default:
return false;
@@ -106,7 +215,29 @@ static bool cs35l45_volatile_reg(struct device *dev, unsigned int reg)
case CS35L45_GLOBAL_ENABLES:
case CS35L45_ERROR_RELEASE:
case CS35L45_AMP_PCM_HPF_TST: /* not cachable */
- case CS35L45_IRQ1_EINT_4:
+ case CS35L45_PWRMGT_STS:
+ case CS35L45_IRQ1_STATUS:
+ case CS35L45_IRQ1_EINT_1 ... CS35L45_IRQ1_EINT_18:
+ case CS35L45_IRQ1_STS_1 ... CS35L45_IRQ1_STS_18:
+ case CS35L45_GPIO_STATUS1:
+ case CS35L45_DSP_MBOX_1:
+ case CS35L45_DSP_MBOX_2:
+ case CS35L45_DSP_VIRT1_MBOX_1 ... CS35L45_DSP_VIRT1_MBOX_4:
+ case CS35L45_DSP_VIRT2_MBOX_1 ... CS35L45_DSP_VIRT2_MBOX_4:
+ case CS35L45_DSP1_SYS_ID:
+ case CS35L45_DSP1_CLOCK_FREQ:
+ case CS35L45_DSP1_SCRATCH1:
+ case CS35L45_DSP1_SCRATCH2:
+ case CS35L45_DSP1_SCRATCH3:
+ case CS35L45_DSP1_SCRATCH4:
+ case CS35L45_DSP1_CCM_CORE_CONTROL:
+ case CS35L45_DSP1_XMEM_PACK_0 ... CS35L45_DSP1_XMEM_PACK_4607:
+ case CS35L45_DSP1_XMEM_UNPACK32_0 ... CS35L45_DSP1_XMEM_UNPACK32_3071:
+ case CS35L45_DSP1_XMEM_UNPACK24_0 ... CS35L45_DSP1_XMEM_UNPACK24_6143:
+ case CS35L45_DSP1_YMEM_PACK_0 ... CS35L45_DSP1_YMEM_PACK_1532:
+ case CS35L45_DSP1_YMEM_UNPACK32_0 ... CS35L45_DSP1_YMEM_UNPACK32_1022:
+ case CS35L45_DSP1_YMEM_UNPACK24_0 ... CS35L45_DSP1_YMEM_UNPACK24_2043:
+ case CS35L45_DSP1_PMEM_0 ... CS35L45_DSP1_PMEM_3834:
return true;
default:
return false;
diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c
index 855d9f13e6ff..c31597f6bfae 100644
--- a/sound/soc/codecs/cs35l45.c
+++ b/sound/soc/codecs/cs35l45.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
+#include <linux/firmware.h>
#include <linux/regulator/consumer.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -19,6 +20,71 @@
#include "cs35l45.h"
+static bool cs35l45_check_cspl_mbox_sts(const enum cs35l45_cspl_mboxcmd cmd,
+ enum cs35l45_cspl_mboxstate sts)
+{
+ switch (cmd) {
+ case CSPL_MBOX_CMD_NONE:
+ case CSPL_MBOX_CMD_UNKNOWN_CMD:
+ return true;
+ case CSPL_MBOX_CMD_PAUSE:
+ case CSPL_MBOX_CMD_OUT_OF_HIBERNATE:
+ return (sts == CSPL_MBOX_STS_PAUSED);
+ case CSPL_MBOX_CMD_RESUME:
+ return (sts == CSPL_MBOX_STS_RUNNING);
+ case CSPL_MBOX_CMD_REINIT:
+ return (sts == CSPL_MBOX_STS_RUNNING);
+ case CSPL_MBOX_CMD_STOP_PRE_REINIT:
+ return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT);
+ case CSPL_MBOX_CMD_HIBERNATE:
+ return (sts == CSPL_MBOX_STS_HIBERNATE);
+ default:
+ return false;
+ }
+}
+
+static int cs35l45_set_cspl_mbox_cmd(struct cs35l45_private *cs35l45,
+ struct regmap *regmap,
+ const enum cs35l45_cspl_mboxcmd cmd)
+{
+ unsigned int sts = 0, i;
+ int ret;
+
+ if (!cs35l45->dsp.cs_dsp.running) {
+ dev_err(cs35l45->dev, "DSP not running\n");
+ return -EPERM;
+ }
+
+ // Set mailbox cmd
+ ret = regmap_write(regmap, CS35L45_DSP_VIRT1_MBOX_1, cmd);
+ if (ret < 0) {
+ if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE)
+ dev_err(cs35l45->dev, "Failed to write MBOX: %d\n", ret);
+ return ret;
+ }
+
+ // Read mailbox status and verify it is appropriate for the given cmd
+ for (i = 0; i < 5; i++) {
+ usleep_range(1000, 1100);
+
+ ret = regmap_read(regmap, CS35L45_DSP_MBOX_2, &sts);
+ if (ret < 0) {
+ dev_err(cs35l45->dev, "Failed to read MBOX STS: %d\n", ret);
+ continue;
+ }
+
+ if (!cs35l45_check_cspl_mbox_sts(cmd, sts))
+ dev_dbg(cs35l45->dev, "[%u] cmd %u returned invalid sts %u", i, cmd, sts);
+ else
+ return 0;
+ }
+
+ if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE)
+ dev_err(cs35l45->dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts);
+
+ return -ENOMSG;
+}
+
static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -46,10 +112,68 @@ static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w,
return 0;
}
+static int cs35l45_dsp_preload_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 cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
+ int ret;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (cs35l45->dsp.cs_dsp.booted)
+ return 0;
+
+ return wm_adsp_early_event(w, kcontrol, event);
+ case SND_SOC_DAPM_POST_PMU:
+ if (cs35l45->dsp.cs_dsp.running)
+ return 0;
+
+ regmap_set_bits(cs35l45->regmap, CS35L45_PWRMGT_CTL,
+ CS35L45_MEM_RDY_MASK);
+
+ return wm_adsp_event(w, kcontrol, event);
+ case SND_SOC_DAPM_PRE_PMD:
+ if (cs35l45->dsp.preloaded)
+ return 0;
+
+ if (cs35l45->dsp.cs_dsp.running) {
+ ret = wm_adsp_event(w, kcontrol, event);
+ if (ret)
+ return ret;
+ }
+
+ return wm_adsp_early_event(w, kcontrol, event);
+ default:
+ return 0;
+ }
+}
+
+static int cs35l45_dsp_audio_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 cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ return cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
+ CSPL_MBOX_CMD_RESUME);
+ case SND_SOC_DAPM_PRE_PMD:
+ return cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
+ CSPL_MBOX_CMD_PAUSE);
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
static const char * const cs35l45_asp_tx_txt[] = {
"Zero", "ASP_RX1", "ASP_RX2",
"VMON", "IMON", "ERR_VOL",
"VDD_BATTMON", "VDD_BSTMON",
+ "DSP_TX1", "DSP_TX2",
"Interpolator", "IL_TARGET",
};
@@ -57,6 +181,7 @@ static const unsigned int cs35l45_asp_tx_val[] = {
CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,
CS35L45_PCM_SRC_VDD_BATTMON, CS35L45_PCM_SRC_VDD_BSTMON,
+ CS35L45_PCM_SRC_DSP_TX1, CS35L45_PCM_SRC_DSP_TX2,
CS35L45_PCM_SRC_INTERPOLATOR, CS35L45_PCM_SRC_IL_TARGET,
};
@@ -78,12 +203,54 @@ static const struct soc_enum cs35l45_asp_tx_enums[] = {
cs35l45_asp_tx_val),
};
+static const char * const cs35l45_dsp_rx_txt[] = {
+ "Zero", "ASP_RX1", "ASP_RX2",
+ "VMON", "IMON", "ERR_VOL",
+ "CLASSH_TGT", "VDD_BATTMON",
+ "VDD_BSTMON", "TEMPMON",
+};
+
+static const unsigned int cs35l45_dsp_rx_val[] = {
+ CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
+ CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,
+ CS35L45_PCM_SRC_CLASSH_TGT, CS35L45_PCM_SRC_VDD_BATTMON,
+ CS35L45_PCM_SRC_VDD_BSTMON, CS35L45_PCM_SRC_TEMPMON,
+};
+
+static const struct soc_enum cs35l45_dsp_rx_enums[] = {
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX1_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX2_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX3_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX4_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX5_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX6_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX7_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX8_INPUT, 0, CS35L45_PCM_SRC_MASK,
+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
+ cs35l45_dsp_rx_val),
+};
+
static const char * const cs35l45_dac_txt[] = {
- "Zero", "ASP_RX1", "ASP_RX2"
+ "Zero", "ASP_RX1", "ASP_RX2", "DSP_TX1", "DSP_TX2"
};
static const unsigned int cs35l45_dac_val[] = {
- CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2
+ CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
+ CS35L45_PCM_SRC_DSP_TX1, CS35L45_PCM_SRC_DSP_TX2
};
static const struct soc_enum cs35l45_dacpcm_enums[] = {
@@ -100,11 +267,29 @@ static const struct snd_kcontrol_new cs35l45_asp_muxes[] = {
SOC_DAPM_ENUM("ASP_TX5 Source", cs35l45_asp_tx_enums[4]),
};
+static const struct snd_kcontrol_new cs35l45_dsp_muxes[] = {
+ SOC_DAPM_ENUM("DSP_RX1 Source", cs35l45_dsp_rx_enums[0]),
+ SOC_DAPM_ENUM("DSP_RX2 Source", cs35l45_dsp_rx_enums[1]),
+ SOC_DAPM_ENUM("DSP_RX3 Source", cs35l45_dsp_rx_enums[2]),
+ SOC_DAPM_ENUM("DSP_RX4 Source", cs35l45_dsp_rx_enums[3]),
+ SOC_DAPM_ENUM("DSP_RX5 Source", cs35l45_dsp_rx_enums[4]),
+ SOC_DAPM_ENUM("DSP_RX6 Source", cs35l45_dsp_rx_enums[5]),
+ SOC_DAPM_ENUM("DSP_RX7 Source", cs35l45_dsp_rx_enums[6]),
+ SOC_DAPM_ENUM("DSP_RX8 Source", cs35l45_dsp_rx_enums[7]),
+};
+
static const struct snd_kcontrol_new cs35l45_dac_muxes[] = {
SOC_DAPM_ENUM("DACPCM1 Source", cs35l45_dacpcm_enums[0]),
};
static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = {
+ SND_SOC_DAPM_SPK("DSP1 Preload", NULL),
+ SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0,
+ cs35l45_dsp_preload_ev,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0,
+ cs35l45_dsp_audio_ev,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("GLOBAL_EN", SND_SOC_NOPM, 0, 0,
cs35l45_global_en_ev,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -139,6 +324,15 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = {
SND_SOC_DAPM_MUX("ASP_TX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[3]),
SND_SOC_DAPM_MUX("ASP_TX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[4]),
+ SND_SOC_DAPM_MUX("DSP_RX1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[0]),
+ SND_SOC_DAPM_MUX("DSP_RX2 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[1]),
+ SND_SOC_DAPM_MUX("DSP_RX3 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[2]),
+ SND_SOC_DAPM_MUX("DSP_RX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[3]),
+ SND_SOC_DAPM_MUX("DSP_RX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[4]),
+ SND_SOC_DAPM_MUX("DSP_RX6 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[5]),
+ SND_SOC_DAPM_MUX("DSP_RX7 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[6]),
+ SND_SOC_DAPM_MUX("DSP_RX8 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[7]),
+
SND_SOC_DAPM_MUX("DACPCM1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dac_muxes[0]),
SND_SOC_DAPM_OUT_DRV("AMP", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -149,6 +343,8 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = {
#define CS35L45_ASP_MUX_ROUTE(name) \
{ name" Source", "ASP_RX1", "ASP_RX1" }, \
{ name" Source", "ASP_RX2", "ASP_RX2" }, \
+ { name" Source", "DSP_TX1", "DSP1" }, \
+ { name" Source", "DSP_TX2", "DSP1" }, \
{ name" Source", "VMON", "VMON" }, \
{ name" Source", "IMON", "IMON" }, \
{ name" Source", "ERR_VOL", "ERR_VOL" }, \
@@ -157,10 +353,16 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = {
{ name" Source", "Interpolator", "AMP_INTP" }, \
{ name" Source", "IL_TARGET", "IL_TARGET" }
-#define CS35L45_DAC_MUX_ROUTE(name) \
+#define CS35L45_DSP_MUX_ROUTE(name) \
{ name" Source", "ASP_RX1", "ASP_RX1" }, \
{ name" Source", "ASP_RX2", "ASP_RX2" }
+#define CS35L45_DAC_MUX_ROUTE(name) \
+ { name" Source", "ASP_RX1", "ASP_RX1" }, \
+ { name" Source", "ASP_RX2", "ASP_RX2" }, \
+ { name" Source", "DSP_TX1", "DSP1" }, \
+ { name" Source", "DSP_TX2", "DSP1" }
+
static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = {
/* Feedback */
{ "VMON", NULL, "VMON_SRC" },
@@ -204,6 +406,27 @@ static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = {
{ "AMP", NULL, "DACPCM1 Source"},
{ "AMP", NULL, "GLOBAL_EN"},
+ CS35L45_DSP_MUX_ROUTE("DSP_RX1"),
+ CS35L45_DSP_MUX_ROUTE("DSP_RX2"),
+ CS35L45_DSP_MUX_ROUTE("DSP_RX3"),
+ CS35L45_DSP_MUX_ROUTE("DSP_RX4"),
+ CS35L45_DSP_MUX_ROUTE("DSP_RX5"),
+ CS35L45_DSP_MUX_ROUTE("DSP_RX6"),
+ CS35L45_DSP_MUX_ROUTE("DSP_RX7"),
+ CS35L45_DSP_MUX_ROUTE("DSP_RX8"),
+
+ {"DSP1", NULL, "DSP_RX1 Source"},
+ {"DSP1", NULL, "DSP_RX2 Source"},
+ {"DSP1", NULL, "DSP_RX3 Source"},
+ {"DSP1", NULL, "DSP_RX4 Source"},
+ {"DSP1", NULL, "DSP_RX5 Source"},
+ {"DSP1", NULL, "DSP_RX6 Source"},
+ {"DSP1", NULL, "DSP_RX7 Source"},
+ {"DSP1", NULL, "DSP_RX8 Source"},
+
+ {"DSP1 Preload", NULL, "DSP1 Preloader"},
+ {"DSP1", NULL, "DSP1 Preloader"},
+
CS35L45_DAC_MUX_ROUTE("DACPCM1"),
{ "SPK", NULL, "AMP"},
@@ -219,6 +442,8 @@ static const struct snd_kcontrol_new cs35l45_controls[] = {
-409, 48,
(CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1,
0, cs35l45_dig_pcm_vol_tlv),
+ WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
+ WM_ADSP_FW_CONTROL("DSP1", 0),
};
static int cs35l45_set_pll(struct cs35l45_private *cs35l45, unsigned int freq)
@@ -489,7 +714,24 @@ static struct snd_soc_dai_driver cs35l45_dai[] = {
},
};
+static int cs35l45_component_probe(struct snd_soc_component *component)
+{
+ struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
+
+ return wm_adsp2_component_probe(&cs35l45->dsp, component);
+}
+
+static void cs35l45_component_remove(struct snd_soc_component *component)
+{
+ struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
+
+ wm_adsp2_component_remove(&cs35l45->dsp, component);
+}
+
static const struct snd_soc_component_driver cs35l45_component = {
+ .probe = cs35l45_component_probe,
+ .remove = cs35l45_component_remove,
+
.dapm_widgets = cs35l45_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(cs35l45_dapm_widgets),
@@ -504,11 +746,81 @@ static const struct snd_soc_component_driver cs35l45_component = {
.endianness = 1,
};
+static void cs35l45_setup_hibernate(struct cs35l45_private *cs35l45)
+{
+ unsigned int wksrc;
+
+ if (cs35l45->bus_type == CONTROL_BUS_I2C)
+ wksrc = CS35L45_WKSRC_I2C;
+ else
+ wksrc = CS35L45_WKSRC_SPI;
+
+ regmap_update_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL,
+ CS35L45_WKSRC_EN_MASK,
+ wksrc << CS35L45_WKSRC_EN_SHIFT);
+
+ regmap_set_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL,
+ CS35L45_UPDT_WKCTL_MASK);
+
+ regmap_update_bits(cs35l45->regmap, CS35L45_WKI2C_CTL,
+ CS35L45_WKI2C_ADDR_MASK, cs35l45->i2c_addr);
+
+ regmap_set_bits(cs35l45->regmap, CS35L45_WKI2C_CTL,
+ CS35L45_UPDT_WKI2C_MASK);
+}
+
+static int cs35l45_enter_hibernate(struct cs35l45_private *cs35l45)
+{
+ dev_dbg(cs35l45->dev, "Enter hibernate\n");
+
+ cs35l45_setup_hibernate(cs35l45);
+
+ // Don't wait for ACK since bus activity would wake the device
+ regmap_write(cs35l45->regmap, CS35L45_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE);
+
+ return 0;
+}
+
+static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45)
+{
+ const int wake_retries = 20;
+ const int sleep_retries = 5;
+ int ret, i, j;
+
+ for (i = 0; i < sleep_retries; i++) {
+ dev_dbg(cs35l45->dev, "Exit hibernate\n");
+
+ for (j = 0; j < wake_retries; j++) {
+ ret = cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
+ CSPL_MBOX_CMD_OUT_OF_HIBERNATE);
+ if (!ret) {
+ dev_dbg(cs35l45->dev, "Wake success at cycle: %d\n", j);
+ return 0;
+ }
+ usleep_range(100, 200);
+ }
+
+ dev_err(cs35l45->dev, "Wake failed, re-enter hibernate: %d\n", ret);
+
+ cs35l45_setup_hibernate(cs35l45);
+ }
+
+ dev_err(cs35l45->dev, "Timed out waking device\n");
+
+ return -ETIMEDOUT;
+}
+
static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)
{
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
+ if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
+ return 0;
+
+ cs35l45_enter_hibernate(cs35l45);
+
regcache_cache_only(cs35l45->regmap, true);
+ regcache_mark_dirty(cs35l45->regmap);
dev_dbg(cs35l45->dev, "Runtime suspended\n");
@@ -520,9 +832,17 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev)
struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
int ret;
+ if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
+ return 0;
+
dev_dbg(cs35l45->dev, "Runtime resume\n");
regcache_cache_only(cs35l45->regmap, false);
+
+ ret = cs35l45_exit_hibernate(cs35l45);
+ if (ret)
+ return ret;
+
ret = regcache_sync(cs35l45->regmap);
if (ret != 0)
dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret);
@@ -536,7 +856,66 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev)
static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
{
+ struct device_node *node = cs35l45->dev->of_node;
+ unsigned int gpio_regs[] = {CS35L45_GPIO1_CTRL1, CS35L45_GPIO2_CTRL1,
+ CS35L45_GPIO3_CTRL1};
+ unsigned int pad_regs[] = {CS35L45_SYNC_GPIO1,
+ CS35L45_INTB_GPIO2_MCLK_REF, CS35L45_GPIO3};
+ struct device_node *child;
unsigned int val;
+ char of_name[32];
+ int ret, i;
+
+ if (!node)
+ return 0;
+
+ for (i = 0; i < CS35L45_NUM_GPIOS; i++) {
+ sprintf(of_name, "cirrus,gpio-ctrl%d", i + 1);
+ child = of_get_child_by_name(node, of_name);
+ if (!child)
+ continue;
+
+ ret = of_property_read_u32(child, "gpio-dir", &val);
+ if (!ret)
+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+ CS35L45_GPIO_DIR_MASK,
+ val << CS35L45_GPIO_DIR_SHIFT);
+
+ ret = of_property_read_u32(child, "gpio-lvl", &val);
+ if (!ret)
+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+ CS35L45_GPIO_LVL_MASK,
+ val << CS35L45_GPIO_LVL_SHIFT);
+
+ ret = of_property_read_u32(child, "gpio-op-cfg", &val);
+ if (!ret)
+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+ CS35L45_GPIO_OP_CFG_MASK,
+ val << CS35L45_GPIO_OP_CFG_SHIFT);
+
+ ret = of_property_read_u32(child, "gpio-pol", &val);
+ if (!ret)
+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+ CS35L45_GPIO_POL_MASK,
+ val << CS35L45_GPIO_POL_SHIFT);
+
+ ret = of_property_read_u32(child, "gpio-ctrl", &val);
+ if (!ret)
+ regmap_update_bits(cs35l45->regmap, pad_regs[i],
+ CS35L45_GPIO_CTRL_MASK,
+ val << CS35L45_GPIO_CTRL_SHIFT);
+
+ ret = of_property_read_u32(child, "gpio-invert", &val);
+ if (!ret) {
+ regmap_update_bits(cs35l45->regmap, pad_regs[i],
+ CS35L45_GPIO_INVERT_MASK,
+ val << CS35L45_GPIO_INVERT_SHIFT);
+ if (i == 1)
+ cs35l45->irq_invert = val;
+ }
+
+ of_node_put(child);
+ }
if (device_property_read_u32(cs35l45->dev,
"cirrus,asp-sdout-hiz-ctrl", &val) == 0) {
@@ -548,6 +927,134 @@ static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
return 0;
}
+static int cs35l45_dsp_virt2_mbox3_irq_handle(struct cs35l45_private *cs35l45,
+ const unsigned int cmd,
+ unsigned int data)
+{
+ static char *speak_status = "Unknown";
+
+ switch (cmd) {
+ case EVENT_SPEAKER_STATUS:
+ switch (data) {
+ case 1:
+ speak_status = "All Clear";
+ break;
+ case 2:
+ speak_status = "Open Circuit";
+ break;
+ case 4:
+ speak_status = "Short Circuit";
+ break;
+ }
+
+ dev_info(cs35l45->dev, "MBOX event (SPEAKER_STATUS): %s\n",
+ speak_status);
+ break;
+ case EVENT_BOOT_DONE:
+ dev_dbg(cs35l45->dev, "MBOX event (BOOT_DONE)\n");
+ break;
+ default:
+ dev_err(cs35l45->dev, "MBOX event not supported %u\n", cmd);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static irqreturn_t cs35l45_dsp_virt2_mbox_cb(int irq, void *data)
+{
+ struct cs35l45_private *cs35l45 = data;
+ unsigned int mbox_val;
+ int ret = 0;
+
+ ret = regmap_read(cs35l45->regmap, CS35L45_DSP_VIRT2_MBOX_3, &mbox_val);
+ if (!ret && mbox_val)
+ ret = cs35l45_dsp_virt2_mbox3_irq_handle(cs35l45, mbox_val & CS35L45_MBOX3_CMD_MASK,
+ (mbox_val & CS35L45_MBOX3_DATA_MASK) >> CS35L45_MBOX3_DATA_SHIFT);
+
+ /* Handle DSP trace log IRQ */
+ ret = regmap_read(cs35l45->regmap, CS35L45_DSP_VIRT2_MBOX_4, &mbox_val);
+ if (!ret && mbox_val != 0) {
+ dev_err(cs35l45->dev, "Spurious DSP MBOX4 IRQ\n");
+ }
+
+ return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t cs35l45_pll_unlock(int irq, void *data)
+{
+ struct cs35l45_private *cs35l45 = data;
+
+ dev_dbg(cs35l45->dev, "PLL unlock detected!");
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t cs35l45_pll_lock(int irq, void *data)
+{
+ struct cs35l45_private *cs35l45 = data;
+
+ dev_dbg(cs35l45->dev, "PLL lock detected!");
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t cs35l45_spk_safe_err(int irq, void *data);
+
+static const struct cs35l45_irq cs35l45_irqs[] = {
+ CS35L45_IRQ(AMP_SHORT_ERR, "Amplifier short error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(UVLO_VDDBATT_ERR, "VDDBATT undervoltage error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(BST_SHORT_ERR, "Boost inductor error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(BST_UVP_ERR, "Boost undervoltage error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(TEMP_ERR, "Overtemperature error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(AMP_CAL_ERR, "Amplifier calibration error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(UVLO_VDDLV_ERR, "LV threshold detector error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(GLOBAL_ERROR, "Global error", cs35l45_spk_safe_err),
+ CS35L45_IRQ(DSP_WDT_EXPIRE, "DSP Watchdog Timer", cs35l45_spk_safe_err),
+ CS35L45_IRQ(PLL_UNLOCK_FLAG_RISE, "PLL unlock", cs35l45_pll_unlock),
+ CS35L45_IRQ(PLL_LOCK_FLAG, "PLL lock", cs35l45_pll_lock),
+ CS35L45_IRQ(DSP_VIRT2_MBOX, "DSP virtual MBOX 2 write flag", cs35l45_dsp_virt2_mbox_cb),
+};
+
+static irqreturn_t cs35l45_spk_safe_err(int irq, void *data)
+{
+ struct cs35l45_private *cs35l45 = data;
+ int i;
+
+ i = irq - regmap_irq_get_virq(cs35l45->irq_data, 0);
+
+ dev_err(cs35l45->dev, "%s condition detected!\n", cs35l45_irqs[i].name);
+
+ return IRQ_HANDLED;
+}
+
+static const struct regmap_irq cs35l45_reg_irqs[] = {
+ CS35L45_REG_IRQ(IRQ1_EINT_1, AMP_SHORT_ERR),
+ CS35L45_REG_IRQ(IRQ1_EINT_1, UVLO_VDDBATT_ERR),
+ CS35L45_REG_IRQ(IRQ1_EINT_1, BST_SHORT_ERR),
+ CS35L45_REG_IRQ(IRQ1_EINT_1, BST_UVP_ERR),
+ CS35L45_REG_IRQ(IRQ1_EINT_1, TEMP_ERR),
+ CS35L45_REG_IRQ(IRQ1_EINT_3, AMP_CAL_ERR),
+ CS35L45_REG_IRQ(IRQ1_EINT_18, UVLO_VDDLV_ERR),
+ CS35L45_REG_IRQ(IRQ1_EINT_18, GLOBAL_ERROR),
+ CS35L45_REG_IRQ(IRQ1_EINT_2, DSP_WDT_EXPIRE),
+ CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_UNLOCK_FLAG_RISE),
+ CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_LOCK_FLAG),
+ CS35L45_REG_IRQ(IRQ1_EINT_2, DSP_VIRT2_MBOX),
+};
+
+static const struct regmap_irq_chip cs35l45_regmap_irq_chip = {
+ .name = "cs35l45 IRQ1 Controller",
+ .main_status = CS35L45_IRQ1_STATUS,
+ .status_base = CS35L45_IRQ1_EINT_1,
+ .mask_base = CS35L45_IRQ1_MASK_1,
+ .ack_base = CS35L45_IRQ1_EINT_1,
+ .num_regs = 18,
+ .irqs = cs35l45_reg_irqs,
+ .num_irqs = ARRAY_SIZE(cs35l45_reg_irqs),
+ .runtime_pm = true,
+};
+
static int cs35l45_initialize(struct cs35l45_private *cs35l45)
{
struct device *dev = cs35l45->dev;
@@ -593,18 +1100,68 @@ static int cs35l45_initialize(struct cs35l45_private *cs35l45)
if (ret < 0)
return ret;
- pm_runtime_set_autosuspend_delay(cs35l45->dev, 3000);
- pm_runtime_use_autosuspend(cs35l45->dev);
- pm_runtime_set_active(cs35l45->dev);
- pm_runtime_enable(cs35l45->dev);
-
return 0;
}
+static const struct reg_sequence cs35l45_fs_errata_patch[] = {
+ {0x02B80080, 0x00000001},
+ {0x02B80088, 0x00000001},
+ {0x02B80090, 0x00000001},
+ {0x02B80098, 0x00000001},
+ {0x02B800A0, 0x00000001},
+ {0x02B800A8, 0x00000001},
+ {0x02B800B0, 0x00000001},
+ {0x02B800B8, 0x00000001},
+ {0x02B80280, 0x00000001},
+ {0x02B80288, 0x00000001},
+ {0x02B80290, 0x00000001},
+ {0x02B80298, 0x00000001},
+ {0x02B802A0, 0x00000001},
+ {0x02B802A8, 0x00000001},
+ {0x02B802B0, 0x00000001},
+ {0x02B802B8, 0x00000001},
+};
+
+static const struct cs_dsp_region cs35l45_dsp1_regions[] = {
+ { .type = WMFW_HALO_PM_PACKED, .base = CS35L45_DSP1_PMEM_0 },
+ { .type = WMFW_HALO_XM_PACKED, .base = CS35L45_DSP1_XMEM_PACK_0 },
+ { .type = WMFW_HALO_YM_PACKED, .base = CS35L45_DSP1_YMEM_PACK_0 },
+ {. type = WMFW_ADSP2_XM, .base = CS35L45_DSP1_XMEM_UNPACK24_0},
+ {. type = WMFW_ADSP2_YM, .base = CS35L45_DSP1_YMEM_UNPACK24_0},
+};
+
+static int cs35l45_dsp_init(struct cs35l45_private *cs35l45)
+{
+ struct wm_adsp *dsp = &cs35l45->dsp;
+ int ret;
+
+ dsp->part = "cs35l45";
+ dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */
+ dsp->toggle_preload = true;
+ dsp->cs_dsp.num = 1;
+ dsp->cs_dsp.type = WMFW_HALO;
+ dsp->cs_dsp.rev = 0;
+ dsp->cs_dsp.dev = cs35l45->dev;
+ dsp->cs_dsp.regmap = cs35l45->regmap;
+ dsp->cs_dsp.base = CS35L45_DSP1_CLOCK_FREQ;
+ dsp->cs_dsp.base_sysinfo = CS35L45_DSP1_SYS_ID;
+ dsp->cs_dsp.mem = cs35l45_dsp1_regions;
+ dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l45_dsp1_regions);
+ dsp->cs_dsp.lock_regions = 0xFFFFFFFF;
+
+ ret = wm_halo_init(dsp);
+
+ regmap_multi_reg_write(cs35l45->regmap, cs35l45_fs_errata_patch,
+ ARRAY_SIZE(cs35l45_fs_errata_patch));
+
+ return ret;
+}
+
int cs35l45_probe(struct cs35l45_private *cs35l45)
{
struct device *dev = cs35l45->dev;
- int ret;
+ unsigned long irq_pol = IRQF_ONESHOT | IRQF_SHARED;
+ int ret, i, irq;
cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt");
if (IS_ERR(cs35l45->vdd_batt))
@@ -649,14 +1206,63 @@ int cs35l45_probe(struct cs35l45_private *cs35l45)
if (ret < 0)
goto err_reset;
+ ret = cs35l45_dsp_init(cs35l45);
+ if (ret < 0)
+ goto err_reset;
+
+ pm_runtime_set_autosuspend_delay(cs35l45->dev, 3000);
+ pm_runtime_use_autosuspend(cs35l45->dev);
+ pm_runtime_mark_last_busy(cs35l45->dev);
+ pm_runtime_set_active(cs35l45->dev);
+ pm_runtime_get_noresume(cs35l45->dev);
+ pm_runtime_enable(cs35l45->dev);
+
+ if (cs35l45->irq) {
+ if (cs35l45->irq_invert)
+ irq_pol |= IRQF_TRIGGER_HIGH;
+ else
+ irq_pol |= IRQF_TRIGGER_LOW;
+
+ ret = devm_regmap_add_irq_chip(dev, cs35l45->regmap, cs35l45->irq, irq_pol, 0,
+ &cs35l45_regmap_irq_chip, &cs35l45->irq_data);
+ if (ret) {
+ dev_err(dev, "Failed to register IRQ chip: %d\n", ret);
+ goto err_dsp;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cs35l45_irqs); i++) {
+ irq = regmap_irq_get_virq(cs35l45->irq_data, cs35l45_irqs[i].irq);
+ if (irq < 0) {
+ dev_err(dev, "Failed to get %s\n", cs35l45_irqs[i].name);
+ ret = irq;
+ goto err_dsp;
+ }
+
+ ret = devm_request_threaded_irq(dev, irq, NULL, cs35l45_irqs[i].handler,
+ irq_pol, cs35l45_irqs[i].name, cs35l45);
+ if (ret) {
+ dev_err(dev, "Failed to request IRQ %s: %d\n",
+ cs35l45_irqs[i].name, ret);
+ goto err_dsp;
+ }
+ }
+ }
+
ret = devm_snd_soc_register_component(dev, &cs35l45_component,
cs35l45_dai,
ARRAY_SIZE(cs35l45_dai));
if (ret < 0)
- goto err_reset;
+ goto err_dsp;
+
+ pm_runtime_put_autosuspend(cs35l45->dev);
return 0;
+err_dsp:
+ pm_runtime_disable(cs35l45->dev);
+ pm_runtime_put_noidle(cs35l45->dev);
+ wm_adsp2_remove(&cs35l45->dsp);
+
err_reset:
gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
err:
@@ -669,9 +1275,13 @@ EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45);
void cs35l45_remove(struct cs35l45_private *cs35l45)
{
+ pm_runtime_get_sync(cs35l45->dev);
pm_runtime_disable(cs35l45->dev);
+ wm_adsp2_remove(&cs35l45->dsp);
gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
+
+ pm_runtime_put_noidle(cs35l45->dev);
regulator_disable(cs35l45->vdd_a);
/* VDD_BATT must be the last to power-off */
regulator_disable(cs35l45->vdd_batt);
diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h
index 53fe9d2b7b15..0da28439f628 100644
--- a/sound/soc/codecs/cs35l45.h
+++ b/sound/soc/codecs/cs35l45.h
@@ -14,6 +14,8 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <dt-bindings/sound/cs35l45.h>
+#include "wm_adsp.h"
#define CS35L45_DEVID 0x00000000
#define CS35L45_REVID 0x00000004
@@ -24,6 +26,13 @@
#define CS35L45_BLOCK_ENABLES 0x00002018
#define CS35L45_BLOCK_ENABLES2 0x0000201C
#define CS35L45_ERROR_RELEASE 0x00002034
+#define CS35L45_SYNC_GPIO1 0x00002430
+#define CS35L45_INTB_GPIO2_MCLK_REF 0x00002434
+#define CS35L45_GPIO3 0x00002438
+#define CS35L45_PWRMGT_CTL 0x00002900
+#define CS35L45_WAKESRC_CTL 0x00002904
+#define CS35L45_WKI2C_CTL 0x00002908
+#define CS35L45_PWRMGT_STS 0x0000290C
#define CS35L45_REFCLK_INPUT 0x00002C04
#define CS35L45_GLOBAL_SAMPLE_RATE 0x00002C0C
#define CS35L45_BOOST_CCM_CFG 0x00003808
@@ -44,11 +53,105 @@
#define CS35L45_ASPTX3_INPUT 0x00004C28
#define CS35L45_ASPTX4_INPUT 0x00004C2C
#define CS35L45_ASPTX5_INPUT 0x00004C30
+#define CS35L45_DSP1RX1_INPUT 0x00004C40
+#define CS35L45_DSP1RX2_INPUT 0x00004C44
+#define CS35L45_DSP1RX3_INPUT 0x00004C48
+#define CS35L45_DSP1RX4_INPUT 0x00004C4C
+#define CS35L45_DSP1RX5_INPUT 0x00004C50
+#define CS35L45_DSP1RX6_INPUT 0x00004C54
+#define CS35L45_DSP1RX7_INPUT 0x00004C58
+#define CS35L45_DSP1RX8_INPUT 0x00004C5C
#define CS35L45_LDPM_CONFIG 0x00006404
#define CS35L45_AMP_PCM_CONTROL 0x00007000
#define CS35L45_AMP_PCM_HPF_TST 0x00007004
+#define CS35L45_IRQ1_CFG 0x0000E000
+#define CS35L45_IRQ1_STATUS 0x0000E004
+#define CS35L45_IRQ1_EINT_1 0x0000E010
+#define CS35L45_IRQ1_EINT_2 0x0000E014
+#define CS35L45_IRQ1_EINT_3 0x0000E018
#define CS35L45_IRQ1_EINT_4 0x0000E01C
-#define CS35L45_LASTREG 0x0000E01C
+#define CS35L45_IRQ1_EINT_5 0x0000E020
+#define CS35L45_IRQ1_EINT_7 0x0000E028
+#define CS35L45_IRQ1_EINT_8 0x0000E02C
+#define CS35L45_IRQ1_EINT_18 0x0000E054
+#define CS35L45_IRQ1_STS_1 0x0000E090
+#define CS35L45_IRQ1_STS_2 0x0000E094
+#define CS35L45_IRQ1_STS_3 0x0000E098
+#define CS35L45_IRQ1_STS_4 0x0000E09C
+#define CS35L45_IRQ1_STS_5 0x0000E0A0
+#define CS35L45_IRQ1_STS_7 0x0000E0A8
+#define CS35L45_IRQ1_STS_8 0x0000E0AC
+#define CS35L45_IRQ1_STS_18 0x0000E0D4
+#define CS35L45_IRQ1_MASK_1 0x0000E110
+#define CS35L45_IRQ1_MASK_2 0x0000E114
+#define CS35L45_IRQ1_MASK_3 0x0000E118
+#define CS35L45_IRQ1_MASK_4 0x0000E11C
+#define CS35L45_IRQ1_MASK_5 0x0000E120
+#define CS35L45_IRQ1_MASK_6 0x0000E124
+#define CS35L45_IRQ1_MASK_7 0x0000E128
+#define CS35L45_IRQ1_MASK_8 0x0000E12C
+#define CS35L45_IRQ1_MASK_9 0x0000E130
+#define CS35L45_IRQ1_MASK_10 0x0000E134
+#define CS35L45_IRQ1_MASK_11 0x0000E138
+#define CS35L45_IRQ1_MASK_12 0x0000E13C
+#define CS35L45_IRQ1_MASK_13 0x0000E140
+#define CS35L45_IRQ1_MASK_14 0x0000E144
+#define CS35L45_IRQ1_MASK_15 0x0000E148
+#define CS35L45_IRQ1_MASK_16 0x0000E14C
+#define CS35L45_IRQ1_MASK_17 0x0000E150
+#define CS35L45_IRQ1_MASK_18 0x0000E154
+#define CS35L45_GPIO_STATUS1 0x0000F000
+#define CS35L45_GPIO1_CTRL1 0x0000F008
+#define CS35L45_GPIO2_CTRL1 0x0000F00C
+#define CS35L45_GPIO3_CTRL1 0x0000F010
+#define CS35L45_DSP_MBOX_1 0x00011000
+#define CS35L45_DSP_MBOX_2 0x00011004
+#define CS35L45_DSP_VIRT1_MBOX_1 0x00011020
+#define CS35L45_DSP_VIRT1_MBOX_2 0x00011024
+#define CS35L45_DSP_VIRT1_MBOX_3 0x00011028
+#define CS35L45_DSP_VIRT1_MBOX_4 0x0001102C
+#define CS35L45_DSP_VIRT2_MBOX_1 0x00011040
+#define CS35L45_DSP_VIRT2_MBOX_2 0x00011044
+#define CS35L45_DSP_VIRT2_MBOX_3 0x00011048
+#define CS35L45_DSP_VIRT2_MBOX_4 0x0001104C
+#define CS35L45_DSP1_XMEM_PACK_0 0x02000000
+#define CS35L45_DSP1_XMEM_PACK_4607 0x020047FC
+#define CS35L45_DSP1_XMEM_UNPACK32_0 0x02400000
+#define CS35L45_DSP1_XMEM_UNPACK32_3071 0x02402FFC
+#define CS35L45_DSP1_SYS_ID 0x025E0000
+#define CS35L45_DSP1_XMEM_UNPACK24_0 0x02800000
+#define CS35L45_DSP1_XMEM_UNPACK24_6143 0x02805FFC
+#define CS35L45_DSP1_CLOCK_FREQ 0x02B80000
+#define CS35L45_DSP1_RX1_RATE 0x02B80080
+#define CS35L45_DSP1_RX2_RATE 0x02B80088
+#define CS35L45_DSP1_RX3_RATE 0x02B80090
+#define CS35L45_DSP1_RX4_RATE 0x02B80098
+#define CS35L45_DSP1_RX5_RATE 0x02B800A0
+#define CS35L45_DSP1_RX6_RATE 0x02B800A8
+#define CS35L45_DSP1_RX7_RATE 0x02B800B0
+#define CS35L45_DSP1_RX8_RATE 0x02B800B8
+#define CS35L45_DSP1_TX1_RATE 0x02B80280
+#define CS35L45_DSP1_TX2_RATE 0x02B80288
+#define CS35L45_DSP1_TX3_RATE 0x02B80290
+#define CS35L45_DSP1_TX4_RATE 0x02B80298
+#define CS35L45_DSP1_TX5_RATE 0x02B802A0
+#define CS35L45_DSP1_TX6_RATE 0x02B802A8
+#define CS35L45_DSP1_TX7_RATE 0x02B802B0
+#define CS35L45_DSP1_TX8_RATE 0x02B802B8
+#define CS35L45_DSP1_SCRATCH1 0x02B805C0
+#define CS35L45_DSP1_SCRATCH2 0x02B805C8
+#define CS35L45_DSP1_SCRATCH3 0x02B805D0
+#define CS35L45_DSP1_SCRATCH4 0x02B805D8
+#define CS35L45_DSP1_CCM_CORE_CONTROL 0x02BC1000
+#define CS35L45_DSP1_YMEM_PACK_0 0x02C00000
+#define CS35L45_DSP1_YMEM_PACK_1532 0x02C017F0
+#define CS35L45_DSP1_YMEM_UNPACK32_0 0x03000000
+#define CS35L45_DSP1_YMEM_UNPACK32_1022 0x03000FF8
+#define CS35L45_DSP1_YMEM_UNPACK24_0 0x03400000
+#define CS35L45_DSP1_YMEM_UNPACK24_2043 0x03401FEC
+#define CS35L45_DSP1_PMEM_0 0x03800000
+#define CS35L45_DSP1_PMEM_3834 0x03803BE8
+#define CS35L45_LASTREG 0x03C6EFE8
/* SFT_RESET */
#define CS35L45_SOFT_RESET_TRIGGER 0x5A000000
@@ -70,9 +173,20 @@
/* BLOCK_ENABLES2 */
#define CS35L45_ASP_EN_SHIFT 27
+#define CS35L45_MEM_RDY_SHIFT 1
+#define CS35L45_MEM_RDY_MASK BIT(1)
+
/* ERROR_RELEASE */
#define CS35L45_GLOBAL_ERR_RLS_MASK BIT(11)
+/* CCM_CORE */
+#define CS35L45_CCM_CORE_RESET_SHIFT 9
+#define CS35L45_CCM_CORE_RESET_MASK BIT(9)
+#define CS35L45_CCM_PM_REMAP_SHIFT 7
+#define CS35L45_CCM_PM_REMAP_MASK BIT(7)
+#define CS35L45_CCM_CORE_EN_SHIFT 0
+#define CS35L45_CCM_CORE_EN_MASK BIT(0)
+
/* REFCLK_INPUT */
#define CS35L45_PLL_FORCE_EN_SHIFT 16
#define CS35L45_PLL_FORCE_EN_MASK BIT(16)
@@ -165,6 +279,56 @@
#define CS35L45_OTP_BOOT_DONE_STS_MASK BIT(1)
#define CS35L45_OTP_BUSY_MASK BIT(0)
+/* GPIOX_CTRL1 */
+#define CS35L45_GPIO_DIR_SHIFT 31
+#define CS35L45_GPIO_DIR_MASK BIT(31)
+#define CS35L45_GPIO_LVL_SHIFT 15
+#define CS35L45_GPIO_LVL_MASK BIT(15)
+#define CS35L45_GPIO_OP_CFG_SHIFT 14
+#define CS35L45_GPIO_OP_CFG_MASK BIT(14)
+#define CS35L45_GPIO_POL_SHIFT 12
+#define CS35L45_GPIO_POL_MASK BIT(12)
+
+/* SYNC_GPIO1, INTB_GPIO2_MCLK_REF, GPIO3 */
+#define CS35L45_GPIO_CTRL_SHIFT 20
+#define CS35L45_GPIO_CTRL_MASK GENMASK(22, 20)
+#define CS35L45_GPIO_INVERT_SHIFT 19
+#define CS35L45_GPIO_INVERT_MASK BIT(19)
+
+/* CS35L45_IRQ1_EINT_1 */
+#define CS35L45_BST_UVP_ERR_SHIFT 7
+#define CS35L45_BST_UVP_ERR_MASK BIT(7)
+#define CS35L45_BST_SHORT_ERR_SHIFT 8
+#define CS35L45_BST_SHORT_ERR_MASK BIT(8)
+#define CS35L45_TEMP_ERR_SHIFT 17
+#define CS35L45_TEMP_ERR_MASK BIT(17)
+#define CS35L45_MSM_GLOBAL_EN_ASSERT_SHIFT 22
+#define CS35L45_MSM_GLOBAL_EN_ASSERT_MASK BIT(22)
+#define CS35L45_UVLO_VDDBATT_ERR_SHIFT 29
+#define CS35L45_UVLO_VDDBATT_ERR_MASK BIT(29)
+#define CS35L45_AMP_SHORT_ERR_SHIFT 31
+#define CS35L45_AMP_SHORT_ERR_MASK BIT(31)
+
+/* CS35L45_IRQ1_EINT_2 */
+#define CS35L45_DSP_WDT_EXPIRE_SHIFT 4
+#define CS35L45_DSP_WDT_EXPIRE_MASK BIT(4)
+#define CS35L45_DSP_VIRT2_MBOX_SHIFT 21
+#define CS35L45_DSP_VIRT2_MBOX_MASK BIT(21)
+
+/* CS35L45_IRQ1_EINT_3 */
+#define CS35L45_PLL_LOCK_FLAG_SHIFT 1
+#define CS35L45_PLL_LOCK_FLAG_MASK BIT(1)
+#define CS35L45_PLL_UNLOCK_FLAG_RISE_SHIFT 4
+#define CS35L45_PLL_UNLOCK_FLAG_RISE_MASK BIT(4)
+#define CS35L45_AMP_CAL_ERR_SHIFT 25
+#define CS35L45_AMP_CAL_ERR_MASK BIT(25)
+
+/* CS35L45_IRQ1_EINT_18 */
+#define CS35L45_GLOBAL_ERROR_SHIFT 15
+#define CS35L45_GLOBAL_ERROR_MASK BIT(15)
+#define CS35L45_UVLO_VDDLV_ERR_SHIFT 16
+#define CS35L45_UVLO_VDDLV_ERR_MASK BIT(16)
+
/* Mixer sources */
#define CS35L45_PCM_SRC_MASK 0x7F
#define CS35L45_PCM_SRC_ZERO 0x00
@@ -176,6 +340,8 @@
#define CS35L45_PCM_SRC_CLASSH_TGT 0x21
#define CS35L45_PCM_SRC_VDD_BATTMON 0x28
#define CS35L45_PCM_SRC_VDD_BSTMON 0x29
+#define CS35L45_PCM_SRC_DSP_TX1 0x32
+#define CS35L45_PCM_SRC_DSP_TX2 0x33
#define CS35L45_PCM_SRC_TEMPMON 0x3A
#define CS35L45_PCM_SRC_INTERPOLATOR 0x40
#define CS35L45_PCM_SRC_IL_TARGET 0x48
@@ -185,6 +351,51 @@
#define CS35L45_POST_GLOBAL_EN_US 5000
#define CS35L45_PRE_GLOBAL_DIS_US 3000
+/* WAKESRC_CTL */
+#define CS35L45_WKSRC_SYNC_GPIO1 BIT(0)
+#define CS35L45_WKSRC_INT_GPIO2 BIT(1)
+#define CS35L45_WKSRC_GPIO3 BIT(2)
+#define CS35L45_WKSRC_SPI BIT(3)
+#define CS35L45_WKSRC_I2C BIT(4)
+#define CS35L45_UPDT_WKCTL_SHIFT 15
+#define CS35L45_UPDT_WKCTL_MASK BIT(15)
+#define CS35L45_WKSRC_EN_SHIFT 8
+#define CS35L45_WKSRC_EN_MASK GENMASK(12, 8)
+#define CS35L45_WKSRC_POL_SHIFT 0
+#define CS35L45_WKSRC_POL_MASK GENMASK(3, 0)
+
+/* WAKEI2C_CTL */
+#define CS35L45_UPDT_WKI2C_SHIFT 15
+#define CS35L45_UPDT_WKI2C_MASK BIT(15)
+#define CS35L45_WKI2C_ADDR_SHIFT 0
+#define CS35L45_WKI2C_ADDR_MASK GENMASK(6, 0)
+
+#define CS35L45_SPI_MAX_FREQ 4000000
+
+enum cs35l45_cspl_mboxstate {
+ CSPL_MBOX_STS_RUNNING = 0,
+ CSPL_MBOX_STS_PAUSED = 1,
+ CSPL_MBOX_STS_RDY_FOR_REINIT = 2,
+ CSPL_MBOX_STS_HIBERNATE = 3,
+};
+
+enum cs35l45_cspl_mboxcmd {
+ CSPL_MBOX_CMD_NONE = 0,
+ CSPL_MBOX_CMD_PAUSE = 1,
+ CSPL_MBOX_CMD_RESUME = 2,
+ CSPL_MBOX_CMD_REINIT = 3,
+ CSPL_MBOX_CMD_STOP_PRE_REINIT = 4,
+ CSPL_MBOX_CMD_HIBERNATE = 5,
+ CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6,
+ CSPL_MBOX_CMD_UNKNOWN_CMD = -1,
+ CSPL_MBOX_CMD_INVALID_SEQUENCE = -2,
+};
+
+enum control_bus_type {
+ CONTROL_BUS_I2C = 0,
+ CONTROL_BUS_SPI = 1,
+};
+
#define CS35L45_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_3LE| \
SNDRV_PCM_FMTBIT_S24_LE)
@@ -194,7 +405,56 @@
SNDRV_PCM_RATE_88200 | \
SNDRV_PCM_RATE_96000)
+/*
+ * IRQs
+ */
+#define CS35L45_IRQ(_irq, _name, _hand) \
+ { \
+ .irq = CS35L45_ ## _irq ## _IRQ,\
+ .name = _name, \
+ .handler = _hand, \
+ }
+
+struct cs35l45_irq {
+ int irq;
+ const char *name;
+ irqreturn_t (*handler)(int irq, void *data);
+};
+
+#define CS35L45_REG_IRQ(_reg, _irq) \
+ [CS35L45_ ## _irq ## _IRQ] = { \
+ .reg_offset = (CS35L45_ ## _reg) - CS35L45_IRQ1_EINT_1, \
+ .mask = CS35L45_ ## _irq ## _MASK \
+ }
+
+enum cs35l45_irq_list {
+ CS35L45_AMP_SHORT_ERR_IRQ,
+ CS35L45_UVLO_VDDBATT_ERR_IRQ,
+ CS35L45_BST_SHORT_ERR_IRQ,
+ CS35L45_BST_UVP_ERR_IRQ,
+ CS35L45_TEMP_ERR_IRQ,
+ CS35L45_AMP_CAL_ERR_IRQ,
+ CS35L45_UVLO_VDDLV_ERR_IRQ,
+ CS35L45_GLOBAL_ERROR_IRQ,
+ CS35L45_DSP_WDT_EXPIRE_IRQ,
+ CS35L45_PLL_UNLOCK_FLAG_RISE_IRQ,
+ CS35L45_PLL_LOCK_FLAG_IRQ,
+ CS35L45_DSP_VIRT2_MBOX_IRQ,
+ CS35L45_NUM_IRQ
+};
+
+#define CS35L45_MBOX3_CMD_MASK 0xFF
+#define CS35L45_MBOX3_CMD_SHIFT 0
+#define CS35L45_MBOX3_DATA_MASK 0xFFFFFF00
+#define CS35L45_MBOX3_DATA_SHIFT 8
+
+enum mbox3_events {
+ EVENT_SPEAKER_STATUS = 0x66,
+ EVENT_BOOT_DONE = 0x67,
+};
+
struct cs35l45_private {
+ struct wm_adsp dsp; /* needs to be first member */
struct device *dev;
struct regmap *regmap;
struct gpio_desc *reset_gpio;
@@ -204,6 +464,11 @@ struct cs35l45_private {
bool sysclk_set;
u8 slot_width;
u8 slot_count;
+ int irq_invert;
+ int irq;
+ unsigned int i2c_addr;
+ enum control_bus_type bus_type;
+ struct regmap_irq_chip_data *irq_data;
};
extern const struct dev_pm_ops cs35l45_pm_ops;
diff --git a/sound/soc/codecs/cs35l56-i2c.c b/sound/soc/codecs/cs35l56-i2c.c
new file mode 100644
index 000000000000..4b7f034a7670
--- /dev/null
+++ b/sound/soc/codecs/cs35l56-i2c.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// CS35L56 ALSA SoC audio driver I2C binding
+//
+// Copyright (C) 2023 Cirrus Logic, Inc. and
+// Cirrus Logic International Semiconductor Ltd.
+
+#include <linux/acpi.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "cs35l56.h"
+
+static int cs35l56_i2c_probe(struct i2c_client *client)
+{
+ struct cs35l56_private *cs35l56;
+ struct device *dev = &client->dev;
+ const struct regmap_config *regmap_config = &cs35l56_regmap_i2c;
+ int ret;
+
+ cs35l56 = devm_kzalloc(dev, sizeof(struct cs35l56_private), GFP_KERNEL);
+ if (!cs35l56)
+ return -ENOMEM;
+
+ cs35l56->dev = dev;
+ cs35l56->irq = client->irq;
+ cs35l56->can_hibernate = true;
+
+ i2c_set_clientdata(client, cs35l56);
+ cs35l56->regmap = devm_regmap_init_i2c(client, regmap_config);
+ if (IS_ERR(cs35l56->regmap)) {
+ ret = PTR_ERR(cs35l56->regmap);
+ return dev_err_probe(cs35l56->dev, ret, "Failed to allocate register map\n");
+ }
+
+ ret = cs35l56_common_probe(cs35l56);
+ if (ret != 0)
+ return ret;
+
+ ret = cs35l56_init(cs35l56);
+ if (ret == 0)
+ ret = cs35l56_irq_request(cs35l56);
+ if (ret < 0)
+ cs35l56_remove(cs35l56);
+
+ return ret;
+}
+
+static void cs35l56_i2c_remove(struct i2c_client *client)
+{
+ struct cs35l56_private *cs35l56 = i2c_get_clientdata(client);
+
+ cs35l56_remove(cs35l56);
+}
+
+static const struct i2c_device_id cs35l56_id_i2c[] = {
+ { "cs35l56", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, cs35l56_id_i2c);
+
+static struct i2c_driver cs35l56_i2c_driver = {
+ .driver = {
+ .name = "cs35l56",
+ .pm = &cs35l56_pm_ops_i2c_spi,
+ },
+ .id_table = cs35l56_id_i2c,
+ .probe_new = cs35l56_i2c_probe,
+ .remove = cs35l56_i2c_remove,
+};
+
+module_i2c_driver(cs35l56_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC CS35L56 I2C driver");
+MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
new file mode 100644
index 000000000000..448ef3609f4c
--- /dev/null
+++ b/sound/soc/codecs/cs35l56-sdw.c
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// CS35L56 ALSA SoC audio driver SoundWire binding
+//
+// Copyright (C) 2023 Cirrus Logic, Inc. and
+// Cirrus Logic International Semiconductor Ltd.
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_registers.h>
+#include <linux/soundwire/sdw_type.h>
+#include <linux/swab.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "cs35l56.h"
+
+/* Register addresses are offset when sent over SoundWire */
+#define CS35L56_SDW_ADDR_OFFSET 0x8000
+
+static int cs35l56_sdw_read_one(struct sdw_slave *peripheral, unsigned int reg, void *buf)
+{
+ int ret;
+
+ ret = sdw_nread_no_pm(peripheral, reg, 4, (u8 *)buf);
+ if (ret != 0) {
+ dev_err(&peripheral->dev, "Read failed @%#x:%d\n", reg, ret);
+ return ret;
+ }
+
+ swab32s((u32 *)buf);
+
+ return 0;
+}
+
+static int cs35l56_sdw_read(void *context, const void *reg_buf,
+ const size_t reg_size, void *val_buf,
+ size_t val_size)
+{
+ struct sdw_slave *peripheral = context;
+ u8 *buf8 = val_buf;
+ unsigned int reg, bytes;
+ int ret;
+
+ reg = le32_to_cpu(*(const __le32 *)reg_buf);
+ reg += CS35L56_SDW_ADDR_OFFSET;
+
+ if (val_size == 4)
+ return cs35l56_sdw_read_one(peripheral, reg, val_buf);
+
+ while (val_size) {
+ bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR); /* to end of page */
+ if (bytes > val_size)
+ bytes = val_size;
+
+ ret = sdw_nread_no_pm(peripheral, reg, bytes, buf8);
+ if (ret != 0) {
+ dev_err(&peripheral->dev, "Read failed @%#x..%#x:%d\n",
+ reg, reg + bytes - 1, ret);
+ return ret;
+ }
+
+ swab32_array((u32 *)buf8, bytes / 4);
+ val_size -= bytes;
+ reg += bytes;
+ buf8 += bytes;
+ }
+
+ return 0;
+}
+
+static inline void cs35l56_swab_copy(void *dest, const void *src, size_t nbytes)
+{
+ u32 *dest32 = dest;
+ const u32 *src32 = src;
+
+ for (; nbytes > 0; nbytes -= 4)
+ *dest32++ = swab32(*src32++);
+}
+
+static int cs35l56_sdw_write_one(struct sdw_slave *peripheral, unsigned int reg, const void *buf)
+{
+ u32 val_le = swab32(*(u32 *)buf);
+ int ret;
+
+ ret = sdw_nwrite_no_pm(peripheral, reg, 4, (u8 *)&val_le);
+ if (ret != 0) {
+ dev_err(&peripheral->dev, "Write failed @%#x:%d\n", reg, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cs35l56_sdw_gather_write(void *context,
+ const void *reg_buf, size_t reg_size,
+ const void *val_buf, size_t val_size)
+{
+ struct sdw_slave *peripheral = context;
+ const u8 *src_be = val_buf;
+ u32 val_le_buf[64]; /* Define u32 so it is 32-bit aligned */
+ unsigned int reg, bytes;
+ int ret;
+
+ reg = le32_to_cpu(*(const __le32 *)reg_buf);
+ reg += CS35L56_SDW_ADDR_OFFSET;
+
+ if (val_size == 4)
+ return cs35l56_sdw_write_one(peripheral, reg, src_be);
+
+ while (val_size) {
+ bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR); /* to end of page */
+ if (bytes > val_size)
+ bytes = val_size;
+ if (bytes > sizeof(val_le_buf))
+ bytes = sizeof(val_le_buf);
+
+ cs35l56_swab_copy(val_le_buf, src_be, bytes);
+
+ ret = sdw_nwrite_no_pm(peripheral, reg, bytes, (u8 *)val_le_buf);
+ if (ret != 0) {
+ dev_err(&peripheral->dev, "Write failed @%#x..%#x:%d\n",
+ reg, reg + bytes - 1, ret);
+ return ret;
+ }
+
+ val_size -= bytes;
+ reg += bytes;
+ src_be += bytes;
+ }
+
+ return 0;
+}
+
+static int cs35l56_sdw_write(void *context, const void *val_buf, size_t val_size)
+{
+ const u8 *src_buf = val_buf;
+
+ /* First word of val_buf contains the destination address */
+ return cs35l56_sdw_gather_write(context, &src_buf[0], 4, &src_buf[4], val_size - 4);
+}
+
+/*
+ * Registers are big-endian on I2C and SPI but little-endian on SoundWire.
+ * Exported firmware controls are big-endian on I2C/SPI but little-endian on
+ * SoundWire. Firmware files are always big-endian and are opaque blobs.
+ * Present a big-endian regmap and hide the endianness swap, so that the ALSA
+ * byte controls always have the same byte order, and firmware file blobs
+ * can be written verbatim.
+ */
+static const struct regmap_bus cs35l56_regmap_bus_sdw = {
+ .read = cs35l56_sdw_read,
+ .write = cs35l56_sdw_write,
+ .gather_write = cs35l56_sdw_gather_write,
+ .reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
+ .val_format_endian_default = REGMAP_ENDIAN_BIG,
+};
+
+static void cs35l56_sdw_init(struct sdw_slave *peripheral)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
+ int ret;
+
+ pm_runtime_get_noresume(cs35l56->dev);
+
+ regcache_cache_only(cs35l56->regmap, false);
+
+ ret = cs35l56_init(cs35l56);
+ if (ret < 0) {
+ regcache_cache_only(cs35l56->regmap, true);
+ goto out;
+ }
+
+ /*
+ * cs35l56_init can return with !init_done if it triggered
+ * a soft reset.
+ */
+ if (cs35l56->init_done) {
+ /* Enable SoundWire interrupts */
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1,
+ CS35L56_SDW_INT_MASK_CODEC_IRQ);
+ }
+
+out:
+ pm_runtime_mark_last_busy(cs35l56->dev);
+ pm_runtime_put_autosuspend(cs35l56->dev);
+}
+
+static int cs35l56_sdw_interrupt(struct sdw_slave *peripheral,
+ struct sdw_slave_intr_status *status)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
+
+ /* SoundWire core holds our pm_runtime when calling this function. */
+
+ dev_dbg(cs35l56->dev, "int control_port=%#x\n", status->control_port);
+
+ if ((status->control_port & SDW_SCP_INT1_IMPL_DEF) == 0)
+ return 0;
+
+ /*
+ * Prevent bus manager suspending and possibly issuing a
+ * bus-reset before the queued work has run.
+ */
+ pm_runtime_get_noresume(cs35l56->dev);
+
+ /*
+ * Mask and clear until it has been handled. The read of GEN_INT_STAT_1
+ * is required as per the SoundWire spec for interrupt status bits
+ * to clear. GEN_INT_MASK_1 masks the _inputs_ to GEN_INT_STAT1.
+ * None of the interrupts are time-critical so use the
+ * power-efficient queue.
+ */
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
+ sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
+ queue_work(system_power_efficient_wq, &cs35l56->sdw_irq_work);
+
+ return 0;
+}
+
+static void cs35l56_sdw_irq_work(struct work_struct *work)
+{
+ struct cs35l56_private *cs35l56 = container_of(work,
+ struct cs35l56_private,
+ sdw_irq_work);
+
+ cs35l56_irq(-1, cs35l56);
+
+ /* unmask interrupts */
+ if (!cs35l56->sdw_irq_no_unmask)
+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
+ CS35L56_SDW_INT_MASK_CODEC_IRQ);
+
+ pm_runtime_put_autosuspend(cs35l56->dev);
+}
+
+static int cs35l56_sdw_read_prop(struct sdw_slave *peripheral)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
+ struct sdw_slave_prop *prop = &peripheral->prop;
+ struct sdw_dpn_prop *ports;
+
+ ports = devm_kcalloc(cs35l56->dev, 2, sizeof(*ports), GFP_KERNEL);
+ if (!ports)
+ return -ENOMEM;
+
+ prop->source_ports = BIT(CS35L56_SDW1_CAPTURE_PORT);
+ prop->sink_ports = BIT(CS35L56_SDW1_PLAYBACK_PORT);
+ prop->paging_support = true;
+ prop->clk_stop_mode1 = false;
+ prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
+ prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY | SDW_SCP_INT1_IMPL_DEF;
+
+ /* DP1 - playback */
+ ports[0].num = CS35L56_SDW1_PLAYBACK_PORT;
+ ports[0].type = SDW_DPN_FULL;
+ ports[0].ch_prep_timeout = 10;
+ prop->sink_dpn_prop = &ports[0];
+
+ /* DP3 - capture */
+ ports[1].num = CS35L56_SDW1_CAPTURE_PORT;
+ ports[1].type = SDW_DPN_FULL;
+ ports[1].ch_prep_timeout = 10;
+ prop->src_dpn_prop = &ports[1];
+
+ return 0;
+}
+
+static int cs35l56_sdw_update_status(struct sdw_slave *peripheral,
+ enum sdw_slave_status status)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
+
+ switch (status) {
+ case SDW_SLAVE_ATTACHED:
+ dev_dbg(cs35l56->dev, "%s: ATTACHED\n", __func__);
+ if (cs35l56->sdw_attached)
+ break;
+
+ if (!cs35l56->init_done || cs35l56->soft_resetting)
+ cs35l56_sdw_init(peripheral);
+
+ cs35l56->sdw_attached = true;
+ break;
+ case SDW_SLAVE_UNATTACHED:
+ dev_dbg(cs35l56->dev, "%s: UNATTACHED\n", __func__);
+ cs35l56->sdw_attached = false;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int cs35l56_a1_kick_divider(struct cs35l56_private *cs35l56,
+ struct sdw_slave *peripheral)
+{
+ unsigned int curr_scale_reg, next_scale_reg;
+ int curr_scale, next_scale, ret;
+
+ if (!cs35l56->init_done)
+ return 0;
+
+ if (peripheral->bus->params.curr_bank) {
+ curr_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B1;
+ next_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B0;
+ } else {
+ curr_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B0;
+ next_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B1;
+ }
+
+ /*
+ * Current clock scale value must be different to new value.
+ * Modify current to guarantee this. If next still has the dummy
+ * value we wrote when it was current, the core code has not set
+ * a new scale so restore its original good value
+ */
+ curr_scale = sdw_read_no_pm(peripheral, curr_scale_reg);
+ if (curr_scale < 0) {
+ dev_err(cs35l56->dev, "Failed to read current clock scale: %d\n", curr_scale);
+ return curr_scale;
+ }
+
+ next_scale = sdw_read_no_pm(peripheral, next_scale_reg);
+ if (next_scale < 0) {
+ dev_err(cs35l56->dev, "Failed to read next clock scale: %d\n", next_scale);
+ return next_scale;
+ }
+
+ if (next_scale == CS35L56_SDW_INVALID_BUS_SCALE) {
+ next_scale = cs35l56->old_sdw_clock_scale;
+ ret = sdw_write_no_pm(peripheral, next_scale_reg, next_scale);
+ if (ret < 0) {
+ dev_err(cs35l56->dev, "Failed to modify current clock scale: %d\n", ret);
+ return ret;
+ }
+ }
+
+ cs35l56->old_sdw_clock_scale = curr_scale;
+ ret = sdw_write_no_pm(peripheral, curr_scale_reg, CS35L56_SDW_INVALID_BUS_SCALE);
+ if (ret < 0) {
+ dev_err(cs35l56->dev, "Failed to modify current clock scale: %d\n", ret);
+ return ret;
+ }
+
+ dev_dbg(cs35l56->dev, "Next bus scale: %#x\n", next_scale);
+
+ return 0;
+}
+
+static int cs35l56_sdw_bus_config(struct sdw_slave *peripheral,
+ struct sdw_bus_params *params)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
+ int sclk;
+
+ sclk = params->curr_dr_freq / 2;
+ dev_dbg(cs35l56->dev, "%s: sclk=%u c=%u r=%u\n", __func__, sclk, params->col, params->row);
+
+ if (cs35l56->rev < 0xb0)
+ return cs35l56_a1_kick_divider(cs35l56, peripheral);
+
+ return 0;
+}
+
+static int __maybe_unused cs35l56_sdw_clk_stop(struct sdw_slave *peripheral,
+ enum sdw_clk_stop_mode mode,
+ enum sdw_clk_stop_type type)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
+
+ dev_dbg(cs35l56->dev, "%s: mode:%d type:%d\n", __func__, mode, type);
+
+ return 0;
+}
+
+static const struct sdw_slave_ops cs35l56_sdw_ops = {
+ .read_prop = cs35l56_sdw_read_prop,
+ .interrupt_callback = cs35l56_sdw_interrupt,
+ .update_status = cs35l56_sdw_update_status,
+ .bus_config = cs35l56_sdw_bus_config,
+#ifdef DEBUG
+ .clk_stop = cs35l56_sdw_clk_stop,
+#endif
+};
+
+static int __maybe_unused cs35l56_sdw_handle_unattach(struct cs35l56_private *cs35l56)
+{
+ struct sdw_slave *peripheral = cs35l56->sdw_peripheral;
+
+ if (peripheral->unattach_request) {
+ /* Cannot access registers until bus is re-initialized. */
+ dev_dbg(cs35l56->dev, "Wait for initialization_complete\n");
+ if (!wait_for_completion_timeout(&peripheral->initialization_complete,
+ msecs_to_jiffies(5000))) {
+ dev_err(cs35l56->dev, "initialization_complete timed out\n");
+ return -ETIMEDOUT;
+ }
+
+ peripheral->unattach_request = 0;
+
+ /*
+ * Don't call regcache_mark_dirty(), we can't be sure that the
+ * Manager really did issue a Bus Reset.
+ */
+ }
+
+ return 0;
+}
+
+static int __maybe_unused cs35l56_sdw_runtime_suspend(struct device *dev)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
+
+ if (!cs35l56->init_done)
+ return 0;
+
+ return cs35l56_runtime_suspend(dev);
+}
+
+static int __maybe_unused cs35l56_sdw_runtime_resume(struct device *dev)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
+ int ret;
+
+ dev_dbg(dev, "Runtime resume\n");
+
+ if (!cs35l56->init_done)
+ return 0;
+
+ ret = cs35l56_sdw_handle_unattach(cs35l56);
+ if (ret < 0)
+ return ret;
+
+ ret = cs35l56_runtime_resume_common(cs35l56);
+ if (ret)
+ return ret;
+
+ /* Re-enable SoundWire interrupts */
+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
+ CS35L56_SDW_INT_MASK_CODEC_IRQ);
+
+ return 0;
+}
+
+static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_device_id *id)
+{
+ struct device *dev = &peripheral->dev;
+ struct cs35l56_private *cs35l56;
+ int ret;
+
+ cs35l56 = devm_kzalloc(dev, sizeof(*cs35l56), GFP_KERNEL);
+ if (!cs35l56)
+ return -ENOMEM;
+
+ cs35l56->dev = dev;
+ cs35l56->sdw_peripheral = peripheral;
+ INIT_WORK(&cs35l56->sdw_irq_work, cs35l56_sdw_irq_work);
+
+ dev_set_drvdata(dev, cs35l56);
+
+ cs35l56->regmap = devm_regmap_init(dev, &cs35l56_regmap_bus_sdw,
+ peripheral, &cs35l56_regmap_sdw);
+ if (IS_ERR(cs35l56->regmap)) {
+ ret = PTR_ERR(cs35l56->regmap);
+ return dev_err_probe(dev, ret, "Failed to allocate register map\n");
+ }
+
+ /* Start in cache-only until device is enumerated */
+ regcache_cache_only(cs35l56->regmap, true);
+
+ ret = cs35l56_common_probe(cs35l56);
+ if (ret != 0)
+ return ret;
+
+ return 0;
+}
+
+static int cs35l56_sdw_remove(struct sdw_slave *peripheral)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
+
+ /* Disable SoundWire interrupts */
+ cs35l56->sdw_irq_no_unmask = true;
+ cancel_work_sync(&cs35l56->sdw_irq_work);
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
+ sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
+
+ return cs35l56_remove(cs35l56);
+}
+
+static const struct dev_pm_ops cs35l56_sdw_pm = {
+ SET_RUNTIME_PM_OPS(cs35l56_sdw_runtime_suspend, cs35l56_sdw_runtime_resume, NULL)
+};
+
+static const struct sdw_device_id cs35l56_sdw_id[] = {
+ SDW_SLAVE_ENTRY(0x01FA, 0x3556, 0),
+ {},
+};
+MODULE_DEVICE_TABLE(sdw, cs35l56_sdw_id);
+
+static struct sdw_driver cs35l56_sdw_driver = {
+ .driver = {
+ .name = "cs35l56",
+ .pm = &cs35l56_sdw_pm,
+ },
+ .probe = cs35l56_sdw_probe,
+ .remove = cs35l56_sdw_remove,
+ .ops = &cs35l56_sdw_ops,
+ .id_table = cs35l56_sdw_id,
+};
+
+module_sdw_driver(cs35l56_sdw_driver);
+
+MODULE_DESCRIPTION("ASoC CS35L56 SoundWire driver");
+MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
new file mode 100644
index 000000000000..d8bc06ad4888
--- /dev/null
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Components shared between ASoC and HDA CS35L56 drivers
+//
+// Copyright (C) 2023 Cirrus Logic, Inc. and
+// Cirrus Logic International Semiconductor Ltd.
+
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+
+#include "cs35l56.h"
+
+static const struct reg_default cs35l56_reg_defaults[] = {
+ { CS35L56_ASP1_ENABLES1, 0x00000000 },
+ { CS35L56_ASP1_CONTROL1, 0x00000028 },
+ { CS35L56_ASP1_CONTROL2, 0x18180200 },
+ { CS35L56_ASP1_CONTROL3, 0x00000002 },
+ { CS35L56_ASP1_FRAME_CONTROL1, 0x03020100 },
+ { CS35L56_ASP1_FRAME_CONTROL5, 0x00020100 },
+ { CS35L56_ASP1_DATA_CONTROL1, 0x00000018 },
+ { CS35L56_ASP1_DATA_CONTROL5, 0x00000018 },
+ { CS35L56_ASP1TX1_INPUT, 0x00000018 },
+ { CS35L56_ASP1TX2_INPUT, 0x00000019 },
+ { CS35L56_ASP1TX3_INPUT, 0x00000020 },
+ { CS35L56_ASP1TX4_INPUT, 0x00000028 },
+ { CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 },
+ { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
+ { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 },
+ { CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 },
+ { CS35L56_SWIRE_DP3_CH5_INPUT, 0x00000018 },
+ { CS35L56_SWIRE_DP3_CH6_INPUT, 0x00000018 },
+ { CS35L56_IRQ1_CFG, 0x00000000 },
+ { CS35L56_IRQ1_MASK_1, 0x83ffffff },
+ { CS35L56_IRQ1_MASK_2, 0xffff7fff },
+ { CS35L56_IRQ1_MASK_4, 0xe0ffffff },
+ { CS35L56_IRQ1_MASK_8, 0xfc000fff },
+ { CS35L56_IRQ1_MASK_18, 0x1f7df0ff },
+ { CS35L56_IRQ1_MASK_20, 0x15c00000 },
+ /* CS35L56_MAIN_RENDER_USER_MUTE - soft register, no default */
+ /* CS35L56_MAIN_RENDER_USER_VOLUME - soft register, no default */
+ /* CS35L56_MAIN_POSTURE_NUMBER - soft register, no default */
+};
+
+/*
+ * The Ax devices have different default register values to that of B0,
+ * establish a common set of register defaults.
+ */
+static const struct reg_sequence cs35l56_reva_patch[] = {
+ { CS35L56_SWIRE_DP3_CH5_INPUT, 0x00000018 },
+ { CS35L56_SWIRE_DP3_CH6_INPUT, 0x00000018 },
+};
+
+void cs35l56_patch(struct device *dev, struct regmap *regmap, u8 revid)
+{
+ int ret;
+
+ if (revid >= CS35L56_REVID_B0)
+ return;
+
+ ret = regmap_register_patch(regmap, cs35l56_reva_patch,
+ ARRAY_SIZE(cs35l56_reva_patch));
+ if (ret)
+ dev_err(dev, "Failed to apply patch: %d\n", ret);
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_patch, SND_SOC_CS35L56_SHARED);
+
+static bool cs35l56_is_dsp_memory(unsigned int reg)
+{
+ switch (reg) {
+ case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
+ case CS35L56_DSP1_XMEM_UNPACKED32_0 ... CS35L56_DSP1_XMEM_UNPACKED32_4095:
+ case CS35L56_DSP1_XMEM_UNPACKED24_0 ... CS35L56_DSP1_XMEM_UNPACKED24_8191:
+ case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
+ case CS35L56_DSP1_YMEM_UNPACKED32_0 ... CS35L56_DSP1_YMEM_UNPACKED32_3070:
+ case CS35L56_DSP1_YMEM_UNPACKED24_0 ... CS35L56_DSP1_YMEM_UNPACKED24_6141:
+ case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool cs35l56_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS35L56_DEVID:
+ case CS35L56_REVID:
+ case CS35L56_RELID:
+ case CS35L56_OTPID:
+ case CS35L56_SFT_RESET:
+ case CS35L56_GLOBAL_ENABLES:
+ case CS35L56_BLOCK_ENABLES:
+ case CS35L56_BLOCK_ENABLES2:
+ case CS35L56_REFCLK_INPUT:
+ case CS35L56_GLOBAL_SAMPLE_RATE:
+ case CS35L56_ASP1_ENABLES1:
+ case CS35L56_ASP1_CONTROL1:
+ case CS35L56_ASP1_CONTROL2:
+ case CS35L56_ASP1_CONTROL3:
+ case CS35L56_ASP1_FRAME_CONTROL1:
+ case CS35L56_ASP1_FRAME_CONTROL5:
+ case CS35L56_ASP1_DATA_CONTROL1:
+ case CS35L56_ASP1_DATA_CONTROL5:
+ case CS35L56_DACPCM1_INPUT:
+ case CS35L56_DACPCM2_INPUT:
+ case CS35L56_ASP1TX1_INPUT:
+ case CS35L56_ASP1TX2_INPUT:
+ case CS35L56_ASP1TX3_INPUT:
+ case CS35L56_ASP1TX4_INPUT:
+ case CS35L56_DSP1RX1_INPUT:
+ case CS35L56_DSP1RX2_INPUT:
+ case CS35L56_SWIRE_DP3_CH1_INPUT:
+ case CS35L56_SWIRE_DP3_CH2_INPUT:
+ case CS35L56_SWIRE_DP3_CH3_INPUT:
+ case CS35L56_SWIRE_DP3_CH4_INPUT:
+ case CS35L56_SWIRE_DP3_CH5_INPUT:
+ case CS35L56_SWIRE_DP3_CH6_INPUT:
+ case CS35L56_IRQ1_CFG:
+ case CS35L56_IRQ1_STATUS:
+ case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
+ case CS35L56_IRQ1_EINT_18:
+ case CS35L56_IRQ1_EINT_20:
+ case CS35L56_IRQ1_MASK_1:
+ case CS35L56_IRQ1_MASK_2:
+ case CS35L56_IRQ1_MASK_4:
+ case CS35L56_IRQ1_MASK_8:
+ case CS35L56_IRQ1_MASK_18:
+ case CS35L56_IRQ1_MASK_20:
+ case CS35L56_DSP_VIRTUAL1_MBOX_1:
+ case CS35L56_DSP_VIRTUAL1_MBOX_2:
+ case CS35L56_DSP_VIRTUAL1_MBOX_3:
+ case CS35L56_DSP_VIRTUAL1_MBOX_4:
+ case CS35L56_DSP_VIRTUAL1_MBOX_5:
+ case CS35L56_DSP_VIRTUAL1_MBOX_6:
+ case CS35L56_DSP_VIRTUAL1_MBOX_7:
+ case CS35L56_DSP_VIRTUAL1_MBOX_8:
+ case CS35L56_DSP_RESTRICT_STS1:
+ case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
+ case CS35L56_DSP1_SCRATCH1:
+ case CS35L56_DSP1_SCRATCH2:
+ case CS35L56_DSP1_SCRATCH3:
+ case CS35L56_DSP1_SCRATCH4:
+ return true;
+ default:
+ return cs35l56_is_dsp_memory(reg);
+ }
+}
+
+static bool cs35l56_precious_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
+ case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
+ case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS35L56_DEVID:
+ case CS35L56_REVID:
+ case CS35L56_RELID:
+ case CS35L56_OTPID:
+ case CS35L56_SFT_RESET:
+ case CS35L56_GLOBAL_ENABLES: /* owned by firmware */
+ case CS35L56_BLOCK_ENABLES: /* owned by firmware */
+ case CS35L56_BLOCK_ENABLES2: /* owned by firmware */
+ case CS35L56_REFCLK_INPUT: /* owned by firmware */
+ case CS35L56_GLOBAL_SAMPLE_RATE: /* owned by firmware */
+ case CS35L56_DACPCM1_INPUT: /* owned by firmware */
+ case CS35L56_DACPCM2_INPUT: /* owned by firmware */
+ case CS35L56_DSP1RX1_INPUT: /* owned by firmware */
+ case CS35L56_DSP1RX2_INPUT: /* owned by firmware */
+ case CS35L56_IRQ1_STATUS:
+ case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
+ case CS35L56_IRQ1_EINT_18:
+ case CS35L56_IRQ1_EINT_20:
+ case CS35L56_DSP_VIRTUAL1_MBOX_1:
+ case CS35L56_DSP_VIRTUAL1_MBOX_2:
+ case CS35L56_DSP_VIRTUAL1_MBOX_3:
+ case CS35L56_DSP_VIRTUAL1_MBOX_4:
+ case CS35L56_DSP_VIRTUAL1_MBOX_5:
+ case CS35L56_DSP_VIRTUAL1_MBOX_6:
+ case CS35L56_DSP_VIRTUAL1_MBOX_7:
+ case CS35L56_DSP_VIRTUAL1_MBOX_8:
+ case CS35L56_DSP_RESTRICT_STS1:
+ case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
+ case CS35L56_DSP1_SCRATCH1:
+ case CS35L56_DSP1_SCRATCH2:
+ case CS35L56_DSP1_SCRATCH3:
+ case CS35L56_DSP1_SCRATCH4:
+ return true;
+ case CS35L56_MAIN_RENDER_USER_MUTE:
+ case CS35L56_MAIN_RENDER_USER_VOLUME:
+ case CS35L56_MAIN_POSTURE_NUMBER:
+ return false;
+ default:
+ return cs35l56_is_dsp_memory(reg);
+ }
+}
+
+static const u32 cs35l56_firmware_registers[] = {
+ CS35L56_MAIN_RENDER_USER_MUTE,
+ CS35L56_MAIN_RENDER_USER_VOLUME,
+ CS35L56_MAIN_POSTURE_NUMBER,
+};
+
+void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap)
+{
+ int i;
+ unsigned int val;
+
+ for (i = 0; i < ARRAY_SIZE(cs35l56_firmware_registers); i++) {
+ regmap_read(regmap, cs35l56_firmware_registers[i], &val);
+ dev_dbg(dev, "%s: %d: %#x: %#x\n", __func__,
+ i, cs35l56_firmware_registers[i], val);
+ }
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_reread_firmware_registers, SND_SOC_CS35L56_SHARED);
+
+const struct cs_dsp_region cs35l56_dsp1_regions[] = {
+ { .type = WMFW_HALO_PM_PACKED, .base = CS35L56_DSP1_PMEM_0 },
+ { .type = WMFW_HALO_XM_PACKED, .base = CS35L56_DSP1_XMEM_PACKED_0 },
+ { .type = WMFW_HALO_YM_PACKED, .base = CS35L56_DSP1_YMEM_PACKED_0 },
+ { .type = WMFW_ADSP2_XM, .base = CS35L56_DSP1_XMEM_UNPACKED24_0 },
+ { .type = WMFW_ADSP2_YM, .base = CS35L56_DSP1_YMEM_UNPACKED24_0 },
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_dsp1_regions, SND_SOC_CS35L56_SHARED);
+
+static const u32 cs35l56_bclk_valid_for_pll_freq_table[] = {
+ [0x0C] = 128000,
+ [0x0F] = 256000,
+ [0x11] = 384000,
+ [0x12] = 512000,
+ [0x15] = 768000,
+ [0x17] = 1024000,
+ [0x1A] = 1500000,
+ [0x1B] = 1536000,
+ [0x1C] = 2000000,
+ [0x1D] = 2048000,
+ [0x1E] = 2400000,
+ [0x20] = 3000000,
+ [0x21] = 3072000,
+ [0x23] = 4000000,
+ [0x24] = 4096000,
+ [0x25] = 4800000,
+ [0x27] = 6000000,
+ [0x28] = 6144000,
+ [0x29] = 6250000,
+ [0x2A] = 6400000,
+ [0x2E] = 8000000,
+ [0x2F] = 8192000,
+ [0x30] = 9600000,
+ [0x32] = 12000000,
+ [0x33] = 12288000,
+ [0x37] = 13500000,
+ [0x38] = 19200000,
+ [0x39] = 22579200,
+ [0x3B] = 24576000,
+};
+
+int cs35l56_get_bclk_freq_id(unsigned int freq)
+{
+ int i;
+
+ if (freq == 0)
+ return -EINVAL;
+
+ /* The BCLK frequency must be a valid PLL REFCLK */
+ for (i = 0; i < ARRAY_SIZE(cs35l56_bclk_valid_for_pll_freq_table); ++i) {
+ if (cs35l56_bclk_valid_for_pll_freq_table[i] == freq)
+ return i;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, SND_SOC_CS35L56_SHARED);
+
+static const char * const cs35l56_supplies[/* auto-sized */] = {
+ "VDD_P",
+ "VDD_IO",
+ "VDD_A",
+};
+
+void cs35l56_fill_supply_names(struct regulator_bulk_data *data)
+{
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cs35l56_supplies) != CS35L56_NUM_BULK_SUPPLIES);
+ for (i = 0; i < ARRAY_SIZE(cs35l56_supplies); i++)
+ data[i].supply = cs35l56_supplies[i];
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, SND_SOC_CS35L56_SHARED);
+
+const char * const cs35l56_tx_input_texts[] = {
+ "None", "ASP1RX1", "ASP1RX2", "VMON", "IMON", "ERRVOL", "CLASSH",
+ "VDDBMON", "VBSTMON", "DSP1TX1", "DSP1TX2", "DSP1TX3", "DSP1TX4",
+ "DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1TX8", "TEMPMON",
+ "INTERPOLATOR", "SDW1RX1", "SDW1RX2", "SDW2RX1",
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, SND_SOC_CS35L56_SHARED);
+
+const unsigned int cs35l56_tx_input_values[] = {
+ CS35L56_INPUT_SRC_NONE,
+ CS35L56_INPUT_SRC_ASP1RX1,
+ CS35L56_INPUT_SRC_ASP1RX2,
+ CS35L56_INPUT_SRC_VMON,
+ CS35L56_INPUT_SRC_IMON,
+ CS35L56_INPUT_SRC_ERR_VOL,
+ CS35L56_INPUT_SRC_CLASSH,
+ CS35L56_INPUT_SRC_VDDBMON,
+ CS35L56_INPUT_SRC_VBSTMON,
+ CS35L56_INPUT_SRC_DSP1TX1,
+ CS35L56_INPUT_SRC_DSP1TX2,
+ CS35L56_INPUT_SRC_DSP1TX3,
+ CS35L56_INPUT_SRC_DSP1TX4,
+ CS35L56_INPUT_SRC_DSP1TX5,
+ CS35L56_INPUT_SRC_DSP1TX6,
+ CS35L56_INPUT_SRC_DSP1TX7,
+ CS35L56_INPUT_SRC_DSP1TX8,
+ CS35L56_INPUT_SRC_TEMPMON,
+ CS35L56_INPUT_SRC_INTERPOLATOR,
+ CS35L56_INPUT_SRC_SWIRE_RX1,
+ CS35L56_INPUT_SRC_SWIRE_RX2,
+ CS35L56_INPUT_SRC_SWIRE_RX3,
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, SND_SOC_CS35L56_SHARED);
+
+struct regmap_config cs35l56_regmap_i2c = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .reg_format_endian = REGMAP_ENDIAN_BIG,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+ .max_register = CS35L56_DSP1_PMEM_5114,
+ .reg_defaults = cs35l56_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
+ .volatile_reg = cs35l56_volatile_reg,
+ .readable_reg = cs35l56_readable_reg,
+ .precious_reg = cs35l56_precious_reg,
+ .cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, SND_SOC_CS35L56_SHARED);
+
+struct regmap_config cs35l56_regmap_spi = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .pad_bits = 16,
+ .reg_stride = 4,
+ .reg_format_endian = REGMAP_ENDIAN_BIG,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+ .max_register = CS35L56_DSP1_PMEM_5114,
+ .reg_defaults = cs35l56_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
+ .volatile_reg = cs35l56_volatile_reg,
+ .readable_reg = cs35l56_readable_reg,
+ .precious_reg = cs35l56_precious_reg,
+ .cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, SND_SOC_CS35L56_SHARED);
+
+struct regmap_config cs35l56_regmap_sdw = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .reg_format_endian = REGMAP_ENDIAN_LITTLE,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+ .max_register = CS35L56_DSP1_PMEM_5114,
+ .reg_defaults = cs35l56_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
+ .volatile_reg = cs35l56_volatile_reg,
+ .readable_reg = cs35l56_readable_reg,
+ .precious_reg = cs35l56_precious_reg,
+ .cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, SND_SOC_CS35L56_SHARED);
+
+MODULE_DESCRIPTION("ASoC CS35L56 Shared");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c
new file mode 100644
index 000000000000..80dcf37daae2
--- /dev/null
+++ b/sound/soc/codecs/cs35l56-spi.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// CS35L56 ALSA SoC audio driver SPI binding
+//
+// Copyright (C) 2023 Cirrus Logic, Inc. and
+// Cirrus Logic International Semiconductor Ltd.
+
+#include <linux/acpi.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+
+#include "cs35l56.h"
+
+static int cs35l56_spi_probe(struct spi_device *spi)
+{
+ const struct regmap_config *regmap_config = &cs35l56_regmap_spi;
+ struct cs35l56_private *cs35l56;
+ int ret;
+
+ cs35l56 = devm_kzalloc(&spi->dev, sizeof(struct cs35l56_private), GFP_KERNEL);
+ if (!cs35l56)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, cs35l56);
+ cs35l56->regmap = devm_regmap_init_spi(spi, regmap_config);
+ if (IS_ERR(cs35l56->regmap)) {
+ ret = PTR_ERR(cs35l56->regmap);
+ return dev_err_probe(&spi->dev, ret, "Failed to allocate register map\n");
+ return ret;
+ }
+
+ cs35l56->dev = &spi->dev;
+ cs35l56->irq = spi->irq;
+
+ ret = cs35l56_common_probe(cs35l56);
+ if (ret != 0)
+ return ret;
+
+ ret = cs35l56_init(cs35l56);
+ if (ret == 0)
+ ret = cs35l56_irq_request(cs35l56);
+ if (ret < 0)
+ cs35l56_remove(cs35l56);
+
+ return ret;
+}
+
+static void cs35l56_spi_remove(struct spi_device *spi)
+{
+ struct cs35l56_private *cs35l56 = spi_get_drvdata(spi);
+
+ cs35l56_remove(cs35l56);
+}
+
+static const struct spi_device_id cs35l56_id_spi[] = {
+ { "cs35l56", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, cs35l56_id_spi);
+
+static struct spi_driver cs35l56_spi_driver = {
+ .driver = {
+ .name = "cs35l56",
+ .pm = &cs35l56_pm_ops_i2c_spi,
+ },
+ .id_table = cs35l56_id_spi,
+ .probe = cs35l56_spi_probe,
+ .remove = cs35l56_spi_remove,
+};
+
+module_spi_driver(cs35l56_spi_driver);
+
+MODULE_DESCRIPTION("ASoC CS35L56 SPI driver");
+MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
new file mode 100644
index 000000000000..90fc79b5666d
--- /dev/null
+++ b/sound/soc/codecs/cs35l56.c
@@ -0,0 +1,1461 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Driver for Cirrus Logic CS35L56 smart amp
+//
+// Copyright (C) 2023 Cirrus Logic, Inc. and
+// Cirrus Logic International Semiconductor Ltd.
+
+#include <linux/acpi.h>
+#include <linux/completion.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#include "wm_adsp.h"
+#include "cs35l56.h"
+
+static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event);
+
+static int cs35l56_wait_dsp_ready(struct cs35l56_private *cs35l56)
+{
+ int ret;
+
+ if (!cs35l56->fw_patched) {
+ /* block until firmware download completes */
+ ret = wait_for_completion_timeout(&cs35l56->dsp_ready_completion,
+ msecs_to_jiffies(25000));
+ if (!ret) {
+ dev_err(cs35l56->dev, "dsp_ready_completion timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int cs35l56_dspwait_get_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
+ int ret = cs35l56_wait_dsp_ready(cs35l56);
+
+ if (ret)
+ return ret;
+
+ return snd_soc_get_volsw(kcontrol, ucontrol);
+}
+
+static int cs35l56_dspwait_put_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
+ int ret = cs35l56_wait_dsp_ready(cs35l56);
+
+ if (ret)
+ return ret;
+
+ return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
+static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0);
+
+static const struct snd_kcontrol_new cs35l56_controls[] = {
+ SOC_SINGLE_EXT("Speaker Switch",
+ CS35L56_MAIN_RENDER_USER_MUTE, 0, 1, 1,
+ cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw),
+ SOC_SINGLE_S_EXT_TLV("Speaker Volume",
+ CS35L56_MAIN_RENDER_USER_VOLUME,
+ 6, -400, 400, 9, 0,
+ cs35l56_dspwait_get_volsw,
+ cs35l56_dspwait_put_volsw,
+ vol_tlv),
+ SOC_SINGLE_EXT("Posture Number", CS35L56_MAIN_POSTURE_NUMBER,
+ 0, 255, 0,
+ cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw),
+};
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx1_enum,
+ CS35L56_ASP1TX1_INPUT,
+ 0, CS35L56_ASP_TXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new asp1_tx1_mux =
+ SOC_DAPM_ENUM("ASP1TX1 SRC", cs35l56_asp1tx1_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx2_enum,
+ CS35L56_ASP1TX2_INPUT,
+ 0, CS35L56_ASP_TXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new asp1_tx2_mux =
+ SOC_DAPM_ENUM("ASP1TX2 SRC", cs35l56_asp1tx2_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx3_enum,
+ CS35L56_ASP1TX3_INPUT,
+ 0, CS35L56_ASP_TXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new asp1_tx3_mux =
+ SOC_DAPM_ENUM("ASP1TX3 SRC", cs35l56_asp1tx3_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx4_enum,
+ CS35L56_ASP1TX4_INPUT,
+ 0, CS35L56_ASP_TXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new asp1_tx4_mux =
+ SOC_DAPM_ENUM("ASP1TX4 SRC", cs35l56_asp1tx4_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx1_enum,
+ CS35L56_SWIRE_DP3_CH1_INPUT,
+ 0, CS35L56_SWIRETXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new sdw1_tx1_mux =
+ SOC_DAPM_ENUM("SDW1TX1 SRC", cs35l56_sdw1tx1_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx2_enum,
+ CS35L56_SWIRE_DP3_CH2_INPUT,
+ 0, CS35L56_SWIRETXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new sdw1_tx2_mux =
+ SOC_DAPM_ENUM("SDW1TX2 SRC", cs35l56_sdw1tx2_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx3_enum,
+ CS35L56_SWIRE_DP3_CH3_INPUT,
+ 0, CS35L56_SWIRETXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new sdw1_tx3_mux =
+ SOC_DAPM_ENUM("SDW1TX3 SRC", cs35l56_sdw1tx3_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx4_enum,
+ CS35L56_SWIRE_DP3_CH4_INPUT,
+ 0, CS35L56_SWIRETXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new sdw1_tx4_mux =
+ SOC_DAPM_ENUM("SDW1TX4 SRC", cs35l56_sdw1tx4_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx5_enum,
+ CS35L56_SWIRE_DP3_CH5_INPUT,
+ 0, CS35L56_SWIRETXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new sdw1_tx5_mux =
+ SOC_DAPM_ENUM("SDW1TX5 SRC", cs35l56_sdw1tx5_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx6_enum,
+ CS35L56_SWIRE_DP3_CH6_INPUT,
+ 0, CS35L56_SWIRETXn_SRC_MASK,
+ cs35l56_tx_input_texts,
+ cs35l56_tx_input_values);
+
+static const struct snd_kcontrol_new sdw1_tx6_mux =
+ SOC_DAPM_ENUM("SDW1TX6 SRC", cs35l56_sdw1tx6_enum);
+
+static const struct snd_soc_dapm_widget cs35l56_dapm_widgets[] = {
+ SND_SOC_DAPM_REGULATOR_SUPPLY("VDD_B", 0, 0),
+ SND_SOC_DAPM_REGULATOR_SUPPLY("VDD_AMP", 0, 0),
+
+ SND_SOC_DAPM_OUT_DRV("AMP", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_OUTPUT("SPK"),
+
+ SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, cs35l56_dsp_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_AIF_IN("ASP1RX1", NULL, 0, CS35L56_ASP1_ENABLES1,
+ CS35L56_ASP_RX1_EN_SHIFT, 0),
+ SND_SOC_DAPM_AIF_IN("ASP1RX2", NULL, 1, CS35L56_ASP1_ENABLES1,
+ CS35L56_ASP_RX2_EN_SHIFT, 0),
+ SND_SOC_DAPM_AIF_OUT("ASP1TX1", NULL, 0, CS35L56_ASP1_ENABLES1,
+ CS35L56_ASP_TX1_EN_SHIFT, 0),
+ SND_SOC_DAPM_AIF_OUT("ASP1TX2", NULL, 1, CS35L56_ASP1_ENABLES1,
+ CS35L56_ASP_TX2_EN_SHIFT, 0),
+ SND_SOC_DAPM_AIF_OUT("ASP1TX3", NULL, 2, CS35L56_ASP1_ENABLES1,
+ CS35L56_ASP_TX3_EN_SHIFT, 0),
+ SND_SOC_DAPM_AIF_OUT("ASP1TX4", NULL, 3, CS35L56_ASP1_ENABLES1,
+ CS35L56_ASP_TX4_EN_SHIFT, 0),
+
+ SND_SOC_DAPM_MUX("ASP1 TX1 Source", SND_SOC_NOPM, 0, 0, &asp1_tx1_mux),
+ SND_SOC_DAPM_MUX("ASP1 TX2 Source", SND_SOC_NOPM, 0, 0, &asp1_tx2_mux),
+ SND_SOC_DAPM_MUX("ASP1 TX3 Source", SND_SOC_NOPM, 0, 0, &asp1_tx3_mux),
+ SND_SOC_DAPM_MUX("ASP1 TX4 Source", SND_SOC_NOPM, 0, 0, &asp1_tx4_mux),
+
+ SND_SOC_DAPM_MUX("SDW1 TX1 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx1_mux),
+ SND_SOC_DAPM_MUX("SDW1 TX2 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx2_mux),
+ SND_SOC_DAPM_MUX("SDW1 TX3 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx3_mux),
+ SND_SOC_DAPM_MUX("SDW1 TX4 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx4_mux),
+ SND_SOC_DAPM_MUX("SDW1 TX5 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx5_mux),
+ SND_SOC_DAPM_MUX("SDW1 TX6 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx6_mux),
+
+ SND_SOC_DAPM_SIGGEN("VMON ADC"),
+ SND_SOC_DAPM_SIGGEN("IMON ADC"),
+ SND_SOC_DAPM_SIGGEN("ERRVOL ADC"),
+ SND_SOC_DAPM_SIGGEN("CLASSH ADC"),
+ SND_SOC_DAPM_SIGGEN("VDDBMON ADC"),
+ SND_SOC_DAPM_SIGGEN("VBSTMON ADC"),
+ SND_SOC_DAPM_SIGGEN("TEMPMON ADC"),
+};
+
+#define CS35L56_SRC_ROUTE(name) \
+ { name" Source", "ASP1RX1", "ASP1RX1" }, \
+ { name" Source", "ASP1RX2", "ASP1RX2" }, \
+ { name" Source", "VMON", "VMON ADC" }, \
+ { name" Source", "IMON", "IMON ADC" }, \
+ { name" Source", "ERRVOL", "ERRVOL ADC" }, \
+ { name" Source", "CLASSH", "CLASSH ADC" }, \
+ { name" Source", "VDDBMON", "VDDBMON ADC" }, \
+ { name" Source", "VBSTMON", "VBSTMON ADC" }, \
+ { name" Source", "DSP1TX1", "DSP1" }, \
+ { name" Source", "DSP1TX2", "DSP1" }, \
+ { name" Source", "DSP1TX3", "DSP1" }, \
+ { name" Source", "DSP1TX4", "DSP1" }, \
+ { name" Source", "DSP1TX5", "DSP1" }, \
+ { name" Source", "DSP1TX6", "DSP1" }, \
+ { name" Source", "DSP1TX7", "DSP1" }, \
+ { name" Source", "DSP1TX8", "DSP1" }, \
+ { name" Source", "TEMPMON", "TEMPMON ADC" }, \
+ { name" Source", "INTERPOLATOR", "AMP" }, \
+ { name" Source", "SDW1RX1", "SDW1 Playback" }, \
+ { name" Source", "SDW1RX2", "SDW1 Playback" },
+
+static const struct snd_soc_dapm_route cs35l56_audio_map[] = {
+ { "AMP", NULL, "VDD_B" },
+ { "AMP", NULL, "VDD_AMP" },
+
+ { "ASP1RX1", NULL, "ASP1 Playback" },
+ { "ASP1RX2", NULL, "ASP1 Playback" },
+ { "DSP1", NULL, "ASP1RX1" },
+ { "DSP1", NULL, "ASP1RX2" },
+ { "DSP1", NULL, "SDW1 Playback" },
+ { "AMP", NULL, "DSP1" },
+ { "SPK", NULL, "AMP" },
+
+ CS35L56_SRC_ROUTE("ASP1 TX1")
+ CS35L56_SRC_ROUTE("ASP1 TX2")
+ CS35L56_SRC_ROUTE("ASP1 TX3")
+ CS35L56_SRC_ROUTE("ASP1 TX4")
+
+ { "ASP1TX1", NULL, "ASP1 TX1 Source" },
+ { "ASP1TX2", NULL, "ASP1 TX2 Source" },
+ { "ASP1TX3", NULL, "ASP1 TX3 Source" },
+ { "ASP1TX4", NULL, "ASP1 TX4 Source" },
+ { "ASP1 Capture", NULL, "ASP1TX1" },
+ { "ASP1 Capture", NULL, "ASP1TX2" },
+ { "ASP1 Capture", NULL, "ASP1TX3" },
+ { "ASP1 Capture", NULL, "ASP1TX4" },
+
+ CS35L56_SRC_ROUTE("SDW1 TX1")
+ CS35L56_SRC_ROUTE("SDW1 TX2")
+ CS35L56_SRC_ROUTE("SDW1 TX3")
+ CS35L56_SRC_ROUTE("SDW1 TX4")
+ CS35L56_SRC_ROUTE("SDW1 TX5")
+ CS35L56_SRC_ROUTE("SDW1 TX6")
+ { "SDW1 Capture", NULL, "SDW1 TX1 Source" },
+ { "SDW1 Capture", NULL, "SDW1 TX2 Source" },
+ { "SDW1 Capture", NULL, "SDW1 TX3 Source" },
+ { "SDW1 Capture", NULL, "SDW1 TX4 Source" },
+ { "SDW1 Capture", NULL, "SDW1 TX5 Source" },
+ { "SDW1 Capture", NULL, "SDW1 TX6 Source" },
+};
+
+static int cs35l56_mbox_send(struct cs35l56_private *cs35l56, unsigned int command)
+{
+ unsigned int val;
+ int ret;
+
+ regmap_write(cs35l56->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, command);
+ ret = regmap_read_poll_timeout(cs35l56->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
+ val, (val == 0),
+ CS35L56_MBOX_POLL_US, CS35L56_MBOX_TIMEOUT_US);
+ if (ret) {
+ dev_warn(cs35l56->dev, "MBOX command %#x failed: %d\n", command, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cs35l56_dsp_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 cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
+
+ dev_dbg(cs35l56->dev, "%s: %d\n", __func__, event);
+
+ return wm_adsp_event(w, kcontrol, event);
+}
+
+irqreturn_t cs35l56_irq(int irq, void *data)
+{
+ struct cs35l56_private *cs35l56 = data;
+ unsigned int status1 = 0, status8 = 0, status20 = 0;
+ unsigned int mask1, mask8, mask20;
+ unsigned int rv, val;
+ irqreturn_t ret = IRQ_NONE;
+
+ if (!cs35l56->init_done)
+ return IRQ_NONE;
+
+ mutex_lock(&cs35l56->irq_lock);
+
+ rv = pm_runtime_resume_and_get(cs35l56->dev);
+ if (rv < 0) {
+ dev_err(cs35l56->dev, "irq: failed to get pm_runtime: %d\n", rv);
+ goto err_unlock;
+ }
+
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_STATUS, &val);
+ if ((val & CS35L56_IRQ1_STS_MASK) == 0) {
+ dev_dbg(cs35l56->dev, "Spurious IRQ: no pending interrupt\n");
+ goto err;
+ }
+
+ /* Ack interrupts */
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_EINT_1, &status1);
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_MASK_1, &mask1);
+ status1 &= ~mask1;
+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_EINT_1, status1);
+
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_EINT_8, &status8);
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_MASK_8, &mask8);
+ status8 &= ~mask8;
+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_EINT_8, status8);
+
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_EINT_20, &status20);
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_MASK_20, &mask20);
+ status20 &= ~mask20;
+ /* We don't want EINT20 but they default to unmasked: force mask */
+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
+
+ dev_dbg(cs35l56->dev, "%s: %#x %#x\n", __func__, status1, status8);
+
+ /* Check to see if unmasked bits are active */
+ if (!status1 && !status8 && !status20)
+ goto err;
+
+ if (status1 & CS35L56_AMP_SHORT_ERR_EINT1_MASK)
+ dev_crit(cs35l56->dev, "Amp short error\n");
+
+ if (status8 & CS35L56_TEMP_ERR_EINT1_MASK)
+ dev_crit(cs35l56->dev, "Overtemp error\n");
+
+ ret = IRQ_HANDLED;
+
+err:
+ pm_runtime_put(cs35l56->dev);
+err_unlock:
+ mutex_unlock(&cs35l56->irq_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_irq, SND_SOC_CS35L56_CORE);
+
+int cs35l56_irq_request(struct cs35l56_private *cs35l56)
+{
+ int ret;
+
+ if (!cs35l56->irq)
+ return 0;
+
+ ret = devm_request_threaded_irq(cs35l56->dev, cs35l56->irq, NULL,
+ cs35l56_irq,
+ IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
+ "cs35l56", cs35l56);
+ if (ret < 0)
+ dev_err(cs35l56->dev, "Failed to get IRQ: %d\n", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, SND_SOC_CS35L56_CORE);
+
+static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component);
+ unsigned int val;
+
+ dev_dbg(cs35l56->dev, "%s: %#x\n", __func__, fmt);
+
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+ case SND_SOC_DAIFMT_CBC_CFC:
+ break;
+ default:
+ dev_err(cs35l56->dev, "Unsupported clock source mode\n");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ val = CS35L56_ASP_FMT_DSP_A << CS35L56_ASP_FMT_SHIFT;
+ cs35l56->tdm_mode = true;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ val = CS35L56_ASP_FMT_I2S << CS35L56_ASP_FMT_SHIFT;
+ cs35l56->tdm_mode = false;
+ break;
+ default:
+ dev_err(cs35l56->dev, "Unsupported DAI format\n");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_IF:
+ val |= CS35L56_ASP_FSYNC_INV_MASK;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ val |= CS35L56_ASP_BCLK_INV_MASK;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ val |= CS35L56_ASP_BCLK_INV_MASK | CS35L56_ASP_FSYNC_INV_MASK;
+ break;
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ default:
+ dev_err(cs35l56->dev, "Invalid clock invert\n");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(cs35l56->regmap,
+ CS35L56_ASP1_CONTROL2,
+ CS35L56_ASP_FMT_MASK |
+ CS35L56_ASP_BCLK_INV_MASK | CS35L56_ASP_FSYNC_INV_MASK,
+ val);
+
+ /* Hi-Z DOUT in unused slots and when all TX are disabled */
+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL3,
+ CS35L56_ASP1_DOUT_HIZ_CTRL_MASK,
+ CS35L56_ASP_UNUSED_HIZ_OFF_HIZ);
+
+ return 0;
+}
+
+static void cs35l56_set_asp_slot_positions(struct cs35l56_private *cs35l56,
+ unsigned int reg, unsigned long mask)
+{
+ unsigned int reg_val, channel_shift;
+ int bit_num;
+
+ /* Init all slots to 63 */
+ switch (reg) {
+ case CS35L56_ASP1_FRAME_CONTROL1:
+ reg_val = 0x3f3f3f3f;
+ break;
+ case CS35L56_ASP1_FRAME_CONTROL5:
+ reg_val = 0x3f3f3f;
+ break;
+ }
+
+ /* Enable consecutive TX1..TXn for each of the slots set in mask */
+ channel_shift = 0;
+ for_each_set_bit(bit_num, &mask, 32) {
+ reg_val &= ~(0x3f << channel_shift);
+ reg_val |= bit_num << channel_shift;
+ channel_shift += 8;
+ }
+
+ regmap_write(cs35l56->regmap, reg, reg_val);
+}
+
+static int cs35l56_asp_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+
+ if ((slots == 0) || (slot_width == 0)) {
+ dev_dbg(cs35l56->dev, "tdm config cleared\n");
+ cs35l56->asp_slot_width = 0;
+ cs35l56->asp_slot_count = 0;
+ return 0;
+ }
+
+ if (slot_width > (CS35L56_ASP_RX_WIDTH_MASK >> CS35L56_ASP_RX_WIDTH_SHIFT)) {
+ dev_err(cs35l56->dev, "tdm invalid slot width %d\n", slot_width);
+ return -EINVAL;
+ }
+
+ /* More than 32 slots would give an unsupportable BCLK frequency */
+ if (slots > 32) {
+ dev_err(cs35l56->dev, "tdm invalid slot count %d\n", slots);
+ return -EINVAL;
+ }
+
+ cs35l56->asp_slot_width = (u8)slot_width;
+ cs35l56->asp_slot_count = (u8)slots;
+
+ // Note: rx/tx is from point of view of the CPU end
+ if (tx_mask == 0)
+ tx_mask = 0x3; // ASPRX1/RX2 in slots 0 and 1
+
+ if (rx_mask == 0)
+ rx_mask = 0xf; // ASPTX1..TX4 in slots 0..3
+
+ cs35l56_set_asp_slot_positions(cs35l56, CS35L56_ASP1_FRAME_CONTROL1, rx_mask);
+ cs35l56_set_asp_slot_positions(cs35l56, CS35L56_ASP1_FRAME_CONTROL5, tx_mask);
+
+ dev_dbg(cs35l56->dev, "tdm slot width: %u count: %u tx_mask: %#x rx_mask: %#x\n",
+ cs35l56->asp_slot_width, cs35l56->asp_slot_count, tx_mask, rx_mask);
+
+ return 0;
+}
+
+static int cs35l56_asp_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+ unsigned int rate = params_rate(params);
+ u8 asp_width, asp_wl;
+
+ asp_wl = params_width(params);
+ if (cs35l56->asp_slot_width)
+ asp_width = cs35l56->asp_slot_width;
+ else
+ asp_width = asp_wl;
+
+ dev_dbg(cs35l56->dev, "%s: wl=%d, width=%d, rate=%d", __func__, asp_wl, asp_width, rate);
+
+ if (!cs35l56->sysclk_set) {
+ unsigned int slots = cs35l56->asp_slot_count;
+ unsigned int bclk_freq;
+ int freq_id;
+
+ if (slots == 0) {
+ slots = params_channels(params);
+
+ /* I2S always has an even number of slots */
+ if (!cs35l56->tdm_mode)
+ slots = round_up(slots, 2);
+ }
+
+ bclk_freq = asp_width * slots * rate;
+ freq_id = cs35l56_get_bclk_freq_id(bclk_freq);
+ if (freq_id < 0) {
+ dev_err(cs35l56->dev, "%s: Invalid BCLK %u\n", __func__, bclk_freq);
+ return -EINVAL;
+ }
+
+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL1,
+ CS35L56_ASP_BCLK_FREQ_MASK,
+ freq_id << CS35L56_ASP_BCLK_FREQ_SHIFT);
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL2,
+ CS35L56_ASP_RX_WIDTH_MASK, asp_width <<
+ CS35L56_ASP_RX_WIDTH_SHIFT);
+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_DATA_CONTROL5,
+ CS35L56_ASP_RX_WL_MASK, asp_wl);
+ } else {
+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL2,
+ CS35L56_ASP_TX_WIDTH_MASK, asp_width <<
+ CS35L56_ASP_TX_WIDTH_SHIFT);
+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_DATA_CONTROL1,
+ CS35L56_ASP_TX_WL_MASK, asp_wl);
+ }
+
+ return 0;
+}
+
+static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+ int freq_id;
+
+ if (freq == 0) {
+ cs35l56->sysclk_set = false;
+ return 0;
+ }
+
+ freq_id = cs35l56_get_bclk_freq_id(freq);
+ if (freq_id < 0)
+ return freq_id;
+
+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL1,
+ CS35L56_ASP_BCLK_FREQ_MASK,
+ freq_id << CS35L56_ASP_BCLK_FREQ_SHIFT);
+ cs35l56->sysclk_set = true;
+
+ return 0;
+}
+
+static int cs35l56_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+ unsigned int val;
+ int ret;
+
+ dev_dbg(cs35l56->dev, "%s: %d %s\n", __func__, stream, mute ? "mute" : "unmute");
+
+ if (stream != SNDRV_PCM_STREAM_PLAYBACK)
+ return 0;
+
+ if (mute) {
+ ret = cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_AUDIO_PAUSE);
+ } else {
+ ret = cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_AUDIO_PLAY);
+ if (ret == 0) {
+ /* Wait for firmware to enter PS0 power state */
+ ret = regmap_read_poll_timeout(cs35l56->regmap,
+ CS35L56_TRANSDUCER_ACTUAL_PS,
+ val, (val == CS35L56_PS0),
+ CS35L56_PS0_POLL_US,
+ CS35L56_PS0_TIMEOUT_US);
+ if (ret)
+ dev_err(cs35l56->dev, "PS0 wait failed: %d\n", ret);
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops cs35l56_ops = {
+ .set_fmt = cs35l56_asp_dai_set_fmt,
+ .set_tdm_slot = cs35l56_asp_dai_set_tdm_slot,
+ .hw_params = cs35l56_asp_dai_hw_params,
+ .set_sysclk = cs35l56_asp_dai_set_sysclk,
+ .mute_stream = cs35l56_mute_stream,
+};
+
+static void cs35l56_sdw_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ snd_soc_dai_set_dma_data(dai, substream, NULL);
+}
+
+static int cs35l56_sdw_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+
+ /* rx/tx are from point of view of the CPU end so opposite to our rx/tx */
+ cs35l56->rx_mask = tx_mask;
+ cs35l56->tx_mask = rx_mask;
+
+ return 0;
+}
+
+static int cs35l56_sdw_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+ struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
+ struct sdw_stream_config sconfig;
+ struct sdw_port_config pconfig;
+ int ret;
+
+ dev_dbg(cs35l56->dev, "%s: rate %d\n", __func__, params_rate(params));
+
+ if (!cs35l56->init_done)
+ return -ENODEV;
+
+ if (!sdw_stream)
+ return -EINVAL;
+
+ memset(&sconfig, 0, sizeof(sconfig));
+ memset(&pconfig, 0, sizeof(pconfig));
+
+ sconfig.frame_rate = params_rate(params);
+ sconfig.bps = snd_pcm_format_width(params_format(params));
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ sconfig.direction = SDW_DATA_DIR_RX;
+ pconfig.num = CS35L56_SDW1_PLAYBACK_PORT;
+ pconfig.ch_mask = cs35l56->rx_mask;
+ } else {
+ sconfig.direction = SDW_DATA_DIR_TX;
+ pconfig.num = CS35L56_SDW1_CAPTURE_PORT;
+ pconfig.ch_mask = cs35l56->tx_mask;
+ }
+
+ if (pconfig.ch_mask == 0) {
+ sconfig.ch_count = params_channels(params);
+ pconfig.ch_mask = GENMASK(sconfig.ch_count - 1, 0);
+ } else {
+ sconfig.ch_count = hweight32(pconfig.ch_mask);
+ }
+
+ ret = sdw_stream_add_slave(cs35l56->sdw_peripheral, &sconfig, &pconfig,
+ 1, sdw_stream);
+ if (ret) {
+ dev_err(dai->dev, "Failed to add sdw stream: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cs35l56_sdw_dai_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+ struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
+
+ if (!cs35l56->sdw_peripheral)
+ return -EINVAL;
+
+ sdw_stream_remove_slave(cs35l56->sdw_peripheral, sdw_stream);
+
+ return 0;
+}
+
+static int cs35l56_sdw_dai_set_stream(struct snd_soc_dai *dai,
+ void *sdw_stream, int direction)
+{
+ if (!sdw_stream)
+ return 0;
+
+ snd_soc_dai_dma_data_set(dai, direction, sdw_stream);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops cs35l56_sdw_dai_ops = {
+ .set_tdm_slot = cs35l56_sdw_dai_set_tdm_slot,
+ .shutdown = cs35l56_sdw_dai_shutdown,
+ .hw_params = cs35l56_sdw_dai_hw_params,
+ .hw_free = cs35l56_sdw_dai_hw_free,
+ .mute_stream = cs35l56_mute_stream,
+ .set_stream = cs35l56_sdw_dai_set_stream,
+};
+
+static struct snd_soc_dai_driver cs35l56_dai[] = {
+ {
+ .name = "cs35l56-asp1",
+ .id = 0,
+ .playback = {
+ .stream_name = "ASP1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CS35L56_RATES,
+ .formats = CS35L56_RX_FORMATS,
+ },
+ .capture = {
+ .stream_name = "ASP1 Capture",
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = CS35L56_RATES,
+ .formats = CS35L56_TX_FORMATS,
+ },
+ .ops = &cs35l56_ops,
+ .symmetric_rate = 1,
+ .symmetric_sample_bits = 1,
+ },
+ {
+ .name = "cs35l56-sdw1",
+ .id = 1,
+ .playback = {
+ .stream_name = "SDW1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = CS35L56_RATES,
+ .formats = CS35L56_RX_FORMATS,
+ },
+ .capture = {
+ .stream_name = "SDW1 Capture",
+ .channels_min = 1,
+ .channels_max = 6,
+ .rates = CS35L56_RATES,
+ .formats = CS35L56_TX_FORMATS,
+ },
+ .symmetric_rate = 1,
+ .ops = &cs35l56_sdw_dai_ops,
+ }
+};
+
+static int cs35l56_wait_for_firmware_boot(struct cs35l56_private *cs35l56)
+{
+ unsigned int reg;
+ unsigned int val;
+ int ret;
+
+ if (cs35l56->rev < CS35L56_REVID_B0)
+ reg = CS35L56_DSP1_HALO_STATE_A1;
+ else
+ reg = CS35L56_DSP1_HALO_STATE;
+
+ ret = regmap_read_poll_timeout(cs35l56->regmap, reg,
+ val,
+ (val < 0xFFFF) && (val >= CS35L56_HALO_STATE_BOOT_DONE),
+ CS35L56_HALO_STATE_POLL_US,
+ CS35L56_HALO_STATE_TIMEOUT_US);
+
+ if ((ret < 0) && (ret != -ETIMEDOUT)) {
+ dev_err(cs35l56->dev, "Failed to read HALO_STATE: %d\n", ret);
+ return ret;
+ }
+
+ if ((ret == -ETIMEDOUT) || (val != CS35L56_HALO_STATE_BOOT_DONE)) {
+ dev_err(cs35l56->dev, "Firmware boot fail: HALO_STATE=%#x\n", val);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static const struct reg_sequence cs35l56_system_reset_seq[] = {
+ REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
+};
+
+static void cs35l56_system_reset(struct cs35l56_private *cs35l56)
+{
+ cs35l56->soft_resetting = true;
+
+ /*
+ * Must enter cache-only first so there can't be any more register
+ * accesses other than the controlled system reset sequence below.
+ */
+ regcache_cache_only(cs35l56->regmap, true);
+ regmap_multi_reg_write_bypassed(cs35l56->regmap,
+ cs35l56_system_reset_seq,
+ ARRAY_SIZE(cs35l56_system_reset_seq));
+
+ /* On SoundWire the registers won't be accessible until it re-enumerates. */
+ if (cs35l56->sdw_peripheral)
+ return;
+
+ usleep_range(CS35L56_CONTROL_PORT_READY_US, CS35L56_CONTROL_PORT_READY_US + 400);
+ regcache_cache_only(cs35l56->regmap, false);
+}
+
+static void cs35l56_dsp_work(struct work_struct *work)
+{
+ struct cs35l56_private *cs35l56 = container_of(work,
+ struct cs35l56_private,
+ dsp_work);
+ unsigned int reg;
+ unsigned int val;
+ int ret = 0;
+
+ if (!wait_for_completion_timeout(&cs35l56->init_completion,
+ msecs_to_jiffies(5000))) {
+ dev_err(cs35l56->dev, "%s: init_completion timed out\n", __func__);
+ goto complete;
+ }
+
+ if (!cs35l56->init_done || cs35l56->removing)
+ goto complete;
+
+ cs35l56->dsp.part = devm_kasprintf(cs35l56->dev, GFP_KERNEL, "cs35l56%s-%02x",
+ cs35l56->secured ? "s" : "", cs35l56->rev);
+
+ if (!cs35l56->dsp.part)
+ goto complete;
+
+ pm_runtime_get_sync(cs35l56->dev);
+
+ /*
+ * Disable SoundWire interrupts to prevent race with IRQ work.
+ * Setting sdw_irq_no_unmask prevents the handler re-enabling
+ * the SoundWire interrupt.
+ */
+ if (cs35l56->sdw_peripheral) {
+ cs35l56->sdw_irq_no_unmask = true;
+ cancel_work_sync(&cs35l56->sdw_irq_work);
+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
+ sdw_read_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1);
+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
+ }
+
+ ret = cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_SHUTDOWN);
+ if (ret) {
+ dev_dbg(cs35l56->dev, "%s: CS35L56_MBOX_CMD_SHUTDOWN ret %d\n", __func__, ret);
+ goto err;
+ }
+
+ if (cs35l56->rev < CS35L56_REVID_B0)
+ reg = CS35L56_DSP1_PM_CUR_STATE_A1;
+ else
+ reg = CS35L56_DSP1_PM_CUR_STATE;
+
+ ret = regmap_read_poll_timeout(cs35l56->regmap, reg,
+ val, (val == CS35L56_HALO_STATE_SHUTDOWN),
+ CS35L56_HALO_STATE_POLL_US,
+ CS35L56_HALO_STATE_TIMEOUT_US);
+ if (ret < 0)
+ dev_err(cs35l56->dev, "Failed to poll PM_CUR_STATE to 1 is %d (ret %d)\n",
+ val, ret);
+
+ /* Use wm_adsp to load and apply the firmware patch and coefficient files */
+ ret = wm_adsp_power_up(&cs35l56->dsp);
+ if (ret) {
+ dev_dbg(cs35l56->dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret);
+ goto err;
+ }
+
+ if (cs35l56->removing)
+ goto err;
+
+ mutex_lock(&cs35l56->irq_lock);
+
+ init_completion(&cs35l56->init_completion);
+
+ cs35l56_system_reset(cs35l56);
+
+ if (cs35l56->sdw_peripheral) {
+ /*
+ * The system-reset causes the CS35L56 to detach from the bus.
+ * Wait for the manager to re-enumerate the CS35L56 and
+ * cs35l56_init() to run again.
+ */
+ if (!wait_for_completion_timeout(&cs35l56->init_completion,
+ msecs_to_jiffies(5000))) {
+ dev_err(cs35l56->dev, "%s: init_completion timed out (SDW)\n", __func__);
+ goto err_unlock;
+ }
+ } else if (cs35l56_init(cs35l56)) {
+ goto err_unlock;
+ }
+
+ cs35l56->fw_patched = true;
+
+err_unlock:
+ mutex_unlock(&cs35l56->irq_lock);
+err:
+ pm_runtime_mark_last_busy(cs35l56->dev);
+ pm_runtime_put_autosuspend(cs35l56->dev);
+
+ /* Re-enable SoundWire interrupts */
+ if (cs35l56->sdw_peripheral) {
+ cs35l56->sdw_irq_no_unmask = false;
+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
+ CS35L56_SDW_INT_MASK_CODEC_IRQ);
+ }
+
+complete:
+ complete_all(&cs35l56->dsp_ready_completion);
+}
+
+static int cs35l56_component_probe(struct snd_soc_component *component)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
+ struct dentry *debugfs_root = component->debugfs_root;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cs35l56_tx_input_texts) != ARRAY_SIZE(cs35l56_tx_input_values));
+
+ cs35l56->removing = false;
+ cs35l56->component = component;
+ wm_adsp2_component_probe(&cs35l56->dsp, component);
+
+ debugfs_create_bool("init_done", 0444, debugfs_root, &cs35l56->init_done);
+ debugfs_create_bool("can_hibernate", 0444, debugfs_root, &cs35l56->can_hibernate);
+ debugfs_create_bool("fw_patched", 0444, debugfs_root, &cs35l56->fw_patched);
+
+ queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work);
+
+ return 0;
+}
+
+static void cs35l56_component_remove(struct snd_soc_component *component)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
+
+ cs35l56->removing = true;
+ complete(&cs35l56->init_completion);
+ cancel_work_sync(&cs35l56->dsp_work);
+}
+
+static int cs35l56_set_bias_level(struct snd_soc_component *component,
+ enum snd_soc_bias_level level)
+{
+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
+ int ret = 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_STANDBY:
+ /*
+ * Wait for patching to complete when transitioning from
+ * BIAS_OFF to BIAS_STANDBY
+ */
+ if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+ ret = cs35l56_wait_dsp_ready(cs35l56);
+
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static const struct snd_soc_component_driver soc_component_dev_cs35l56 = {
+ .probe = cs35l56_component_probe,
+ .remove = cs35l56_component_remove,
+
+ .dapm_widgets = cs35l56_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cs35l56_dapm_widgets),
+ .dapm_routes = cs35l56_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(cs35l56_audio_map),
+ .controls = cs35l56_controls,
+ .num_controls = ARRAY_SIZE(cs35l56_controls),
+
+ .set_bias_level = cs35l56_set_bias_level,
+};
+
+static const struct reg_sequence cs35l56_hibernate_seq[] = {
+ /* This must be the last register access */
+ REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_HIBERNATE_NOW),
+};
+
+static const struct reg_sequence cs35l56_hibernate_wake_seq[] = {
+ REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_WAKEUP),
+};
+
+int cs35l56_runtime_suspend(struct device *dev)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ if (!cs35l56->init_done)
+ return 0;
+
+ /* Firmware must have entered a power-save state */
+ ret = regmap_read_poll_timeout(cs35l56->regmap,
+ CS35L56_TRANSDUCER_ACTUAL_PS,
+ val, (val >= CS35L56_PS3),
+ CS35L56_PS3_POLL_US,
+ CS35L56_PS3_TIMEOUT_US);
+ if (ret)
+ dev_warn(cs35l56->dev, "PS3 wait failed: %d\n", ret);
+
+ /* Clear BOOT_DONE so it can be used to detect a reboot */
+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_EINT_4, CS35L56_OTP_BOOT_DONE_MASK);
+
+ if (!cs35l56->can_hibernate) {
+ regcache_cache_only(cs35l56->regmap, true);
+ dev_dbg(dev, "Suspended: no hibernate");
+
+ return 0;
+ }
+
+ /*
+ * Enable auto-hibernate. If it is woken by some other wake source
+ * it will automatically return to hibernate.
+ */
+ ret = cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE);
+ if (ret)
+ dev_warn(cs35l56->dev, "ALLOW_HIBERNATE failed: %d\n", ret);
+
+ /*
+ * Must enter cache-only first so there can't be any more register
+ * accesses other than the controlled hibernate sequence below.
+ */
+ regcache_cache_only(cs35l56->regmap, true);
+
+ regmap_multi_reg_write_bypassed(cs35l56->regmap,
+ cs35l56_hibernate_seq,
+ ARRAY_SIZE(cs35l56_hibernate_seq));
+
+ dev_dbg(dev, "Suspended: hibernate");
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend, SND_SOC_CS35L56_CORE);
+
+static int __maybe_unused cs35l56_runtime_resume_i2c_spi(struct device *dev)
+{
+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
+
+ if (!cs35l56->init_done)
+ return 0;
+
+ return cs35l56_runtime_resume_common(cs35l56);
+}
+
+int cs35l56_runtime_resume_common(struct cs35l56_private *cs35l56)
+{
+ unsigned int val;
+ int ret;
+
+ if (!cs35l56->can_hibernate) {
+ regcache_cache_only(cs35l56->regmap, false);
+ goto out_sync;
+ }
+
+ if (!cs35l56->sdw_peripheral) {
+ /*
+ * Dummy transaction to trigger I2C/SPI auto-wake. This will NAK on I2C.
+ * Must be done before releasing cache-only.
+ */
+ regmap_multi_reg_write_bypassed(cs35l56->regmap,
+ cs35l56_hibernate_wake_seq,
+ ARRAY_SIZE(cs35l56_hibernate_wake_seq));
+
+ usleep_range(CS35L56_CONTROL_PORT_READY_US,
+ CS35L56_CONTROL_PORT_READY_US + 400);
+ }
+
+ regcache_cache_only(cs35l56->regmap, false);
+
+ ret = cs35l56_wait_for_firmware_boot(cs35l56);
+ if (ret) {
+ dev_err(cs35l56->dev, "Hibernate wake failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
+ if (ret)
+ goto err;
+
+out_sync:
+ /* BOOT_DONE will be 1 if the amp reset */
+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_EINT_4, &val);
+ if (val & CS35L56_OTP_BOOT_DONE_MASK) {
+ dev_dbg(cs35l56->dev, "Registers reset in suspend\n");
+ regcache_mark_dirty(cs35l56->regmap);
+ }
+
+ regcache_sync(cs35l56->regmap);
+
+ dev_dbg(cs35l56->dev, "Resumed");
+
+ return 0;
+
+err:
+ regmap_write(cs35l56->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
+ CS35L56_MBOX_CMD_HIBERNATE_NOW);
+
+ regcache_cache_only(cs35l56->regmap, true);
+
+ return ret;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common, SND_SOC_CS35L56_CORE);
+
+static int cs35l56_dsp_init(struct cs35l56_private *cs35l56)
+{
+ struct wm_adsp *dsp;
+ int ret;
+
+ cs35l56->dsp_wq = create_singlethread_workqueue("cs35l56-dsp");
+ if (!cs35l56->dsp_wq)
+ return -ENOMEM;
+
+ INIT_WORK(&cs35l56->dsp_work, cs35l56_dsp_work);
+ init_completion(&cs35l56->dsp_ready_completion);
+
+ dsp = &cs35l56->dsp;
+ dsp->part = "cs35l56";
+ dsp->cs_dsp.num = 1;
+ dsp->cs_dsp.type = WMFW_HALO;
+ dsp->cs_dsp.rev = 0;
+ dsp->fw = 12;
+ dsp->cs_dsp.dev = cs35l56->dev;
+ dsp->cs_dsp.regmap = cs35l56->regmap;
+ dsp->cs_dsp.base = CS35L56_DSP1_CORE_BASE;
+ dsp->cs_dsp.base_sysinfo = CS35L56_DSP1_SYS_INFO_ID;
+ dsp->cs_dsp.mem = cs35l56_dsp1_regions;
+ dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l56_dsp1_regions);
+ dsp->cs_dsp.no_core_startstop = true;
+ dsp->wmfw_optional = true;
+
+ dev_dbg(cs35l56->dev, "DSP system name: '%s'\n", dsp->system_name);
+
+ ret = wm_halo_init(dsp);
+ if (ret != 0) {
+ dev_err(cs35l56->dev, "wm_halo_init failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cs35l56_acpi_get_name(struct cs35l56_private *cs35l56)
+{
+ acpi_handle handle = ACPI_HANDLE(cs35l56->dev);
+ const char *sub;
+
+ /* If there is no ACPI_HANDLE, there is no ACPI for this system, return 0 */
+ if (!handle)
+ return 0;
+
+ sub = acpi_get_subsystem_id(handle);
+ if (IS_ERR(sub)) {
+ /* If bad ACPI, return 0 and fallback to legacy firmware path, otherwise fail */
+ if (PTR_ERR(sub) == -ENODATA)
+ return 0;
+ else
+ return PTR_ERR(sub);
+ }
+
+ cs35l56->dsp.system_name = sub;
+ dev_dbg(cs35l56->dev, "Subsystem ID: %s\n", cs35l56->dsp.system_name);
+
+ return 0;
+}
+
+int cs35l56_common_probe(struct cs35l56_private *cs35l56)
+{
+ int ret;
+
+ init_completion(&cs35l56->init_completion);
+ mutex_init(&cs35l56->irq_lock);
+
+ dev_set_drvdata(cs35l56->dev, cs35l56);
+
+ cs35l56_fill_supply_names(cs35l56->supplies);
+ ret = devm_regulator_bulk_get(cs35l56->dev, ARRAY_SIZE(cs35l56->supplies),
+ cs35l56->supplies);
+ if (ret != 0)
+ return dev_err_probe(cs35l56->dev, ret, "Failed to request supplies\n");
+
+ /* Reset could be controlled by the BIOS or shared by multiple amps */
+ cs35l56->reset_gpio = devm_gpiod_get_optional(cs35l56->dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(cs35l56->reset_gpio)) {
+ ret = PTR_ERR(cs35l56->reset_gpio);
+ /*
+ * If RESET is shared the first amp to probe will grab the reset
+ * line and reset all the amps
+ */
+ if (ret != -EBUSY)
+ return dev_err_probe(cs35l56->dev, ret, "Failed to get reset GPIO\n");
+
+ dev_info(cs35l56->dev, "Reset GPIO busy, assume shared reset\n");
+ cs35l56->reset_gpio = NULL;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies);
+ if (ret != 0)
+ return dev_err_probe(cs35l56->dev, ret, "Failed to enable supplies\n");
+
+ if (cs35l56->reset_gpio) {
+ /* satisfy minimum reset pulse width spec */
+ usleep_range(CS35L56_RESET_PULSE_MIN_US,
+ CS35L56_RESET_PULSE_MIN_US + 400);
+ gpiod_set_value_cansleep(cs35l56->reset_gpio, 1);
+ }
+
+ ret = cs35l56_acpi_get_name(cs35l56);
+ if (ret != 0)
+ goto err;
+
+ ret = cs35l56_dsp_init(cs35l56);
+ if (ret < 0) {
+ dev_err_probe(cs35l56->dev, ret, "DSP init failed\n");
+ goto err;
+ }
+
+ ret = devm_snd_soc_register_component(cs35l56->dev,
+ &soc_component_dev_cs35l56,
+ cs35l56_dai, ARRAY_SIZE(cs35l56_dai));
+ if (ret < 0) {
+ dev_err_probe(cs35l56->dev, ret, "Register codec failed\n");
+ goto err;
+ }
+
+ return 0;
+
+err:
+ gpiod_set_value_cansleep(cs35l56->reset_gpio, 0);
+ regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies);
+
+ return ret;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_common_probe, SND_SOC_CS35L56_CORE);
+
+int cs35l56_init(struct cs35l56_private *cs35l56)
+{
+ int ret;
+ unsigned int devid, revid, otpid, secured;
+
+ /*
+ * Check whether the actions associated with soft reset or one time
+ * init need to be performed.
+ */
+ if (cs35l56->soft_resetting)
+ goto post_soft_reset;
+
+ if (cs35l56->init_done)
+ return 0;
+
+ pm_runtime_set_autosuspend_delay(cs35l56->dev, 100);
+ pm_runtime_use_autosuspend(cs35l56->dev);
+ pm_runtime_set_active(cs35l56->dev);
+ pm_runtime_enable(cs35l56->dev);
+
+ /*
+ * If the system is not using a reset_gpio then issue a
+ * dummy read to force a wakeup.
+ */
+ if (!cs35l56->reset_gpio)
+ regmap_read(cs35l56->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, &devid);
+
+ /* Wait for control port to be ready (datasheet tIRS). */
+ usleep_range(CS35L56_CONTROL_PORT_READY_US,
+ CS35L56_CONTROL_PORT_READY_US + 400);
+
+ /*
+ * The HALO_STATE register is in different locations on Ax and B0
+ * devices so the REVID needs to be determined before waiting for the
+ * firmware to boot.
+ */
+ ret = regmap_read(cs35l56->regmap, CS35L56_REVID, &revid);
+ if (ret < 0) {
+ dev_err(cs35l56->dev, "Get Revision ID failed\n");
+ return ret;
+ }
+ cs35l56->rev = revid & (CS35L56_AREVID_MASK | CS35L56_MTLREVID_MASK);
+
+ ret = cs35l56_wait_for_firmware_boot(cs35l56);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(cs35l56->regmap, CS35L56_DEVID, &devid);
+ if (ret < 0) {
+ dev_err(cs35l56->dev, "Get Device ID failed\n");
+ return ret;
+ }
+ devid &= CS35L56_DEVID_MASK;
+
+ switch (devid) {
+ case 0x35A56:
+ break;
+ default:
+ dev_err(cs35l56->dev, "Unknown device %x\n", devid);
+ return ret;
+ }
+
+ ret = regmap_read(cs35l56->regmap, CS35L56_DSP_RESTRICT_STS1, &secured);
+ if (ret) {
+ dev_err(cs35l56->dev, "Get Secure status failed\n");
+ return ret;
+ }
+
+ /* When any bus is restricted treat the device as secured */
+ if (secured & CS35L56_RESTRICTED_MASK)
+ cs35l56->secured = true;
+
+ ret = regmap_read(cs35l56->regmap, CS35L56_OTPID, &otpid);
+ if (ret < 0) {
+ dev_err(cs35l56->dev, "Get OTP ID failed\n");
+ return ret;
+ }
+
+ dev_info(cs35l56->dev, "Cirrus Logic CS35L56%s Rev %02X OTP%d\n",
+ cs35l56->secured ? "s" : "", cs35l56->rev, otpid);
+
+ cs35l56_patch(cs35l56->dev, cs35l56->regmap, cs35l56->rev);
+
+ /* Wake source interrupts default to unmasked, so mask them */
+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
+ regmap_update_bits(cs35l56->regmap, CS35L56_IRQ1_MASK_1,
+ CS35L56_AMP_SHORT_ERR_EINT1_MASK,
+ 0);
+ regmap_update_bits(cs35l56->regmap, CS35L56_IRQ1_MASK_8,
+ CS35L56_TEMP_ERR_EINT1_MASK,
+ 0);
+
+ if (!cs35l56->reset_gpio) {
+ dev_dbg(cs35l56->dev, "No reset gpio: using soft reset\n");
+ cs35l56_system_reset(cs35l56);
+ if (cs35l56->sdw_peripheral) {
+ /* Keep alive while we wait for re-enumeration */
+ pm_runtime_get_noresume(cs35l56->dev);
+ return 0;
+ }
+ }
+
+post_soft_reset:
+ if (cs35l56->soft_resetting) {
+ cs35l56->soft_resetting = false;
+
+ /* Done re-enumerating after one-time init so release the keep-alive */
+ if (cs35l56->sdw_peripheral && !cs35l56->init_done)
+ pm_runtime_put_noidle(cs35l56->dev);
+
+ regcache_mark_dirty(cs35l56->regmap);
+ ret = cs35l56_wait_for_firmware_boot(cs35l56);
+ if (ret)
+ return ret;
+
+ dev_dbg(cs35l56->dev, "Firmware rebooted after soft reset\n");
+ }
+
+ /* Disable auto-hibernate so that runtime_pm has control */
+ ret = cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
+ if (ret)
+ return ret;
+
+ /* Populate soft registers in the regmap cache */
+ cs35l56_reread_firmware_registers(cs35l56->dev, cs35l56->regmap);
+
+ /* Registers could be dirty after soft reset or SoundWire enumeration */
+ regcache_sync(cs35l56->regmap);
+
+ cs35l56->init_done = true;
+ complete(&cs35l56->init_completion);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_init, SND_SOC_CS35L56_CORE);
+
+int cs35l56_remove(struct cs35l56_private *cs35l56)
+{
+ cs35l56->init_done = false;
+
+ /*
+ * WAKE IRQs unmask if CS35L56 hibernates so free the handler to
+ * prevent it racing with remove().
+ */
+ if (cs35l56->irq)
+ devm_free_irq(cs35l56->dev, cs35l56->irq, cs35l56);
+
+ flush_workqueue(cs35l56->dsp_wq);
+ destroy_workqueue(cs35l56->dsp_wq);
+
+ pm_runtime_suspend(cs35l56->dev);
+ pm_runtime_disable(cs35l56->dev);
+
+ regcache_cache_only(cs35l56->regmap, true);
+
+ kfree(cs35l56->dsp.system_name);
+
+ gpiod_set_value_cansleep(cs35l56->reset_gpio, 0);
+ regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_remove, SND_SOC_CS35L56_CORE);
+
+const struct dev_pm_ops cs35l56_pm_ops_i2c_spi = {
+ SET_RUNTIME_PM_OPS(cs35l56_runtime_suspend, cs35l56_runtime_resume_i2c_spi, NULL)
+};
+EXPORT_SYMBOL_NS_GPL(cs35l56_pm_ops_i2c_spi, SND_SOC_CS35L56_CORE);
+
+MODULE_DESCRIPTION("ASoC CS35L56 driver");
+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
new file mode 100644
index 000000000000..efc4b99180f9
--- /dev/null
+++ b/sound/soc/codecs/cs35l56.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Driver for Cirrus Logic CS35L56 smart amp
+ *
+ * Copyright (C) 2023 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#ifndef CS35L56_H
+#define CS35L56_H
+
+#include <linux/completion.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/workqueue.h>
+#include <sound/cs35l56.h>
+#include "wm_adsp.h"
+
+#define CS35L56_SDW_GEN_INT_STAT_1 0xc0
+#define CS35L56_SDW_GEN_INT_MASK_1 0xc1
+#define CS35L56_SDW_INT_MASK_CODEC_IRQ BIT(0)
+
+#define CS35L56_SDW_INVALID_BUS_SCALE 0xf
+
+#define CS35L56_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
+#define CS35L56_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE \
+ | SNDRV_PCM_FMTBIT_S32_LE)
+
+#define CS35L56_RATES (SNDRV_PCM_RATE_48000)
+
+struct sdw_slave;
+
+struct cs35l56_private {
+ struct wm_adsp dsp; /* must be first member */
+ struct work_struct dsp_work;
+ struct workqueue_struct *dsp_wq;
+ struct completion dsp_ready_completion;
+ struct mutex irq_lock;
+ struct snd_soc_component *component;
+ struct device *dev;
+ struct regmap *regmap;
+ struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES];
+ int irq;
+ struct sdw_slave *sdw_peripheral;
+ u8 rev;
+ struct work_struct sdw_irq_work;
+ bool secured;
+ bool sdw_irq_no_unmask;
+ bool soft_resetting;
+ bool init_done;
+ bool sdw_attached;
+ bool removing;
+ bool fw_patched;
+ bool can_hibernate;
+ struct completion init_completion;
+ struct gpio_desc *reset_gpio;
+
+ u32 rx_mask;
+ u32 tx_mask;
+ u8 asp_slot_width;
+ u8 asp_slot_count;
+ bool tdm_mode;
+ bool sysclk_set;
+ u8 old_sdw_clock_scale;
+};
+
+extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi;
+
+int cs35l56_runtime_suspend(struct device *dev);
+int cs35l56_runtime_resume_common(struct cs35l56_private *cs35l56);
+irqreturn_t cs35l56_irq(int irq, void *data);
+int cs35l56_irq_request(struct cs35l56_private *cs35l56);
+int cs35l56_common_probe(struct cs35l56_private *cs35l56);
+int cs35l56_init(struct cs35l56_private *cs35l56);
+int cs35l56_remove(struct cs35l56_private *cs35l56);
+
+#endif /* ifndef CS35L56_H */
diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c
index 06c4214382e3..a6538dab6639 100644
--- a/sound/soc/codecs/cs47l15.c
+++ b/sound/soc/codecs/cs47l15.c
@@ -1468,7 +1468,7 @@ error_core:
return ret;
}
-static int cs47l15_remove(struct platform_device *pdev)
+static void cs47l15_remove(struct platform_device *pdev)
{
struct cs47l15 *cs47l15 = platform_get_drvdata(pdev);
@@ -1482,8 +1482,6 @@ static int cs47l15_remove(struct platform_device *pdev)
madera_free_irq(cs47l15->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l15);
madera_free_overheat(&cs47l15->core);
madera_core_free(&cs47l15->core);
-
- return 0;
}
static struct platform_driver cs47l15_codec_driver = {
@@ -1491,7 +1489,7 @@ static struct platform_driver cs47l15_codec_driver = {
.name = "cs47l15-codec",
},
.probe = &cs47l15_probe,
- .remove = &cs47l15_remove,
+ .remove_new = cs47l15_remove,
};
module_platform_driver(cs47l15_codec_driver);
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index f9a2b865d717..a07b621d463e 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -1319,7 +1319,7 @@ err_dsp_irq:
return ret;
}
-static int cs47l24_remove(struct platform_device *pdev)
+static void cs47l24_remove(struct platform_device *pdev)
{
struct cs47l24_priv *cs47l24 = platform_get_drvdata(pdev);
struct arizona *arizona = cs47l24->core.arizona;
@@ -1333,8 +1333,6 @@ static int cs47l24_remove(struct platform_device *pdev)
arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, cs47l24);
-
- return 0;
}
static struct platform_driver cs47l24_codec_driver = {
@@ -1342,7 +1340,7 @@ static struct platform_driver cs47l24_codec_driver = {
.name = "cs47l24-codec",
},
.probe = cs47l24_probe,
- .remove = cs47l24_remove,
+ .remove_new = cs47l24_remove,
};
module_platform_driver(cs47l24_codec_driver);
diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c
index c1032d6c9143..c05c80c16c84 100644
--- a/sound/soc/codecs/cs47l35.c
+++ b/sound/soc/codecs/cs47l35.c
@@ -1744,7 +1744,7 @@ error_core:
return ret;
}
-static int cs47l35_remove(struct platform_device *pdev)
+static void cs47l35_remove(struct platform_device *pdev)
{
struct cs47l35 *cs47l35 = platform_get_drvdata(pdev);
int i;
@@ -1758,8 +1758,6 @@ static int cs47l35_remove(struct platform_device *pdev)
madera_free_irq(cs47l35->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l35);
madera_free_overheat(&cs47l35->core);
madera_core_free(&cs47l35->core);
-
- return 0;
}
static struct platform_driver cs47l35_codec_driver = {
@@ -1767,7 +1765,7 @@ static struct platform_driver cs47l35_codec_driver = {
.name = "cs47l35-codec",
},
.probe = &cs47l35_probe,
- .remove = &cs47l35_remove,
+ .remove_new = cs47l35_remove,
};
module_platform_driver(cs47l35_codec_driver);
diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c
index 215d8211aa59..dd7997a53e70 100644
--- a/sound/soc/codecs/cs47l85.c
+++ b/sound/soc/codecs/cs47l85.c
@@ -2695,7 +2695,7 @@ error_core:
return ret;
}
-static int cs47l85_remove(struct platform_device *pdev)
+static void cs47l85_remove(struct platform_device *pdev)
{
struct cs47l85 *cs47l85 = platform_get_drvdata(pdev);
int i;
@@ -2709,8 +2709,6 @@ static int cs47l85_remove(struct platform_device *pdev)
madera_free_irq(cs47l85->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l85);
madera_free_overheat(&cs47l85->core);
madera_core_free(&cs47l85->core);
-
- return 0;
}
static struct platform_driver cs47l85_codec_driver = {
@@ -2718,7 +2716,7 @@ static struct platform_driver cs47l85_codec_driver = {
.name = "cs47l85-codec",
},
.probe = &cs47l85_probe,
- .remove = &cs47l85_remove,
+ .remove_new = cs47l85_remove,
};
module_platform_driver(cs47l85_codec_driver);
diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c
index 1ad6526c7871..cdd5e7e20b5d 100644
--- a/sound/soc/codecs/cs47l90.c
+++ b/sound/soc/codecs/cs47l90.c
@@ -2618,7 +2618,7 @@ error_core:
return ret;
}
-static int cs47l90_remove(struct platform_device *pdev)
+static void cs47l90_remove(struct platform_device *pdev)
{
struct cs47l90 *cs47l90 = platform_get_drvdata(pdev);
int i;
@@ -2633,8 +2633,6 @@ static int cs47l90_remove(struct platform_device *pdev)
madera_set_irq_wake(cs47l90->core.madera, MADERA_IRQ_DSP_IRQ1, 0);
madera_free_irq(cs47l90->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l90);
madera_core_free(&cs47l90->core);
-
- return 0;
}
static struct platform_driver cs47l90_codec_driver = {
@@ -2642,7 +2640,7 @@ static struct platform_driver cs47l90_codec_driver = {
.name = "cs47l90-codec",
},
.probe = &cs47l90_probe,
- .remove = &cs47l90_remove,
+ .remove_new = cs47l90_remove,
};
module_platform_driver(cs47l90_codec_driver);
diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c
index fe576d64e089..bc4d311d4778 100644
--- a/sound/soc/codecs/cs47l92.c
+++ b/sound/soc/codecs/cs47l92.c
@@ -2068,7 +2068,7 @@ error_core:
return ret;
}
-static int cs47l92_remove(struct platform_device *pdev)
+static void cs47l92_remove(struct platform_device *pdev)
{
struct cs47l92 *cs47l92 = platform_get_drvdata(pdev);
@@ -2081,8 +2081,6 @@ static int cs47l92_remove(struct platform_device *pdev)
madera_free_irq(cs47l92->core.madera, MADERA_IRQ_DSP_IRQ1, cs47l92);
madera_core_free(&cs47l92->core);
-
- return 0;
}
static struct platform_driver cs47l92_codec_driver = {
@@ -2090,7 +2088,7 @@ static struct platform_driver cs47l92_codec_driver = {
.name = "cs47l92-codec",
},
.probe = &cs47l92_probe,
- .remove = &cs47l92_remove,
+ .remove_new = cs47l92_remove,
};
module_platform_driver(cs47l92_codec_driver);
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c
index 8222cde6e3b9..11320423c69c 100644
--- a/sound/soc/codecs/inno_rk3036.c
+++ b/sound/soc/codecs/inno_rk3036.c
@@ -457,13 +457,11 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev)
return ret;
}
-static int rk3036_codec_platform_remove(struct platform_device *pdev)
+static void rk3036_codec_platform_remove(struct platform_device *pdev)
{
struct rk3036_codec_priv *priv = dev_get_drvdata(&pdev->dev);
clk_disable_unprepare(priv->pclk);
-
- return 0;
}
static const struct of_device_id rk3036_codec_of_match[] __maybe_unused = {
@@ -478,7 +476,7 @@ static struct platform_driver rk3036_codec_platform_driver = {
.of_match_table = of_match_ptr(rk3036_codec_of_match),
},
.probe = rk3036_codec_platform_probe,
- .remove = rk3036_codec_platform_remove,
+ .remove_new = rk3036_codec_platform_remove,
};
module_platform_driver(rk3036_codec_platform_driver);
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
index a73a7d7a1c0a..9e0a4e8a46c3 100644
--- a/sound/soc/codecs/lpass-rx-macro.c
+++ b/sound/soc/codecs/lpass-rx-macro.c
@@ -3639,7 +3639,7 @@ err:
return ret;
}
-static int rx_macro_remove(struct platform_device *pdev)
+static void rx_macro_remove(struct platform_device *pdev)
{
struct rx_macro *rx = dev_get_drvdata(&pdev->dev);
@@ -3650,8 +3650,6 @@ static int rx_macro_remove(struct platform_device *pdev)
clk_disable_unprepare(rx->dcodec);
lpass_macro_pds_exit(rx->pds);
-
- return 0;
}
static const struct of_device_id rx_macro_dt_match[] = {
@@ -3723,7 +3721,7 @@ static struct platform_driver rx_macro_driver = {
.pm = &rx_macro_pm_ops,
},
.probe = rx_macro_probe,
- .remove = rx_macro_remove,
+ .remove_new = rx_macro_remove,
};
module_platform_driver(rx_macro_driver);
diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c
index 473d3cd39554..b044c9c6f89b 100644
--- a/sound/soc/codecs/lpass-tx-macro.c
+++ b/sound/soc/codecs/lpass-tx-macro.c
@@ -2076,7 +2076,7 @@ err:
return ret;
}
-static int tx_macro_remove(struct platform_device *pdev)
+static void tx_macro_remove(struct platform_device *pdev)
{
struct tx_macro *tx = dev_get_drvdata(&pdev->dev);
@@ -2087,8 +2087,6 @@ static int tx_macro_remove(struct platform_device *pdev)
clk_disable_unprepare(tx->fsgen);
lpass_macro_pds_exit(tx->pds);
-
- return 0;
}
static int __maybe_unused tx_macro_runtime_suspend(struct device *dev)
@@ -2160,7 +2158,7 @@ static struct platform_driver tx_macro_driver = {
.pm = &tx_macro_pm_ops,
},
.probe = tx_macro_probe,
- .remove = tx_macro_remove,
+ .remove_new = tx_macro_remove,
};
module_platform_driver(tx_macro_driver);
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index fd62817d29a0..74724448da50 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -1575,7 +1575,7 @@ err:
return ret;
}
-static int va_macro_remove(struct platform_device *pdev)
+static void va_macro_remove(struct platform_device *pdev)
{
struct va_macro *va = dev_get_drvdata(&pdev->dev);
@@ -1584,8 +1584,6 @@ static int va_macro_remove(struct platform_device *pdev)
clk_disable_unprepare(va->macro);
lpass_macro_pds_exit(va->pds);
-
- return 0;
}
static int __maybe_unused va_macro_runtime_suspend(struct device *dev)
@@ -1639,7 +1637,7 @@ static struct platform_driver va_macro_driver = {
.pm = &va_macro_pm_ops,
},
.probe = va_macro_probe,
- .remove = va_macro_remove,
+ .remove_new = va_macro_remove,
};
module_platform_driver(va_macro_driver);
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c
index ba7480f3831e..728f26d12ab0 100644
--- a/sound/soc/codecs/lpass-wsa-macro.c
+++ b/sound/soc/codecs/lpass-wsa-macro.c
@@ -2486,7 +2486,7 @@ err:
}
-static int wsa_macro_remove(struct platform_device *pdev)
+static void wsa_macro_remove(struct platform_device *pdev)
{
struct wsa_macro *wsa = dev_get_drvdata(&pdev->dev);
@@ -2495,8 +2495,6 @@ static int wsa_macro_remove(struct platform_device *pdev)
clk_disable_unprepare(wsa->mclk);
clk_disable_unprepare(wsa->npl);
clk_disable_unprepare(wsa->fsgen);
-
- return 0;
}
static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev)
@@ -2568,7 +2566,7 @@ static struct platform_driver wsa_macro_driver = {
.pm = &wsa_macro_pm_ops,
},
.probe = wsa_macro_probe,
- .remove = wsa_macro_remove,
+ .remove_new = wsa_macro_remove,
};
module_platform_driver(wsa_macro_driver);
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 78e543eb3c83..cec90cf920ff 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -1276,13 +1276,11 @@ err_disable_clk:
return ret;
}
-static int pm8916_wcd_analog_spmi_remove(struct platform_device *pdev)
+static void pm8916_wcd_analog_spmi_remove(struct platform_device *pdev)
{
struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(&pdev->dev);
clk_disable_unprepare(priv->mclk);
-
- return 0;
}
static const struct of_device_id pm8916_wcd_analog_spmi_match_table[] = {
@@ -1298,7 +1296,7 @@ static struct platform_driver pm8916_wcd_analog_spmi_driver = {
.of_match_table = pm8916_wcd_analog_spmi_match_table,
},
.probe = pm8916_wcd_analog_spmi_probe,
- .remove = pm8916_wcd_analog_spmi_remove,
+ .remove_new = pm8916_wcd_analog_spmi_remove,
};
module_platform_driver(pm8916_wcd_analog_spmi_driver);
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
index d490a0f18675..978c4d056e81 100644
--- a/sound/soc/codecs/msm8916-wcd-digital.c
+++ b/sound/soc/codecs/msm8916-wcd-digital.c
@@ -1220,14 +1220,12 @@ err_clk:
return ret;
}
-static int msm8916_wcd_digital_remove(struct platform_device *pdev)
+static void msm8916_wcd_digital_remove(struct platform_device *pdev)
{
struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(&pdev->dev);
clk_disable_unprepare(priv->mclk);
clk_disable_unprepare(priv->ahbclk);
-
- return 0;
}
static const struct of_device_id msm8916_wcd_digital_match_table[] = {
@@ -1243,7 +1241,7 @@ static struct platform_driver msm8916_wcd_digital_driver = {
.of_match_table = msm8916_wcd_digital_match_table,
},
.probe = msm8916_wcd_digital_probe,
- .remove = msm8916_wcd_digital_remove,
+ .remove_new = msm8916_wcd_digital_remove,
};
module_platform_driver(msm8916_wcd_digital_driver);
diff --git a/sound/soc/codecs/rk817_codec.c b/sound/soc/codecs/rk817_codec.c
index 2a5b274bfc0f..d4da98469f8b 100644
--- a/sound/soc/codecs/rk817_codec.c
+++ b/sound/soc/codecs/rk817_codec.c
@@ -518,13 +518,11 @@ err_:
return ret;
}
-static int rk817_platform_remove(struct platform_device *pdev)
+static void rk817_platform_remove(struct platform_device *pdev)
{
struct rk817_codec_priv *rk817 = platform_get_drvdata(pdev);
clk_disable_unprepare(rk817->mclk);
-
- return 0;
}
static struct platform_driver rk817_codec_driver = {
@@ -532,7 +530,7 @@ static struct platform_driver rk817_codec_driver = {
.name = "rk817-codec",
},
.probe = rk817_platform_probe,
- .remove = rk817_platform_remove,
+ .remove_new = rk817_platform_remove,
};
module_platform_driver(rk817_codec_driver);
diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
index fcac763b04d1..f033f79ed238 100644
--- a/sound/soc/codecs/wcd938x.c
+++ b/sound/soc/codecs/wcd938x.c
@@ -4529,11 +4529,9 @@ static int wcd938x_probe(struct platform_device *pdev)
return 0;
}
-static int wcd938x_remove(struct platform_device *pdev)
+static void wcd938x_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &wcd938x_comp_ops);
-
- return 0;
}
#if defined(CONFIG_OF)
@@ -4547,7 +4545,7 @@ MODULE_DEVICE_TABLE(of, wcd938x_dt_match);
static struct platform_driver wcd938x_codec_driver = {
.probe = wcd938x_probe,
- .remove = wcd938x_remove,
+ .remove_new = wcd938x_remove,
.driver = {
.name = "wcd938x_codec",
.of_match_table = of_match_ptr(wcd938x_dt_match),
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index adaf886b0a9d..3bdbdf3770b5 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -2148,7 +2148,7 @@ err_jack_codec_dev:
return ret;
}
-static int wm5102_remove(struct platform_device *pdev)
+static void wm5102_remove(struct platform_device *pdev)
{
struct wm5102_priv *wm5102 = platform_get_drvdata(pdev);
struct arizona *arizona = wm5102->core.arizona;
@@ -2163,8 +2163,6 @@ static int wm5102_remove(struct platform_device *pdev)
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102);
arizona_jack_codec_dev_remove(&wm5102->core);
-
- return 0;
}
static struct platform_driver wm5102_codec_driver = {
@@ -2172,7 +2170,7 @@ static struct platform_driver wm5102_codec_driver = {
.name = "wm5102-codec",
},
.probe = wm5102_probe,
- .remove = wm5102_remove,
+ .remove_new = wm5102_remove,
};
module_platform_driver(wm5102_codec_driver);
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index e0b971620d0f..ad670300de8d 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -2506,7 +2506,7 @@ err_jack_codec_dev:
return ret;
}
-static int wm5110_remove(struct platform_device *pdev)
+static void wm5110_remove(struct platform_device *pdev)
{
struct wm5110_priv *wm5110 = platform_get_drvdata(pdev);
struct arizona *arizona = wm5110->core.arizona;
@@ -2523,8 +2523,6 @@ static int wm5110_remove(struct platform_device *pdev)
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5110);
arizona_jack_codec_dev_remove(&wm5110->core);
-
- return 0;
}
static struct platform_driver wm5110_codec_driver = {
@@ -2532,7 +2530,7 @@ static struct platform_driver wm5110_codec_driver = {
.name = "wm5110-codec",
},
.probe = wm5110_probe,
- .remove = wm5110_remove,
+ .remove_new = wm5110_remove,
};
module_platform_driver(wm5110_codec_driver);
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 8fe9a75d1235..bca3ebe0dac4 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -4657,11 +4657,9 @@ static int wm8994_probe(struct platform_device *pdev)
return ret;
}
-static int wm8994_remove(struct platform_device *pdev)
+static void wm8994_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -4701,7 +4699,7 @@ static struct platform_driver wm8994_codec_driver = {
.pm = &wm8994_pm_ops,
},
.probe = wm8994_probe,
- .remove = wm8994_remove,
+ .remove_new = wm8994_remove,
};
module_platform_driver(wm8994_codec_driver);
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index c0207e9a7d53..87442840f0af 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -1193,7 +1193,7 @@ err_jack_codec_dev:
return ret;
}
-static int wm8997_remove(struct platform_device *pdev)
+static void wm8997_remove(struct platform_device *pdev)
{
struct wm8997_priv *wm8997 = platform_get_drvdata(pdev);
struct arizona *arizona = wm8997->core.arizona;
@@ -1203,8 +1203,6 @@ static int wm8997_remove(struct platform_device *pdev)
arizona_free_spk_irqs(arizona);
arizona_jack_codec_dev_remove(&wm8997->core);
-
- return 0;
}
static struct platform_driver wm8997_codec_driver = {
@@ -1212,7 +1210,7 @@ static struct platform_driver wm8997_codec_driver = {
.name = "wm8997-codec",
},
.probe = wm8997_probe,
- .remove = wm8997_remove,
+ .remove_new = wm8997_remove,
};
module_platform_driver(wm8997_codec_driver);
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 79fc6bbaa3aa..3c2c4d12c08e 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -1409,7 +1409,7 @@ err_pm_disable:
return ret;
}
-static int wm8998_remove(struct platform_device *pdev)
+static void wm8998_remove(struct platform_device *pdev)
{
struct wm8998_priv *wm8998 = platform_get_drvdata(pdev);
struct arizona *arizona = wm8998->core.arizona;
@@ -1419,8 +1419,6 @@ static int wm8998_remove(struct platform_device *pdev)
arizona_free_spk_irqs(arizona);
arizona_jack_codec_dev_remove(&wm8998->core);
-
- return 0;
}
static struct platform_driver wm8998_codec_driver = {
@@ -1428,7 +1426,7 @@ static struct platform_driver wm8998_codec_driver = {
.name = "wm8998-codec",
},
.probe = wm8998_probe,
- .remove = wm8998_remove,
+ .remove_new = wm8998_remove,
};
module_platform_driver(wm8998_codec_driver);
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index ea0dbc634ecf..216120b68b64 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -787,6 +787,8 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
adsp_dbg(dsp, "Failed to request '%s'\n", *filename);
kfree(*filename);
*filename = NULL;
+ } else {
+ adsp_dbg(dsp, "Found '%s'\n", *filename);
}
return ret;
@@ -807,7 +809,6 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
cirrus_dir, system_name,
asoc_component_prefix, "wmfw")) {
- adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename);
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
cirrus_dir, system_name,
asoc_component_prefix, "bin");
@@ -819,7 +820,6 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
cirrus_dir, system_name,
NULL, "wmfw")) {
- adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename);
if (asoc_component_prefix)
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
cirrus_dir, system_name,
@@ -835,7 +835,6 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
"", NULL, NULL, "wmfw")) {
- adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename);
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
"", NULL, NULL, "bin");
return 0;
@@ -844,12 +843,35 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
cirrus_dir, NULL, NULL, "wmfw");
if (!ret) {
- adsp_dbg(dsp, "Found '%s'\n", *wmfw_filename);
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
cirrus_dir, NULL, NULL, "bin");
return 0;
}
+ if (dsp->wmfw_optional) {
+ if (system_name) {
+ if (asoc_component_prefix)
+ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ cirrus_dir, system_name,
+ asoc_component_prefix, "bin");
+
+ if (!*coeff_firmware)
+ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ cirrus_dir, system_name,
+ NULL, "bin");
+ }
+
+ if (!*coeff_firmware)
+ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ "", NULL, NULL, "bin");
+
+ if (!*coeff_firmware)
+ wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ cirrus_dir, NULL, NULL, "bin");
+
+ return 0;
+ }
+
adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n",
cirrus_dir, dsp->part, dsp->fwf_name, wm_adsp_fw[dsp->fw].file,
system_name, asoc_component_prefix);
@@ -995,11 +1017,8 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
-static void wm_adsp_boot_work(struct work_struct *work)
+int wm_adsp_power_up(struct wm_adsp *dsp)
{
- struct wm_adsp *dsp = container_of(work,
- struct wm_adsp,
- boot_work);
int ret = 0;
char *wmfw_filename = NULL;
const struct firmware *wmfw_firmware = NULL;
@@ -1010,16 +1029,28 @@ static void wm_adsp_boot_work(struct work_struct *work)
&wmfw_firmware, &wmfw_filename,
&coeff_firmware, &coeff_filename);
if (ret)
- return;
+ return ret;
- cs_dsp_power_up(&dsp->cs_dsp,
- wmfw_firmware, wmfw_filename,
- coeff_firmware, coeff_filename,
- wm_adsp_fw_text[dsp->fw]);
+ ret = cs_dsp_power_up(&dsp->cs_dsp,
+ wmfw_firmware, wmfw_filename,
+ coeff_firmware, coeff_filename,
+ wm_adsp_fw_text[dsp->fw]);
wm_adsp_release_firmware_files(dsp,
wmfw_firmware, wmfw_filename,
coeff_firmware, coeff_filename);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(wm_adsp_power_up);
+
+static void wm_adsp_boot_work(struct work_struct *work)
+{
+ struct wm_adsp *dsp = container_of(work,
+ struct wm_adsp,
+ boot_work);
+
+ wm_adsp_power_up(dsp);
}
int wm_adsp_early_event(struct snd_soc_dapm_widget *w,
@@ -1102,8 +1133,10 @@ int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *comp
{
char preload[32];
- snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
- snd_soc_component_disable_pin(component, preload);
+ if (!dsp->cs_dsp.no_core_startstop) {
+ snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
+ snd_soc_component_disable_pin(component, preload);
+ }
cs_dsp_init_debugfs(&dsp->cs_dsp, component->debugfs_root);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index dc2f7a096e26..769904d34a87 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -34,6 +34,7 @@ struct wm_adsp {
unsigned int sys_config_size;
int fw;
+ bool wmfw_optional;
struct work_struct boot_work;
int (*pre_run)(struct wm_adsp *dsp);
@@ -90,6 +91,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
int wm_adsp_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
+int wm_adsp_power_up(struct wm_adsp *dsp);
+
irqreturn_t wm_adsp2_bus_error(int irq, void *data);
irqreturn_t wm_halo_bus_error(int irq, void *data);
irqreturn_t wm_halo_wdt_expire(int irq, void *data);
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index 7f7dd07c63b2..acdf98b2ee9c 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -730,7 +730,7 @@ err_clk_disable:
return ret;
}
-static int dw_i2s_remove(struct platform_device *pdev)
+static void dw_i2s_remove(struct platform_device *pdev)
{
struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
@@ -738,7 +738,6 @@ static int dw_i2s_remove(struct platform_device *pdev)
clk_disable_unprepare(dev->clk);
pm_runtime_disable(&pdev->dev);
- return 0;
}
#ifdef CONFIG_OF
@@ -756,7 +755,7 @@ static const struct dev_pm_ops dwc_pm_ops = {
static struct platform_driver dw_i2s_driver = {
.probe = dw_i2s_probe,
- .remove = dw_i2s_remove,
+ .remove_new = dw_i2s_remove,
.driver = {
.name = "designware-i2s",
.of_match_table = of_match_ptr(dw_i2s_of_match),
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 9af4c4a35eb1..e65a85feba78 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -205,11 +205,9 @@ err:
return ret;
}
-static int eukrea_tlv320_remove(struct platform_device *pdev)
+static void eukrea_tlv320_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&eukrea_tlv320);
-
- return 0;
}
static const struct of_device_id imx_tlv320_dt_ids[] = {
@@ -224,7 +222,7 @@ static struct platform_driver eukrea_tlv320_driver = {
.of_match_table = imx_tlv320_dt_ids,
},
.probe = eukrea_tlv320_probe,
- .remove = eukrea_tlv320_remove,
+ .remove_new = eukrea_tlv320_remove,
};
module_platform_driver(eukrea_tlv320_driver);
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index e16e7b3fa96c..adb8a59de2bd 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1252,13 +1252,11 @@ err_pm_disable:
return ret;
}
-static int fsl_asrc_remove(struct platform_device *pdev)
+static void fsl_asrc_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
fsl_asrc_runtime_suspend(&pdev->dev);
-
- return 0;
}
static int fsl_asrc_runtime_resume(struct device *dev)
@@ -1394,7 +1392,7 @@ MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
static struct platform_driver fsl_asrc_driver = {
.probe = fsl_asrc_probe,
- .remove = fsl_asrc_remove,
+ .remove_new = fsl_asrc_remove,
.driver = {
.name = "fsl-asrc",
.of_match_table = fsl_asrc_ids,
diff --git a/sound/soc/fsl/fsl_aud2htx.c b/sound/soc/fsl/fsl_aud2htx.c
index 1e421d9a03fb..46b0c5dcc4a5 100644
--- a/sound/soc/fsl/fsl_aud2htx.c
+++ b/sound/soc/fsl/fsl_aud2htx.c
@@ -257,11 +257,9 @@ static int fsl_aud2htx_probe(struct platform_device *pdev)
return ret;
}
-static int fsl_aud2htx_remove(struct platform_device *pdev)
+static void fsl_aud2htx_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static int __maybe_unused fsl_aud2htx_runtime_suspend(struct device *dev)
@@ -300,7 +298,7 @@ static const struct dev_pm_ops fsl_aud2htx_pm_ops = {
static struct platform_driver fsl_aud2htx_driver = {
.probe = fsl_aud2htx_probe,
- .remove = fsl_aud2htx_remove,
+ .remove_new = fsl_aud2htx_remove,
.driver = {
.name = "fsl-aud2htx",
.pm = &fsl_aud2htx_pm_ops,
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
index 672148dd4b23..0ab2c1962117 100644
--- a/sound/soc/fsl/fsl_audmix.c
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -506,7 +506,7 @@ err_disable_pm:
return ret;
}
-static int fsl_audmix_remove(struct platform_device *pdev)
+static void fsl_audmix_remove(struct platform_device *pdev)
{
struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev);
@@ -514,8 +514,6 @@ static int fsl_audmix_remove(struct platform_device *pdev)
if (priv->pdev)
platform_device_unregister(priv->pdev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -558,7 +556,7 @@ static const struct dev_pm_ops fsl_audmix_pm = {
static struct platform_driver fsl_audmix_driver = {
.probe = fsl_audmix_probe,
- .remove = fsl_audmix_remove,
+ .remove_new = fsl_audmix_remove,
.driver = {
.name = "fsl-audmix",
.of_match_table = fsl_audmix_ids,
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 808fb61a7a0f..963f9774c883 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -890,15 +890,13 @@ static int fsl_soc_dma_probe(struct platform_device *pdev)
return 0;
}
-static int fsl_soc_dma_remove(struct platform_device *pdev)
+static void fsl_soc_dma_remove(struct platform_device *pdev)
{
struct dma_object *dma = dev_get_drvdata(&pdev->dev);
iounmap(dma->channel);
irq_dispose_mapping(dma->irq);
kfree(dma);
-
- return 0;
}
static const struct of_device_id fsl_soc_dma_ids[] = {
@@ -913,7 +911,7 @@ static struct platform_driver fsl_soc_dma_driver = {
.of_match_table = fsl_soc_dma_ids,
},
.probe = fsl_soc_dma_probe,
- .remove = fsl_soc_dma_remove,
+ .remove_new = fsl_soc_dma_remove,
};
module_platform_driver(fsl_soc_dma_driver);
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index 3153d19136b2..670cbdb361b6 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -1979,11 +1979,9 @@ static int fsl_easrc_probe(struct platform_device *pdev)
return 0;
}
-static int fsl_easrc_remove(struct platform_device *pdev)
+static void fsl_easrc_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static __maybe_unused int fsl_easrc_runtime_suspend(struct device *dev)
@@ -2093,7 +2091,7 @@ static const struct dev_pm_ops fsl_easrc_pm_ops = {
static struct platform_driver fsl_easrc_driver = {
.probe = fsl_easrc_probe,
- .remove = fsl_easrc_remove,
+ .remove_new = fsl_easrc_remove,
.driver = {
.name = "fsl-easrc",
.pm = &fsl_easrc_pm_ops,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 17fefd27ec90..936f0cd4b06d 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -1101,7 +1101,7 @@ err_pm_disable:
return ret;
}
-static int fsl_esai_remove(struct platform_device *pdev)
+static void fsl_esai_remove(struct platform_device *pdev)
{
struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
@@ -1110,8 +1110,6 @@ static int fsl_esai_remove(struct platform_device *pdev)
fsl_esai_runtime_suspend(&pdev->dev);
cancel_work_sync(&esai_priv->work);
-
- return 0;
}
static const struct of_device_id fsl_esai_dt_ids[] = {
@@ -1200,7 +1198,7 @@ static const struct dev_pm_ops fsl_esai_pm_ops = {
static struct platform_driver fsl_esai_driver = {
.probe = fsl_esai_probe,
- .remove = fsl_esai_remove,
+ .remove_new = fsl_esai_remove,
.driver = {
.name = "fsl-esai-dai",
.pm = &fsl_esai_pm_ops,
diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c
index 4922e6795b73..3fb3d3e4d09a 100644
--- a/sound/soc/fsl/fsl_mqs.c
+++ b/sound/soc/fsl/fsl_mqs.c
@@ -261,10 +261,9 @@ err_free_gpr_np:
return ret;
}
-static int fsl_mqs_remove(struct platform_device *pdev)
+static void fsl_mqs_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
#ifdef CONFIG_PM
@@ -360,7 +359,7 @@ MODULE_DEVICE_TABLE(of, fsl_mqs_dt_ids);
static struct platform_driver fsl_mqs_driver = {
.probe = fsl_mqs_probe,
- .remove = fsl_mqs_remove,
+ .remove_new = fsl_mqs_remove,
.driver = {
.name = "fsl-mqs",
.of_match_table = fsl_mqs_dt_ids,
diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c
index 46c7868a2653..15b48b5ea856 100644
--- a/sound/soc/fsl/fsl_rpmsg.c
+++ b/sound/soc/fsl/fsl_rpmsg.c
@@ -247,14 +247,12 @@ static int fsl_rpmsg_probe(struct platform_device *pdev)
return 0;
}
-static int fsl_rpmsg_remove(struct platform_device *pdev)
+static void fsl_rpmsg_remove(struct platform_device *pdev)
{
struct fsl_rpmsg *rpmsg = platform_get_drvdata(pdev);
if (rpmsg->card_pdev)
platform_device_unregister(rpmsg->card_pdev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -302,7 +300,7 @@ static const struct dev_pm_ops fsl_rpmsg_pm_ops = {
static struct platform_driver fsl_rpmsg_driver = {
.probe = fsl_rpmsg_probe,
- .remove = fsl_rpmsg_remove,
+ .remove_new = fsl_rpmsg_remove,
.driver = {
.name = "fsl_rpmsg",
.pm = &fsl_rpmsg_pm_ops,
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 4e6b75f1ddd0..07d13dca852e 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1489,13 +1489,11 @@ err_pm_disable:
return ret;
}
-static int fsl_sai_remove(struct platform_device *pdev)
+static void fsl_sai_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
fsl_sai_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct fsl_sai_soc_data fsl_sai_vf610_data = {
@@ -1696,7 +1694,7 @@ static const struct dev_pm_ops fsl_sai_pm_ops = {
static struct platform_driver fsl_sai_driver = {
.probe = fsl_sai_probe,
- .remove = fsl_sai_remove,
+ .remove_new = fsl_sai_remove,
.driver = {
.name = "fsl-sai",
.pm = &fsl_sai_pm_ops,
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 275aba8e0c46..015c3708aa04 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1659,11 +1659,9 @@ err_pm_disable:
return ret;
}
-static int fsl_spdif_remove(struct platform_device *pdev)
+static void fsl_spdif_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -1765,7 +1763,7 @@ static struct platform_driver fsl_spdif_driver = {
.pm = &fsl_spdif_pm,
},
.probe = fsl_spdif_probe,
- .remove = fsl_spdif_remove,
+ .remove_new = fsl_spdif_remove,
};
module_platform_driver(fsl_spdif_driver);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 6af00b62a60f..53ed3701b0b0 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1671,7 +1671,7 @@ error_ac97_ops:
return ret;
}
-static int fsl_ssi_remove(struct platform_device *pdev)
+static void fsl_ssi_remove(struct platform_device *pdev)
{
struct fsl_ssi *ssi = dev_get_drvdata(&pdev->dev);
@@ -1690,8 +1690,6 @@ static int fsl_ssi_remove(struct platform_device *pdev)
snd_soc_set_ac97_ops(NULL);
mutex_destroy(&ssi->ac97_reg_lock);
}
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -1737,7 +1735,7 @@ static struct platform_driver fsl_ssi_driver = {
.pm = &fsl_ssi_pm,
},
.probe = fsl_ssi_probe,
- .remove = fsl_ssi_remove,
+ .remove_new = fsl_ssi_remove,
};
module_platform_driver(fsl_ssi_driver);
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
index 2a78243df752..318fe77683f5 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -1339,10 +1339,9 @@ static int fsl_xcvr_probe(struct platform_device *pdev)
return ret;
}
-static int fsl_xcvr_remove(struct platform_device *pdev)
+static void fsl_xcvr_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev)
@@ -1478,7 +1477,7 @@ static struct platform_driver fsl_xcvr_driver = {
.pm = &fsl_xcvr_pm_ops,
.of_match_table = fsl_xcvr_dt_ids,
},
- .remove = fsl_xcvr_remove,
+ .remove_new = fsl_xcvr_remove,
};
module_platform_driver(fsl_xcvr_driver);
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 582f1e2431ee..be003a117b39 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -315,12 +315,10 @@ static int imx_audmux_probe(struct platform_device *pdev)
return 0;
}
-static int imx_audmux_remove(struct platform_device *pdev)
+static void imx_audmux_remove(struct platform_device *pdev)
{
if (audmux_type == IMX31_AUDMUX)
audmux_debugfs_remove();
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -359,7 +357,7 @@ static const struct dev_pm_ops imx_audmux_pm = {
static struct platform_driver imx_audmux_driver = {
.probe = imx_audmux_probe,
- .remove = imx_audmux_remove,
+ .remove_new = imx_audmux_remove,
.driver = {
.name = DRIVER_NAME,
.pm = &imx_audmux_pm,
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index 6614b3447649..765dad607bf6 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -743,14 +743,12 @@ fail:
return ret;
}
-static int imx_rpmsg_pcm_remove(struct platform_device *pdev)
+static void imx_rpmsg_pcm_remove(struct platform_device *pdev)
{
struct rpmsg_info *info = platform_get_drvdata(pdev);
if (info->rpmsg_wq)
destroy_workqueue(info->rpmsg_wq);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -821,7 +819,7 @@ static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = {
static struct platform_driver imx_pcm_rpmsg_driver = {
.probe = imx_rpmsg_pcm_probe,
- .remove = imx_rpmsg_pcm_remove,
+ .remove_new = imx_rpmsg_pcm_remove,
.driver = {
.name = IMX_PCM_DRV_NAME,
.pm = &imx_rpmsg_pcm_pm_ops,
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 580a0d963f0e..26c22783927b 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -193,14 +193,12 @@ fail:
return ret;
}
-static int imx_sgtl5000_remove(struct platform_device *pdev)
+static void imx_sgtl5000_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card);
clk_put(data->codec_clk);
-
- return 0;
}
static const struct of_device_id imx_sgtl5000_dt_ids[] = {
@@ -216,7 +214,7 @@ static struct platform_driver imx_sgtl5000_driver = {
.of_match_table = imx_sgtl5000_dt_ids,
},
.probe = imx_sgtl5000_probe,
- .remove = imx_sgtl5000_remove,
+ .remove_new = imx_sgtl5000_remove,
};
module_platform_driver(imx_sgtl5000_driver);
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index a082ae636a4f..40a4a2667394 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -311,12 +311,11 @@ static int psc_ac97_of_probe(struct platform_device *op)
return 0;
}
-static int psc_ac97_of_remove(struct platform_device *op)
+static void psc_ac97_of_remove(struct platform_device *op)
{
mpc5200_audio_dma_destroy(op);
snd_soc_unregister_component(&op->dev);
snd_soc_set_ac97_ops(NULL);
- return 0;
}
/* Match table for of_platform binding */
@@ -329,7 +328,7 @@ MODULE_DEVICE_TABLE(of, psc_ac97_match);
static struct platform_driver psc_ac97_driver = {
.probe = psc_ac97_of_probe,
- .remove = psc_ac97_of_remove,
+ .remove_new = psc_ac97_of_remove,
.driver = {
.name = "mpc5200-psc-ac97",
.of_match_table = psc_ac97_match,
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 73f3e61f208a..413df413b5eb 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -210,11 +210,10 @@ static int psc_i2s_of_probe(struct platform_device *op)
}
-static int psc_i2s_of_remove(struct platform_device *op)
+static void psc_i2s_of_remove(struct platform_device *op)
{
mpc5200_audio_dma_destroy(op);
snd_soc_unregister_component(&op->dev);
- return 0;
}
/* Match table for of_platform binding */
@@ -227,7 +226,7 @@ MODULE_DEVICE_TABLE(of, psc_i2s_match);
static struct platform_driver psc_i2s_driver = {
.probe = psc_i2s_of_probe,
- .remove = psc_i2s_of_remove,
+ .remove_new = psc_i2s_of_remove,
.driver = {
.name = "mpc5200-psc-i2s",
.of_match_table = psc_i2s_match,
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index e71a992fbf93..ea2076ea8afe 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -387,7 +387,7 @@ error_alloc:
*
* This function is called when the platform device is removed.
*/
-static int mpc8610_hpcd_remove(struct platform_device *pdev)
+static void mpc8610_hpcd_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct mpc8610_hpcd_data *machine_data =
@@ -395,13 +395,11 @@ static int mpc8610_hpcd_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
kfree(machine_data);
-
- return 0;
}
static struct platform_driver mpc8610_hpcd_driver = {
.probe = mpc8610_hpcd_probe,
- .remove = mpc8610_hpcd_remove,
+ .remove_new = mpc8610_hpcd_remove,
.driver = {
/* The name must match 'compatible' property in the device tree,
* in lowercase letters.
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index b45742931b0d..0b1418abeb9c 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -396,7 +396,7 @@ error_put:
*
* This function is called when the platform device is removed.
*/
-static int p1022_ds_remove(struct platform_device *pdev)
+static void p1022_ds_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct machine_data *mdata =
@@ -404,13 +404,11 @@ static int p1022_ds_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
kfree(mdata);
-
- return 0;
}
static struct platform_driver p1022_ds_driver = {
.probe = p1022_ds_probe,
- .remove = p1022_ds_remove,
+ .remove_new = p1022_ds_remove,
.driver = {
/*
* The name must match 'compatible' property in the device tree,
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c
index b395adabe823..4d85b742114c 100644
--- a/sound/soc/fsl/p1022_rdk.c
+++ b/sound/soc/fsl/p1022_rdk.c
@@ -345,7 +345,7 @@ error_put:
*
* This function is called when the platform device is removed.
*/
-static int p1022_rdk_remove(struct platform_device *pdev)
+static void p1022_rdk_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct machine_data *mdata =
@@ -353,13 +353,11 @@ static int p1022_rdk_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
kfree(mdata);
-
- return 0;
}
static struct platform_driver p1022_rdk_driver = {
.probe = p1022_rdk_probe,
- .remove = p1022_rdk_remove,
+ .remove_new = p1022_rdk_remove,
.driver = {
/*
* The name must match 'compatible' property in the device tree,
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index 997c3e66c636..d24c02e90878 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -109,14 +109,12 @@ static int pcm030_fabric_probe(struct platform_device *op)
}
-static int pcm030_fabric_remove(struct platform_device *op)
+static void pcm030_fabric_remove(struct platform_device *op)
{
struct pcm030_audio_data *pdata = platform_get_drvdata(op);
snd_soc_unregister_card(pdata->card);
platform_device_unregister(pdata->codec_device);
-
- return 0;
}
static const struct of_device_id pcm030_audio_match[] = {
@@ -127,7 +125,7 @@ MODULE_DEVICE_TABLE(of, pcm030_audio_match);
static struct platform_driver pcm030_fabric_driver = {
.probe = pcm030_fabric_probe,
- .remove = pcm030_fabric_remove,
+ .remove_new = pcm030_fabric_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = pcm030_audio_match,
diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c
index 98c8990596a8..e10e5bf28432 100644
--- a/sound/soc/generic/test-component.c
+++ b/sound/soc/generic/test-component.c
@@ -635,11 +635,9 @@ static int test_driver_probe(struct platform_device *pdev)
return 0;
}
-static int test_driver_remove(struct platform_device *pdev)
+static void test_driver_remove(struct platform_device *pdev)
{
mile_stone_x(&pdev->dev);
-
- return 0;
}
static struct platform_driver test_driver = {
@@ -648,7 +646,7 @@ static struct platform_driver test_driver = {
.of_match_table = test_of_match,
},
.probe = test_driver_probe,
- .remove = test_driver_remove,
+ .remove_new = test_driver_remove,
};
module_platform_driver(test_driver);
diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c
index 56bb7bbd3976..b7ab8467b5cf 100644
--- a/sound/soc/img/img-i2s-in.c
+++ b/sound/soc/img/img-i2s-in.c
@@ -532,13 +532,11 @@ err_pm_disable:
return ret;
}
-static int img_i2s_in_dev_remove(struct platform_device *pdev)
+static void img_i2s_in_dev_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
img_i2s_in_runtime_suspend(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -609,7 +607,7 @@ static struct platform_driver img_i2s_in_driver = {
.pm = &img_i2s_in_pm_ops
},
.probe = img_i2s_in_probe,
- .remove = img_i2s_in_dev_remove
+ .remove_new = img_i2s_in_dev_remove
};
module_platform_driver(img_i2s_in_driver);
diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c
index abeff7829310..fe95ddfb8407 100644
--- a/sound/soc/img/img-i2s-out.c
+++ b/sound/soc/img/img-i2s-out.c
@@ -532,13 +532,11 @@ err_pm_disable:
return ret;
}
-static int img_i2s_out_dev_remove(struct platform_device *pdev)
+static void img_i2s_out_dev_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
img_i2s_out_runtime_suspend(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -609,7 +607,7 @@ static struct platform_driver img_i2s_out_driver = {
.pm = &img_i2s_out_pm_ops
},
.probe = img_i2s_out_probe,
- .remove = img_i2s_out_dev_remove
+ .remove_new = img_i2s_out_dev_remove
};
module_platform_driver(img_i2s_out_driver);
diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c
index 08506b05e226..df1291ee2b3b 100644
--- a/sound/soc/img/img-parallel-out.c
+++ b/sound/soc/img/img-parallel-out.c
@@ -282,7 +282,7 @@ err_pm_disable:
return ret;
}
-static int img_prl_out_dev_remove(struct platform_device *pdev)
+static void img_prl_out_dev_remove(struct platform_device *pdev)
{
struct img_prl_out *prl = platform_get_drvdata(pdev);
@@ -291,8 +291,6 @@ static int img_prl_out_dev_remove(struct platform_device *pdev)
img_prl_out_suspend(&pdev->dev);
clk_disable_unprepare(prl->clk_sys);
-
- return 0;
}
static const struct of_device_id img_prl_out_of_match[] = {
@@ -313,7 +311,7 @@ static struct platform_driver img_prl_out_driver = {
.pm = &img_prl_out_pm_ops
},
.probe = img_prl_out_probe,
- .remove = img_prl_out_dev_remove
+ .remove_new = img_prl_out_dev_remove
};
module_platform_driver(img_prl_out_driver);
diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c
index 3f1d1a7e8735..558062a1804a 100644
--- a/sound/soc/img/img-spdif-in.c
+++ b/sound/soc/img/img-spdif-in.c
@@ -810,13 +810,11 @@ err_pm_disable:
return ret;
}
-static int img_spdif_in_dev_remove(struct platform_device *pdev)
+static void img_spdif_in_dev_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
img_spdif_in_runtime_suspend(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -880,7 +878,7 @@ static struct platform_driver img_spdif_in_driver = {
.pm = &img_spdif_in_pm_ops
},
.probe = img_spdif_in_probe,
- .remove = img_spdif_in_dev_remove
+ .remove_new = img_spdif_in_dev_remove
};
module_platform_driver(img_spdif_in_driver);
diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c
index 983761d3fa7e..b13e128e50d6 100644
--- a/sound/soc/img/img-spdif-out.c
+++ b/sound/soc/img/img-spdif-out.c
@@ -402,13 +402,11 @@ err_pm_disable:
return ret;
}
-static int img_spdif_out_dev_remove(struct platform_device *pdev)
+static void img_spdif_out_dev_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
img_spdif_out_runtime_suspend(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -470,7 +468,7 @@ static struct platform_driver img_spdif_out_driver = {
.pm = &img_spdif_out_pm_ops
},
.probe = img_spdif_out_probe,
- .remove = img_spdif_out_dev_remove
+ .remove_new = img_spdif_out_dev_remove
};
module_platform_driver(img_spdif_out_driver);
diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c
index e3b858643bd5..da6251680e41 100644
--- a/sound/soc/img/pistachio-internal-dac.c
+++ b/sound/soc/img/pistachio-internal-dac.c
@@ -215,15 +215,13 @@ err_regulator:
return ret;
}
-static int pistachio_internal_dac_remove(struct platform_device *pdev)
+static void pistachio_internal_dac_remove(struct platform_device *pdev)
{
struct pistachio_internal_dac *dac = dev_get_drvdata(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pistachio_internal_dac_pwr_off(dac);
regulator_disable(dac->supply);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -273,7 +271,7 @@ static struct platform_driver pistachio_internal_dac_plat_driver = {
.pm = &pistachio_internal_dac_pm_ops
},
.probe = pistachio_internal_dac_probe,
- .remove = pistachio_internal_dac_remove
+ .remove_new = pistachio_internal_dac_remove
};
module_platform_driver(pistachio_internal_dac_plat_driver);
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index c75616a5fd0a..ba4597bdf32e 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -741,10 +741,9 @@ static int sst_platform_probe(struct platform_device *pdev)
return ret;
}
-static int sst_platform_remove(struct platform_device *pdev)
+static void sst_platform_remove(struct platform_device *pdev)
{
dev_dbg(&pdev->dev, "sst_platform_remove success\n");
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -813,7 +812,7 @@ static struct platform_driver sst_platform_driver = {
.pm = &sst_platform_pm,
},
.probe = sst_platform_probe,
- .remove = sst_platform_remove,
+ .remove_new = sst_platform_remove,
};
module_platform_driver(sst_platform_driver);
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 3be64430c256..d3973936426a 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -335,14 +335,13 @@ static int sst_acpi_probe(struct platform_device *pdev)
* This function is called by OS when a device is unloaded
* This frees the interrupt etc
*/
-static int sst_acpi_remove(struct platform_device *pdev)
+static void sst_acpi_remove(struct platform_device *pdev)
{
struct intel_sst_drv *ctx;
ctx = platform_get_drvdata(pdev);
sst_context_cleanup(ctx);
platform_set_drvdata(pdev, NULL);
- return 0;
}
static const struct acpi_device_id sst_acpi_ids[] = {
@@ -360,7 +359,7 @@ static struct platform_driver sst_acpi_driver = {
.pm = &intel_sst_pm,
},
.probe = sst_acpi_probe,
- .remove = sst_acpi_remove,
+ .remove_new = sst_acpi_remove,
};
module_platform_driver(sst_acpi_driver);
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index df157b01df8b..7a30d2d36f19 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -628,7 +628,7 @@ err_put_codec:
return ret;
}
-static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
+static void snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
@@ -636,7 +636,6 @@ static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
gpiod_put(priv->speaker_en_gpio);
device_remove_software_node(priv->codec_dev);
put_device(priv->codec_dev);
- return 0;
}
static struct platform_driver snd_byt_cht_es8316_mc_driver = {
@@ -644,7 +643,7 @@ static struct platform_driver snd_byt_cht_es8316_mc_driver = {
.name = "bytcht_es8316",
},
.probe = snd_byt_cht_es8316_mc_probe,
- .remove = snd_byt_cht_es8316_mc_remove,
+ .remove_new = snd_byt_cht_es8316_mc_remove,
};
module_platform_driver(snd_byt_cht_es8316_mc_driver);
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 79e0039c79a3..789609eb0884 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -1844,7 +1844,7 @@ err_device:
return ret_val;
}
-static int snd_byt_rt5640_mc_remove(struct platform_device *pdev)
+static void snd_byt_rt5640_mc_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
@@ -1854,7 +1854,6 @@ static int snd_byt_rt5640_mc_remove(struct platform_device *pdev)
device_remove_software_node(priv->codec_dev);
put_device(priv->codec_dev);
- return 0;
}
static struct platform_driver snd_byt_rt5640_mc_driver = {
@@ -1862,7 +1861,7 @@ static struct platform_driver snd_byt_rt5640_mc_driver = {
.name = "bytcr_rt5640",
},
.probe = snd_byt_rt5640_mc_probe,
- .remove = snd_byt_rt5640_mc_remove,
+ .remove_new = snd_byt_rt5640_mc_remove,
};
module_platform_driver(snd_byt_rt5640_mc_driver);
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 8fca9b82d4d0..805afaf47b29 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -1127,14 +1127,13 @@ err_device:
return ret_val;
}
-static int snd_byt_rt5651_mc_remove(struct platform_device *pdev)
+static void snd_byt_rt5651_mc_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
device_remove_software_node(priv->codec_dev);
put_device(priv->codec_dev);
- return 0;
}
static struct platform_driver snd_byt_rt5651_mc_driver = {
@@ -1142,7 +1141,7 @@ static struct platform_driver snd_byt_rt5651_mc_driver = {
.name = "bytcr_rt5651",
},
.probe = snd_byt_rt5651_mc_probe,
- .remove = snd_byt_rt5651_mc_remove,
+ .remove_new = snd_byt_rt5651_mc_remove,
};
module_platform_driver(snd_byt_rt5651_mc_driver);
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c
index c0706537f673..f2382d4cb76f 100644
--- a/sound/soc/intel/boards/bytcr_wm5102.c
+++ b/sound/soc/intel/boards/bytcr_wm5102.c
@@ -466,13 +466,12 @@ out_put_gpio:
return ret;
}
-static int snd_byt_wm5102_mc_remove(struct platform_device *pdev)
+static void snd_byt_wm5102_mc_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card);
gpiod_put(priv->spkvdd_en_gpio);
- return 0;
}
static struct platform_driver snd_byt_wm5102_mc_driver = {
@@ -480,7 +479,7 @@ static struct platform_driver snd_byt_wm5102_mc_driver = {
.name = "bytcr_wm5102",
},
.probe = snd_byt_wm5102_mc_probe,
- .remove = snd_byt_wm5102_mc_remove,
+ .remove_new = snd_byt_wm5102_mc_remove,
};
module_platform_driver(snd_byt_wm5102_mc_driver);
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 2c086e901aae..850310de774b 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -623,15 +623,13 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
return ret_val;
}
-static int snd_cht_mc_remove(struct platform_device *pdev)
+static void snd_cht_mc_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
if (ctx->quirks & QUIRK_PMC_PLT_CLK_0)
clk_disable_unprepare(ctx->mclk);
-
- return 0;
}
static struct platform_driver snd_cht_mc_driver = {
@@ -639,7 +637,7 @@ static struct platform_driver snd_cht_mc_driver = {
.name = "cht-bsw-max98090",
},
.probe = snd_cht_mc_probe,
- .remove = snd_cht_mc_remove,
+ .remove_new = snd_cht_mc_remove,
};
module_platform_driver(snd_cht_mc_driver)
diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
index 894b6610b9e2..adf5852b2c9a 100644
--- a/sound/soc/intel/boards/sof_es8336.c
+++ b/sound/soc/intel/boards/sof_es8336.c
@@ -780,7 +780,7 @@ err_put_codec:
return ret;
}
-static int sof_es8336_remove(struct platform_device *pdev)
+static void sof_es8336_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
@@ -789,8 +789,6 @@ static int sof_es8336_remove(struct platform_device *pdev)
gpiod_put(priv->gpio_speakers);
device_remove_software_node(priv->codec_dev);
put_device(priv->codec_dev);
-
- return 0;
}
static const struct platform_device_id board_ids[] = {
@@ -817,7 +815,7 @@ static struct platform_driver sof_es8336_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = sof_es8336_probe,
- .remove = sof_es8336_remove,
+ .remove_new = sof_es8336_remove,
.id_table = board_ids,
};
module_platform_driver(sof_es8336_driver);
diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c
index d4c67d5340a9..5192e02b3cee 100644
--- a/sound/soc/intel/boards/sof_pcm512x.c
+++ b/sound/soc/intel/boards/sof_pcm512x.c
@@ -416,7 +416,7 @@ static int sof_audio_probe(struct platform_device *pdev)
&sof_audio_card_pcm512x);
}
-static int sof_pcm512x_remove(struct platform_device *pdev)
+static void sof_pcm512x_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct snd_soc_component *component;
@@ -427,13 +427,11 @@ static int sof_pcm512x_remove(struct platform_device *pdev)
break;
}
}
-
- return 0;
}
static struct platform_driver sof_audio = {
.probe = sof_audio_probe,
- .remove = sof_pcm512x_remove,
+ .remove_new = sof_pcm512x_remove,
.driver = {
.name = "sof_pcm512x",
.pm = &snd_soc_pm_ops,
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index d2ed807abde9..4ea69197791c 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -1602,13 +1602,11 @@ static int mc_probe(struct platform_device *pdev)
return ret;
}
-static int mc_remove(struct platform_device *pdev)
+static void mc_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
mc_dailink_exit_loop(card);
-
- return 0;
}
static struct platform_driver sof_sdw_driver = {
@@ -1617,7 +1615,7 @@ static struct platform_driver sof_sdw_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = mc_probe,
- .remove = mc_remove,
+ .remove_new = mc_remove,
};
module_platform_driver(sof_sdw_driver);
diff --git a/sound/soc/intel/boards/sof_wm8804.c b/sound/soc/intel/boards/sof_wm8804.c
index fbad5a73de44..17224d26d9d6 100644
--- a/sound/soc/intel/boards/sof_wm8804.c
+++ b/sound/soc/intel/boards/sof_wm8804.c
@@ -278,11 +278,10 @@ static int sof_wm8804_probe(struct platform_device *pdev)
return devm_snd_soc_register_card(&pdev->dev, card);
}
-static int sof_wm8804_remove(struct platform_device *pdev)
+static void sof_wm8804_remove(struct platform_device *pdev)
{
if (sof_wm8804_quirk & SOF_WM8804_UP2_QUIRK)
gpiod_remove_lookup_table(&up2_gpios_table);
- return 0;
}
static struct platform_driver sof_wm8804_driver = {
@@ -291,7 +290,7 @@ static struct platform_driver sof_wm8804_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = sof_wm8804_probe,
- .remove = sof_wm8804_remove,
+ .remove_new = sof_wm8804_remove,
};
module_platform_driver(sof_wm8804_driver);
diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c
index d5d08bd766c7..cac3dffbd0d9 100644
--- a/sound/soc/intel/catpt/device.c
+++ b/sound/soc/intel/catpt/device.c
@@ -293,7 +293,7 @@ static int catpt_acpi_probe(struct platform_device *pdev)
return catpt_probe_components(cdev);
}
-static int catpt_acpi_remove(struct platform_device *pdev)
+static void catpt_acpi_remove(struct platform_device *pdev)
{
struct catpt_dev *cdev = platform_get_drvdata(pdev);
@@ -305,8 +305,6 @@ static int catpt_acpi_remove(struct platform_device *pdev)
catpt_sram_free(&cdev->iram);
catpt_sram_free(&cdev->dram);
-
- return 0;
}
static struct snd_soc_acpi_mach lpt_machines[] = {
@@ -376,7 +374,7 @@ MODULE_DEVICE_TABLE(acpi, catpt_ids);
static struct platform_driver catpt_acpi_driver = {
.probe = catpt_acpi_probe,
- .remove = catpt_acpi_remove,
+ .remove_new = catpt_acpi_remove,
.driver = {
.name = "intel_catpt",
.acpi_match_table = catpt_ids,
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
index a3a73c26f9aa..50e93c3707e8 100644
--- a/sound/soc/intel/skylake/skl-ssp-clk.c
+++ b/sound/soc/intel/skylake/skl-ssp-clk.c
@@ -402,15 +402,13 @@ err_unreg_skl_clk:
return ret;
}
-static int skl_clk_dev_remove(struct platform_device *pdev)
+static void skl_clk_dev_remove(struct platform_device *pdev)
{
struct skl_clk_data *data;
data = platform_get_drvdata(pdev);
unregister_src_clk(data);
unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC);
-
- return 0;
}
static struct platform_driver skl_clk_driver = {
@@ -418,7 +416,7 @@ static struct platform_driver skl_clk_driver = {
.name = "skl-ssp-clk",
},
.probe = skl_clk_dev_probe,
- .remove = skl_clk_dev_remove,
+ .remove_new = skl_clk_dev_remove,
};
module_platform_driver(skl_clk_driver);
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index afdf7d61e4c5..d1eb90310afa 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -736,7 +736,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
return err;
}
-static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
+static void kirkwood_i2s_dev_remove(struct platform_device *pdev)
{
struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
@@ -744,8 +744,6 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
if (!IS_ERR(priv->extclk))
clk_disable_unprepare(priv->extclk);
clk_disable_unprepare(priv->clk);
-
- return 0;
}
#ifdef CONFIG_OF
@@ -761,7 +759,7 @@ MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
static struct platform_driver kirkwood_i2s_driver = {
.probe = kirkwood_i2s_dev_probe,
- .remove = kirkwood_i2s_dev_remove,
+ .remove_new = kirkwood_i2s_dev_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(mvebu_audio_of_match),
diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c
index 1c28b41e4311..1ba0633e542f 100644
--- a/sound/soc/mediatek/common/mtk-btcvsd.c
+++ b/sound/soc/mediatek/common/mtk-btcvsd.c
@@ -1387,13 +1387,12 @@ unmap_pkv_err:
return ret;
}
-static int mtk_btcvsd_snd_remove(struct platform_device *pdev)
+static void mtk_btcvsd_snd_remove(struct platform_device *pdev)
{
struct mtk_btcvsd_snd *btcvsd = dev_get_drvdata(&pdev->dev);
iounmap(btcvsd->bt_pkv_base);
iounmap(btcvsd->bt_sram_bank2_base);
- return 0;
}
static const struct of_device_id mtk_btcvsd_snd_dt_match[] = {
@@ -1408,7 +1407,7 @@ static struct platform_driver mtk_btcvsd_snd_driver = {
.of_match_table = mtk_btcvsd_snd_dt_match,
},
.probe = mtk_btcvsd_snd_probe,
- .remove = mtk_btcvsd_snd_remove,
+ .remove_new = mtk_btcvsd_snd_remove,
};
module_platform_driver(mtk_btcvsd_snd_driver);
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 0f178de92a0f..c9d4420e9b4c 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -1439,14 +1439,12 @@ err_pm_disable:
return ret;
}
-static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
+static void mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
{
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mt2701_afe_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct mt2701_soc_variants mt2701_soc_v1 = {
@@ -1477,7 +1475,7 @@ static struct platform_driver mt2701_afe_pcm_driver = {
.pm = &mt2701_afe_pm_ops,
},
.probe = mt2701_afe_pcm_dev_probe,
- .remove = mt2701_afe_pcm_dev_remove,
+ .remove_new = mt2701_afe_pcm_dev_remove,
};
module_platform_driver(mt2701_afe_pcm_driver);
diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
index fb4abec9aa5f..43038444c43d 100644
--- a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
@@ -876,14 +876,12 @@ err_pm_disable:
return ret;
}
-static int mt6797_afe_pcm_dev_remove(struct platform_device *pdev)
+static void mt6797_afe_pcm_dev_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mt6797_afe_runtime_suspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
-
- return 0;
}
static const struct of_device_id mt6797_afe_pcm_dt_match[] = {
@@ -904,7 +902,7 @@ static struct platform_driver mt6797_afe_pcm_driver = {
.pm = &mt6797_afe_pm_ops,
},
.probe = mt6797_afe_pcm_dev_probe,
- .remove = mt6797_afe_pcm_dev_remove,
+ .remove_new = mt6797_afe_pcm_dev_remove,
};
module_platform_driver(mt6797_afe_pcm_driver);
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index bc155dd937e0..f93c2ec8beb7 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -1195,14 +1195,13 @@ err_pm_disable:
return ret;
}
-static int mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
+static void mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mt8173_afe_runtime_suspend(&pdev->dev);
- return 0;
}
static const struct of_device_id mt8173_afe_pcm_dt_match[] = {
@@ -1223,7 +1222,7 @@ static struct platform_driver mt8173_afe_pcm_driver = {
.pm = &mt8173_afe_pm_ops,
},
.probe = mt8173_afe_pcm_dev_probe,
- .remove = mt8173_afe_pcm_dev_remove,
+ .remove_new = mt8173_afe_pcm_dev_remove,
};
module_platform_driver(mt8173_afe_pcm_driver);
diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
index 86c8a523fe9e..90422ed2bbcc 100644
--- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
+++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
@@ -1255,13 +1255,11 @@ err_pm_disable:
return ret;
}
-static int mt8183_afe_pcm_dev_remove(struct platform_device *pdev)
+static void mt8183_afe_pcm_dev_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mt8183_afe_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct of_device_id mt8183_afe_pcm_dt_match[] = {
@@ -1282,7 +1280,7 @@ static struct platform_driver mt8183_afe_pcm_driver = {
.pm = &mt8183_afe_pm_ops,
},
.probe = mt8183_afe_pcm_dev_probe,
- .remove = mt8183_afe_pcm_dev_remove,
+ .remove_new = mt8183_afe_pcm_dev_remove,
};
module_platform_driver(mt8183_afe_pcm_driver);
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index e8e84de86542..e5f9373bed56 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -3323,11 +3323,9 @@ err_pm_put:
return ret;
}
-static int mt8188_afe_pcm_dev_remove(struct platform_device *pdev)
+static void mt8188_afe_pcm_dev_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
-
- return 0;
}
static const struct of_device_id mt8188_afe_pcm_dt_match[] = {
@@ -3348,7 +3346,7 @@ static struct platform_driver mt8188_afe_pcm_driver = {
.pm = &mt8188_afe_pm_ops,
},
.probe = mt8188_afe_pcm_dev_probe,
- .remove = mt8188_afe_pcm_dev_remove,
+ .remove_new = mt8188_afe_pcm_dev_remove,
};
module_platform_driver(mt8188_afe_pcm_driver);
diff --git a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
index 333e0ee98c5a..d0520e7e1d79 100644
--- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
+++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
@@ -2349,7 +2349,7 @@ err_pm_disable:
return ret;
}
-static int mt8192_afe_pcm_dev_remove(struct platform_device *pdev)
+static void mt8192_afe_pcm_dev_remove(struct platform_device *pdev)
{
struct mtk_base_afe *afe = platform_get_drvdata(pdev);
@@ -2359,7 +2359,6 @@ static int mt8192_afe_pcm_dev_remove(struct platform_device *pdev)
/* disable afe clock */
mt8192_afe_disable_clock(afe);
- return 0;
}
static const struct of_device_id mt8192_afe_pcm_dt_match[] = {
@@ -2380,7 +2379,7 @@ static struct platform_driver mt8192_afe_pcm_driver = {
.pm = &mt8192_afe_pm_ops,
},
.probe = mt8192_afe_pcm_dev_probe,
- .remove = mt8192_afe_pcm_dev_remove,
+ .remove_new = mt8192_afe_pcm_dev_remove,
};
module_platform_driver(mt8192_afe_pcm_driver);
diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
index 72b2c6d629b9..9e45efeada55 100644
--- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
+++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
@@ -3253,7 +3253,7 @@ err_pm_put:
return ret;
}
-static int mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
+static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
{
struct mtk_base_afe *afe = platform_get_drvdata(pdev);
@@ -3264,7 +3264,6 @@ static int mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
mt8195_afe_runtime_suspend(&pdev->dev);
mt8195_afe_deinit_clock(afe);
- return 0;
}
static const struct of_device_id mt8195_afe_pcm_dt_match[] = {
@@ -3285,7 +3284,7 @@ static struct platform_driver mt8195_afe_pcm_driver = {
.pm = &mt8195_afe_pm_ops,
},
.probe = mt8195_afe_pcm_dev_probe,
- .remove = mt8195_afe_pcm_dev_remove,
+ .remove_new = mt8195_afe_pcm_dev_remove,
};
module_platform_driver(mt8195_afe_pcm_driver);
diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c
index 88e611e64d14..da351a60df0c 100644
--- a/sound/soc/meson/aiu.c
+++ b/sound/soc/meson/aiu.c
@@ -331,11 +331,9 @@ err:
return ret;
}
-static int aiu_remove(struct platform_device *pdev)
+static void aiu_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
-
- return 0;
}
static const struct aiu_platform_data aiu_gxbb_pdata = {
@@ -364,7 +362,7 @@ MODULE_DEVICE_TABLE(of, aiu_of_match);
static struct platform_driver aiu_pdrv = {
.probe = aiu_probe,
- .remove = aiu_remove,
+ .remove_new = aiu_remove,
.driver = {
.name = "meson-aiu",
.of_match_table = aiu_of_match,
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index a55e7256a4c3..457c3a72a414 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -169,11 +169,9 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
return 0;
}
-static int mxs_sgtl5000_remove(struct platform_device *pdev)
+static void mxs_sgtl5000_remove(struct platform_device *pdev)
{
mxs_saif_put_mclk(0);
-
- return 0;
}
static const struct of_device_id mxs_sgtl5000_dt_ids[] = {
@@ -188,7 +186,7 @@ static struct platform_driver mxs_sgtl5000_audio_driver = {
.of_match_table = mxs_sgtl5000_dt_ids,
},
.probe = mxs_sgtl5000_probe,
- .remove = mxs_sgtl5000_remove,
+ .remove_new = mxs_sgtl5000_remove,
};
module_platform_driver(mxs_sgtl5000_audio_driver);
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index b3c1744eff91..a1ed141b8795 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -545,7 +545,7 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev)
return 0;
}
-static int asoc_mmp_sspa_remove(struct platform_device *pdev)
+static void asoc_mmp_sspa_remove(struct platform_device *pdev)
{
struct sspa_priv *sspa = platform_get_drvdata(pdev);
@@ -553,11 +553,10 @@ static int asoc_mmp_sspa_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
if (pdev->dev.of_node)
- return 0;
+ return;
clk_put(sspa->audio_clk);
clk_put(sspa->sysclk);
- return 0;
}
#ifdef CONFIG_OF
@@ -575,7 +574,7 @@ static struct platform_driver asoc_mmp_sspa_driver = {
.of_match_table = of_match_ptr(mmp_sspa_of_match),
},
.probe = asoc_mmp_sspa_probe,
- .remove = asoc_mmp_sspa_remove,
+ .remove_new = asoc_mmp_sspa_remove,
};
module_platform_driver(asoc_mmp_sspa_driver);
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 809ea34736ed..e73bd62c033c 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -263,13 +263,12 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
pxa_ac97_dai_driver, ARRAY_SIZE(pxa_ac97_dai_driver));
}
-static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
+static void pxa2xx_ac97_dev_remove(struct platform_device *pdev)
{
struct ac97_controller *ctrl = platform_get_drvdata(pdev);
snd_ac97_controller_unregister(ctrl);
pxa2xx_ac97_hw_remove(pdev);
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -289,7 +288,7 @@ static SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops,
static struct platform_driver pxa2xx_ac97_driver = {
.probe = pxa2xx_ac97_dev_probe,
- .remove = pxa2xx_ac97_dev_remove,
+ .remove_new = pxa2xx_ac97_dev_remove,
.driver = {
.name = "pxa2xx-ac97",
#ifdef CONFIG_PM_SLEEP
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index 928fd23e2c27..bba07899f8fc 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -1140,12 +1140,10 @@ static int q6pcm_routing_probe(struct platform_device *pdev)
NULL, 0);
}
-static int q6pcm_routing_remove(struct platform_device *pdev)
+static void q6pcm_routing_remove(struct platform_device *pdev)
{
kfree(routing_data);
routing_data = NULL;
-
- return 0;
}
#ifdef CONFIG_OF
@@ -1162,7 +1160,7 @@ static struct platform_driver q6pcm_routing_platform_driver = {
.of_match_table = of_match_ptr(q6pcm_routing_device_id),
},
.probe = q6pcm_routing_probe,
- .remove = q6pcm_routing_remove,
+ .remove_new = q6pcm_routing_remove,
};
module_platform_driver(q6pcm_routing_platform_driver);
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 2e24cc0570eb..575a0b9b01e9 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -851,7 +851,7 @@ err_clk:
return ret;
}
-static int rockchip_i2s_remove(struct platform_device *pdev)
+static void rockchip_i2s_remove(struct platform_device *pdev)
{
struct rk_i2s_dev *i2s = dev_get_drvdata(&pdev->dev);
@@ -860,8 +860,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
i2s_runtime_suspend(&pdev->dev);
clk_disable_unprepare(i2s->hclk);
-
- return 0;
}
static const struct dev_pm_ops rockchip_i2s_pm_ops = {
@@ -871,7 +869,7 @@ static const struct dev_pm_ops rockchip_i2s_pm_ops = {
static struct platform_driver rockchip_i2s_driver = {
.probe = rockchip_i2s_probe,
- .remove = rockchip_i2s_remove,
+ .remove_new = rockchip_i2s_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(rockchip_i2s_match),
diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c
index 6ce92b1db790..52f9aae60be8 100644
--- a/sound/soc/rockchip/rockchip_pdm.c
+++ b/sound/soc/rockchip/rockchip_pdm.c
@@ -661,7 +661,7 @@ err_pm_disable:
return ret;
}
-static int rockchip_pdm_remove(struct platform_device *pdev)
+static void rockchip_pdm_remove(struct platform_device *pdev)
{
struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev);
@@ -671,8 +671,6 @@ static int rockchip_pdm_remove(struct platform_device *pdev)
clk_disable_unprepare(pdm->clk);
clk_disable_unprepare(pdm->hclk);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -710,7 +708,7 @@ static const struct dev_pm_ops rockchip_pdm_pm_ops = {
static struct platform_driver rockchip_pdm_driver = {
.probe = rockchip_pdm_probe,
- .remove = rockchip_pdm_remove,
+ .remove_new = rockchip_pdm_remove,
.driver = {
.name = "rockchip-pdm",
.of_match_table = of_match_ptr(rockchip_pdm_match),
diff --git a/sound/soc/rockchip/rockchip_rt5645.c b/sound/soc/rockchip/rockchip_rt5645.c
index d07cc5c813f2..e73a342b7953 100644
--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -206,14 +206,12 @@ put_codec_of_node:
return ret;
}
-static int snd_rk_mc_remove(struct platform_device *pdev)
+static void snd_rk_mc_remove(struct platform_device *pdev)
{
of_node_put(rk_dailink.cpus->of_node);
rk_dailink.cpus->of_node = NULL;
of_node_put(rk_dailink.codecs->of_node);
rk_dailink.codecs->of_node = NULL;
-
- return 0;
}
static const struct of_device_id rockchip_rt5645_of_match[] = {
@@ -225,7 +223,7 @@ MODULE_DEVICE_TABLE(of, rockchip_rt5645_of_match);
static struct platform_driver snd_rk_mc_driver = {
.probe = snd_rk_mc_probe,
- .remove = snd_rk_mc_remove,
+ .remove_new = snd_rk_mc_remove,
.driver = {
.name = DRV_NAME,
.pm = &snd_soc_pm_ops,
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
index 2d937fcf357d..0b73fe94e4bb 100644
--- a/sound/soc/rockchip/rockchip_spdif.c
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -367,13 +367,11 @@ err_pm_runtime:
return ret;
}
-static int rk_spdif_remove(struct platform_device *pdev)
+static void rk_spdif_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
rk_spdif_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops rk_spdif_pm_ops = {
@@ -383,7 +381,7 @@ static const struct dev_pm_ops rk_spdif_pm_ops = {
static struct platform_driver rk_spdif_driver = {
.probe = rk_spdif_probe,
- .remove = rk_spdif_remove,
+ .remove_new = rk_spdif_remove,
.driver = {
.name = "rockchip-spdif",
.of_match_table = of_match_ptr(rk_spdif_match),
diff --git a/sound/soc/samsung/arndale.c b/sound/soc/samsung/arndale.c
index a5dc640d0d76..fdff83e72d29 100644
--- a/sound/soc/samsung/arndale.c
+++ b/sound/soc/samsung/arndale.c
@@ -185,12 +185,11 @@ err_put_of_nodes:
return ret;
}
-static int arndale_audio_remove(struct platform_device *pdev)
+static void arndale_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
arndale_put_of_nodes(card);
- return 0;
}
static const struct of_device_id arndale_audio_of_match[] = {
@@ -208,7 +207,7 @@ static struct platform_driver arndale_audio_driver = {
.of_match_table = arndale_audio_of_match,
},
.probe = arndale_audio_probe,
- .remove = arndale_audio_remove,
+ .remove_new = arndale_audio_remove,
};
module_platform_driver(arndale_audio_driver);
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 083e278aa021..f3d98abd5f0d 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1560,13 +1560,13 @@ err_disable_clk:
return ret;
}
-static int samsung_i2s_remove(struct platform_device *pdev)
+static void samsung_i2s_remove(struct platform_device *pdev)
{
struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
/* The secondary device has no driver data assigned */
if (!priv)
- return 0;
+ return;
pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
@@ -1576,8 +1576,6 @@ static int samsung_i2s_remove(struct platform_device *pdev)
clk_disable_unprepare(priv->clk);
pm_runtime_put_noidle(&pdev->dev);
-
- return 0;
}
static void fsd_i2s_fixup_early(struct snd_pcm_substream *substream,
@@ -1746,7 +1744,7 @@ static const struct dev_pm_ops samsung_i2s_pm = {
static struct platform_driver samsung_i2s_driver = {
.probe = samsung_i2s_probe,
- .remove = samsung_i2s_remove,
+ .remove_new = samsung_i2s_remove,
.id_table = samsung_i2s_driver_ids,
.driver = {
.name = "samsung-i2s",
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
index 1e0fefa89ad5..fd95a79cc9fa 100644
--- a/sound/soc/samsung/odroid.c
+++ b/sound/soc/samsung/odroid.c
@@ -331,15 +331,13 @@ err_put_node:
return ret;
}
-static int odroid_audio_remove(struct platform_device *pdev)
+static void odroid_audio_remove(struct platform_device *pdev)
{
struct odroid_priv *priv = platform_get_drvdata(pdev);
snd_soc_of_put_dai_link_codecs(&priv->card.dai_link[1]);
clk_put(priv->sclk_i2s);
clk_put(priv->clk_i2s_bus);
-
- return 0;
}
static const struct of_device_id odroid_audio_of_match[] = {
@@ -358,7 +356,7 @@ static struct platform_driver odroid_audio_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = odroid_audio_probe,
- .remove = odroid_audio_remove,
+ .remove_new = odroid_audio_remove,
};
module_platform_driver(odroid_audio_driver);
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index e859252ae5e6..335fe5cb9cfc 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -579,20 +579,18 @@ err_dis_cclk:
return ret;
}
-static int s3c_pcm_dev_remove(struct platform_device *pdev)
+static void s3c_pcm_dev_remove(struct platform_device *pdev)
{
struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(pcm->cclk);
clk_disable_unprepare(pcm->pclk);
-
- return 0;
}
static struct platform_driver s3c_pcm_driver = {
.probe = s3c_pcm_dev_probe,
- .remove = s3c_pcm_dev_remove,
+ .remove_new = s3c_pcm_dev_remove,
.driver = {
.name = "samsung-pcm",
},
diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c
index da342da03880..334080e631af 100644
--- a/sound/soc/samsung/snow.c
+++ b/sound/soc/samsung/snow.c
@@ -219,7 +219,7 @@ static int snow_probe(struct platform_device *pdev)
return 0;
}
-static int snow_remove(struct platform_device *pdev)
+static void snow_remove(struct platform_device *pdev)
{
struct snow_priv *priv = platform_get_drvdata(pdev);
struct snd_soc_dai_link *link = &priv->dai_link;
@@ -229,8 +229,6 @@ static int snow_remove(struct platform_device *pdev)
snd_soc_of_put_dai_link_codecs(link);
clk_put(priv->clk_i2s_bus);
-
- return 0;
}
static const struct of_device_id snow_of_match[] = {
@@ -248,7 +246,7 @@ static struct platform_driver snow_driver = {
.of_match_table = snow_of_match,
},
.probe = snow_probe,
- .remove = snow_remove,
+ .remove_new = snow_remove,
};
module_platform_driver(snow_driver);
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 7d815e237e5c..28dc1bbfc8e7 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -460,7 +460,7 @@ err0:
return ret;
}
-static int spdif_remove(struct platform_device *pdev)
+static void spdif_remove(struct platform_device *pdev)
{
struct samsung_spdif_info *spdif = &spdif_info;
struct resource *mem_res;
@@ -472,13 +472,11 @@ static int spdif_remove(struct platform_device *pdev)
clk_disable_unprepare(spdif->sclk);
clk_disable_unprepare(spdif->pclk);
-
- return 0;
}
static struct platform_driver samsung_spdif_driver = {
.probe = spdif_probe,
- .remove = spdif_remove,
+ .remove_new = spdif_remove,
.driver = {
.name = "samsung-spdif",
},
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 9f3f1af6349f..1051c306292f 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -2030,7 +2030,7 @@ exit_fsia:
return ret;
}
-static int fsi_remove(struct platform_device *pdev)
+static void fsi_remove(struct platform_device *pdev)
{
struct fsi_master *master;
@@ -2040,8 +2040,6 @@ static int fsi_remove(struct platform_device *pdev)
fsi_stream_remove(&master->fsia);
fsi_stream_remove(&master->fsib);
-
- return 0;
}
static void __fsi_suspend(struct fsi_priv *fsi,
@@ -2108,7 +2106,7 @@ static struct platform_driver fsi_driver = {
.of_match_table = fsi_of_match,
},
.probe = fsi_probe,
- .remove = fsi_remove,
+ .remove_new = fsi_remove,
.id_table = fsi_id_table,
};
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index 46d145cbaf29..cc200f45826c 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -323,10 +323,9 @@ static int hac_soc_platform_probe(struct platform_device *pdev)
sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
}
-static int hac_soc_platform_remove(struct platform_device *pdev)
+static void hac_soc_platform_remove(struct platform_device *pdev)
{
snd_soc_set_ac97_ops(NULL);
- return 0;
}
static struct platform_driver hac_pcm_driver = {
@@ -335,7 +334,7 @@ static struct platform_driver hac_pcm_driver = {
},
.probe = hac_soc_platform_probe,
- .remove = hac_soc_platform_remove,
+ .remove_new = hac_soc_platform_remove,
};
module_platform_driver(hac_pcm_driver);
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index cb17f7d0cf0c..6a522e6dd85a 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1987,7 +1987,7 @@ exit_snd_probe:
return ret;
}
-static int rsnd_remove(struct platform_device *pdev)
+static void rsnd_remove(struct platform_device *pdev)
{
struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
struct rsnd_dai *rdai;
@@ -2019,8 +2019,6 @@ static int rsnd_remove(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(remove_func); i++)
remove_func[i](priv);
-
- return 0;
}
static int __maybe_unused rsnd_suspend(struct device *dev)
@@ -2052,7 +2050,7 @@ static struct platform_driver rsnd_driver = {
.of_match_table = rsnd_of_match,
},
.probe = rsnd_probe,
- .remove = rsnd_remove,
+ .remove_new = rsnd_remove,
};
module_platform_driver(rsnd_driver);
diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index d502aa55c5a8..fe79eb90e1e5 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -1075,7 +1075,7 @@ err_reset:
return ret;
}
-static int rz_ssi_remove(struct platform_device *pdev)
+static void rz_ssi_remove(struct platform_device *pdev)
{
struct rz_ssi_priv *ssi = dev_get_drvdata(&pdev->dev);
@@ -1084,8 +1084,6 @@ static int rz_ssi_remove(struct platform_device *pdev)
pm_runtime_put(ssi->dev);
pm_runtime_disable(ssi->dev);
reset_control_assert(ssi->rstc);
-
- return 0;
}
static const struct of_device_id rz_ssi_of_match[] = {
@@ -1100,7 +1098,7 @@ static struct platform_driver rz_ssi_driver = {
.of_match_table = rz_ssi_of_match,
},
.probe = rz_ssi_probe,
- .remove = rz_ssi_remove,
+ .remove_new = rz_ssi_remove,
};
module_platform_driver(rz_ssi_driver);
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index f2a386fcd92e..84e1b14e68e4 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -778,10 +778,9 @@ static int siu_probe(struct platform_device *pdev)
return 0;
}
-static int siu_remove(struct platform_device *pdev)
+static void siu_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static struct platform_driver siu_driver = {
@@ -789,7 +788,7 @@ static struct platform_driver siu_driver = {
.name = "siu-pcm-audio",
},
.probe = siu_probe,
- .remove = siu_remove,
+ .remove_new = siu_remove,
};
module_platform_driver(siu_driver);
diff --git a/sound/soc/sof/ipc4-control.c b/sound/soc/sof/ipc4-control.c
index d26ed2a6029f..6f0698be9451 100644
--- a/sound/soc/sof/ipc4-control.c
+++ b/sound/soc/sof/ipc4-control.c
@@ -429,14 +429,17 @@ static int sof_ipc4_widget_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_s
default:
break;
}
+
+ if (ret < 0) {
+ dev_err(sdev->dev,
+ "kcontrol %d set up failed for widget %s\n",
+ scontrol->comp_id, swidget->widget->name);
+ return ret;
+ }
}
}
- if (ret < 0)
- dev_err(sdev->dev, "kcontrol %d set up failed for widget %s\n",
- scontrol->comp_id, swidget->widget->name);
-
- return ret;
+ return 0;
}
static int
diff --git a/sound/soc/sprd/sprd-mcdt.c b/sound/soc/sprd/sprd-mcdt.c
index f6a55fa60c1b..688419c6b092 100644
--- a/sound/soc/sprd/sprd-mcdt.c
+++ b/sound/soc/sprd/sprd-mcdt.c
@@ -973,7 +973,7 @@ static int sprd_mcdt_probe(struct platform_device *pdev)
return 0;
}
-static int sprd_mcdt_remove(struct platform_device *pdev)
+static void sprd_mcdt_remove(struct platform_device *pdev)
{
struct sprd_mcdt_chan *chan, *temp;
@@ -983,8 +983,6 @@ static int sprd_mcdt_remove(struct platform_device *pdev)
list_del(&chan->list);
mutex_unlock(&sprd_mcdt_list_mutex);
-
- return 0;
}
static const struct of_device_id sprd_mcdt_of_match[] = {
@@ -995,7 +993,7 @@ MODULE_DEVICE_TABLE(of, sprd_mcdt_of_match);
static struct platform_driver sprd_mcdt_driver = {
.probe = sprd_mcdt_probe,
- .remove = sprd_mcdt_remove,
+ .remove_new = sprd_mcdt_remove,
.driver = {
.name = "sprd-mcdt",
.of_match_table = sprd_mcdt_of_match,
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
index 837c1848d9bf..a8fff7378641 100644
--- a/sound/soc/stm/stm32_adfsdm.c
+++ b/sound/soc/stm/stm32_adfsdm.c
@@ -386,12 +386,10 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
return ret;
}
-static int stm32_adfsdm_remove(struct platform_device *pdev)
+static void stm32_adfsdm_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static struct platform_driver stm32_adfsdm_driver = {
@@ -400,7 +398,7 @@ static struct platform_driver stm32_adfsdm_driver = {
.of_match_table = stm32_adfsdm_of_match,
},
.probe = stm32_adfsdm_probe,
- .remove = stm32_adfsdm_remove,
+ .remove_new = stm32_adfsdm_remove,
};
module_platform_driver(stm32_adfsdm_driver);
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index 9dad85ecb93f..387130701960 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -1097,13 +1097,11 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
return 0;
}
-static int stm32_i2s_remove(struct platform_device *pdev)
+static void stm32_i2s_remove(struct platform_device *pdev)
{
snd_dmaengine_pcm_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static int stm32_i2s_probe(struct platform_device *pdev)
@@ -1221,7 +1219,7 @@ static struct platform_driver stm32_i2s_driver = {
.pm = &stm32_i2s_pm_ops,
},
.probe = stm32_i2s_probe,
- .remove = stm32_i2s_remove,
+ .remove_new = stm32_i2s_remove,
};
module_platform_driver(stm32_i2s_driver);
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 8ba4206f751d..f6695dee353b 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -1559,7 +1559,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
return 0;
}
-static int stm32_sai_sub_remove(struct platform_device *pdev)
+static void stm32_sai_sub_remove(struct platform_device *pdev)
{
struct stm32_sai_sub_data *sai = dev_get_drvdata(&pdev->dev);
@@ -1567,8 +1567,6 @@ static int stm32_sai_sub_remove(struct platform_device *pdev)
snd_dmaengine_pcm_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -1618,7 +1616,7 @@ static struct platform_driver stm32_sai_sub_driver = {
.pm = &stm32_sai_sub_pm_ops,
},
.probe = stm32_sai_sub_probe,
- .remove = stm32_sai_sub_remove,
+ .remove_new = stm32_sai_sub_remove,
};
module_platform_driver(stm32_sai_sub_driver);
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index d399c906bb92..a4066f271f2d 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -939,7 +939,7 @@ static int stm32_spdifrx_parse_of(struct platform_device *pdev,
return 0;
}
-static int stm32_spdifrx_remove(struct platform_device *pdev)
+static void stm32_spdifrx_remove(struct platform_device *pdev)
{
struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev);
@@ -952,8 +952,6 @@ static int stm32_spdifrx_remove(struct platform_device *pdev)
snd_dmaengine_pcm_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static int stm32_spdifrx_probe(struct platform_device *pdev)
@@ -1078,7 +1076,7 @@ static struct platform_driver stm32_spdifrx_driver = {
.pm = &stm32_spdifrx_pm_ops,
},
.probe = stm32_spdifrx_probe,
- .remove = stm32_spdifrx_remove,
+ .remove_new = stm32_spdifrx_remove,
};
module_platform_driver(stm32_spdifrx_driver);
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 835dc3404367..55328850aef5 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -1821,7 +1821,7 @@ err_clk_disable:
return ret;
}
-static int sun4i_codec_remove(struct platform_device *pdev)
+static void sun4i_codec_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
@@ -1830,8 +1830,6 @@ static int sun4i_codec_remove(struct platform_device *pdev)
if (scodec->rst)
reset_control_assert(scodec->rst);
clk_disable_unprepare(scodec->clk_apb);
-
- return 0;
}
static struct platform_driver sun4i_codec_driver = {
@@ -1840,7 +1838,7 @@ static struct platform_driver sun4i_codec_driver = {
.of_match_table = sun4i_codec_of_match,
},
.probe = sun4i_codec_probe,
- .remove = sun4i_codec_remove,
+ .remove_new = sun4i_codec_remove,
};
module_platform_driver(sun4i_codec_driver);
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 6028871825ba..669d712bbe9f 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -1606,7 +1606,7 @@ err_pm_disable:
return ret;
}
-static int sun4i_i2s_remove(struct platform_device *pdev)
+static void sun4i_i2s_remove(struct platform_device *pdev)
{
struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
@@ -1616,8 +1616,6 @@ static int sun4i_i2s_remove(struct platform_device *pdev)
if (!IS_ERR(i2s->rst))
reset_control_assert(i2s->rst);
-
- return 0;
}
static const struct of_device_id sun4i_i2s_match[] = {
@@ -1660,7 +1658,7 @@ static const struct dev_pm_ops sun4i_i2s_pm_ops = {
static struct platform_driver sun4i_i2s_driver = {
.probe = sun4i_i2s_probe,
- .remove = sun4i_i2s_remove,
+ .remove_new = sun4i_i2s_remove,
.driver = {
.name = "sun4i-i2s",
.of_match_table = sun4i_i2s_match,
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index bcceebca915a..ff18d4113aac 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -703,13 +703,11 @@ err_unregister:
return ret;
}
-static int sun4i_spdif_remove(struct platform_device *pdev)
+static void sun4i_spdif_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
sun4i_spdif_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops sun4i_spdif_pm = {
@@ -724,7 +722,7 @@ static struct platform_driver sun4i_spdif_driver = {
.pm = &sun4i_spdif_pm,
},
.probe = sun4i_spdif_probe,
- .remove = sun4i_spdif_remove,
+ .remove_new = sun4i_spdif_remove,
};
module_platform_driver(sun4i_spdif_driver);
diff --git a/sound/soc/sunxi/sun50i-dmic.c b/sound/soc/sunxi/sun50i-dmic.c
index 069c993acb31..c10439b9e0a2 100644
--- a/sound/soc/sunxi/sun50i-dmic.c
+++ b/sound/soc/sunxi/sun50i-dmic.c
@@ -373,13 +373,11 @@ err_disable_runtime_pm:
return ret;
}
-static int sun50i_dmic_remove(struct platform_device *pdev)
+static void sun50i_dmic_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
sun50i_dmic_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops sun50i_dmic_pm = {
@@ -394,7 +392,7 @@ static struct platform_driver sun50i_dmic_driver = {
.pm = &sun50i_dmic_pm,
},
.probe = sun50i_dmic_probe,
- .remove = sun50i_dmic_remove,
+ .remove_new = sun50i_dmic_remove,
};
module_platform_driver(sun50i_dmic_driver);
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 9844978d91e6..4c0d0d7d3e58 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -1349,13 +1349,11 @@ err_pm_disable:
return ret;
}
-static int sun8i_codec_remove(struct platform_device *pdev)
+static void sun8i_codec_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
sun8i_codec_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct sun8i_codec_quirks sun8i_a33_quirks = {
@@ -1385,7 +1383,7 @@ static struct platform_driver sun8i_codec_driver = {
.pm = &sun8i_codec_pm_ops,
},
.probe = sun8i_codec_probe,
- .remove = sun8i_codec_remove,
+ .remove_new = sun8i_codec_remove,
};
module_platform_driver(sun8i_codec_driver);
diff --git a/sound/soc/tegra/tegra186_asrc.c b/sound/soc/tegra/tegra186_asrc.c
index 9f12faaa609d..e016a6a7f7c4 100644
--- a/sound/soc/tegra/tegra186_asrc.c
+++ b/sound/soc/tegra/tegra186_asrc.c
@@ -1016,11 +1016,9 @@ static int tegra186_asrc_platform_probe(struct platform_device *pdev)
return 0;
}
-static int tegra186_asrc_platform_remove(struct platform_device *pdev)
+static void tegra186_asrc_platform_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra186_asrc_pm_ops = {
@@ -1037,7 +1035,7 @@ static struct platform_driver tegra186_asrc_driver = {
.pm = &tegra186_asrc_pm_ops,
},
.probe = tegra186_asrc_platform_probe,
- .remove = tegra186_asrc_platform_remove,
+ .remove_new = tegra186_asrc_platform_remove,
};
module_platform_driver(tegra186_asrc_driver)
diff --git a/sound/soc/tegra/tegra186_dspk.c b/sound/soc/tegra/tegra186_dspk.c
index a74c980ee775..a0ce7eb11de9 100644
--- a/sound/soc/tegra/tegra186_dspk.c
+++ b/sound/soc/tegra/tegra186_dspk.c
@@ -524,11 +524,9 @@ static int tegra186_dspk_platform_probe(struct platform_device *pdev)
return 0;
}
-static int tegra186_dspk_platform_remove(struct platform_device *pdev)
+static void tegra186_dspk_platform_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra186_dspk_pm_ops = {
@@ -545,7 +543,7 @@ static struct platform_driver tegra186_dspk_driver = {
.pm = &tegra186_dspk_pm_ops,
},
.probe = tegra186_dspk_platform_probe,
- .remove = tegra186_dspk_platform_remove,
+ .remove_new = tegra186_dspk_platform_remove,
};
module_platform_driver(tegra186_dspk_driver);
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index d23d88a10899..fea6955f7f43 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -429,7 +429,7 @@ err:
return ret;
}
-static int tegra20_ac97_platform_remove(struct platform_device *pdev)
+static void tegra20_ac97_platform_remove(struct platform_device *pdev)
{
struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev);
@@ -439,8 +439,6 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)
clk_disable_unprepare(ac97->clk_ac97);
snd_soc_set_ac97_ops(NULL);
-
- return 0;
}
static const struct of_device_id tegra20_ac97_of_match[] = {
@@ -454,7 +452,7 @@ static struct platform_driver tegra20_ac97_driver = {
.of_match_table = tegra20_ac97_of_match,
},
.probe = tegra20_ac97_platform_probe,
- .remove = tegra20_ac97_platform_remove,
+ .remove_new = tegra20_ac97_platform_remove,
};
module_platform_driver(tegra20_ac97_driver);
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index d37a9f2603e8..e1a0f50969c1 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -475,13 +475,11 @@ err:
return ret;
}
-static int tegra20_i2s_platform_remove(struct platform_device *pdev)
+static void tegra20_i2s_platform_remove(struct platform_device *pdev)
{
tegra_pcm_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct of_device_id tegra20_i2s_of_match[] = {
@@ -503,7 +501,7 @@ static struct platform_driver tegra20_i2s_driver = {
.pm = &tegra20_i2s_pm_ops,
},
.probe = tegra20_i2s_platform_probe,
- .remove = tegra20_i2s_platform_remove,
+ .remove_new = tegra20_i2s_platform_remove,
};
module_platform_driver(tegra20_i2s_driver);
diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c
index 100a2b6e6063..6868508585a0 100644
--- a/sound/soc/tegra/tegra210_admaif.c
+++ b/sound/soc/tegra/tegra210_admaif.c
@@ -842,11 +842,9 @@ static int tegra_admaif_probe(struct platform_device *pdev)
return 0;
}
-static int tegra_admaif_remove(struct platform_device *pdev)
+static void tegra_admaif_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra_admaif_pm_ops = {
@@ -858,7 +856,7 @@ static const struct dev_pm_ops tegra_admaif_pm_ops = {
static struct platform_driver tegra_admaif_driver = {
.probe = tegra_admaif_probe,
- .remove = tegra_admaif_remove,
+ .remove_new = tegra_admaif_remove,
.driver = {
.name = "tegra210-admaif",
.of_match_table = tegra_admaif_of_match,
diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c
index 49691d2cce50..41117c1d61fb 100644
--- a/sound/soc/tegra/tegra210_adx.c
+++ b/sound/soc/tegra/tegra210_adx.c
@@ -504,11 +504,9 @@ static int tegra210_adx_platform_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_adx_platform_remove(struct platform_device *pdev)
+static void tegra210_adx_platform_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra210_adx_pm_ops = {
@@ -525,7 +523,7 @@ static struct platform_driver tegra210_adx_driver = {
.pm = &tegra210_adx_pm_ops,
},
.probe = tegra210_adx_platform_probe,
- .remove = tegra210_adx_platform_remove,
+ .remove_new = tegra210_adx_platform_remove,
};
module_platform_driver(tegra210_adx_driver);
diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c
index b38d205b69cc..8c00c09eeefb 100644
--- a/sound/soc/tegra/tegra210_ahub.c
+++ b/sound/soc/tegra/tegra210_ahub.c
@@ -1410,11 +1410,9 @@ static int tegra_ahub_probe(struct platform_device *pdev)
return 0;
}
-static int tegra_ahub_remove(struct platform_device *pdev)
+static void tegra_ahub_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra_ahub_pm_ops = {
@@ -1426,7 +1424,7 @@ static const struct dev_pm_ops tegra_ahub_pm_ops = {
static struct platform_driver tegra_ahub_driver = {
.probe = tegra_ahub_probe,
- .remove = tegra_ahub_remove,
+ .remove_new = tegra_ahub_remove,
.driver = {
.name = "tegra210-ahub",
.of_match_table = tegra_ahub_of_match,
diff --git a/sound/soc/tegra/tegra210_amx.c b/sound/soc/tegra/tegra210_amx.c
index d064cc67fea6..782a141b65c0 100644
--- a/sound/soc/tegra/tegra210_amx.c
+++ b/sound/soc/tegra/tegra210_amx.c
@@ -573,11 +573,9 @@ static int tegra210_amx_platform_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_amx_platform_remove(struct platform_device *pdev)
+static void tegra210_amx_platform_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra210_amx_pm_ops = {
@@ -594,7 +592,7 @@ static struct platform_driver tegra210_amx_driver = {
.pm = &tegra210_amx_pm_ops,
},
.probe = tegra210_amx_platform_probe,
- .remove = tegra210_amx_platform_remove,
+ .remove_new = tegra210_amx_platform_remove,
};
module_platform_driver(tegra210_amx_driver);
diff --git a/sound/soc/tegra/tegra210_dmic.c b/sound/soc/tegra/tegra210_dmic.c
index db95794530f4..763b206cd52b 100644
--- a/sound/soc/tegra/tegra210_dmic.c
+++ b/sound/soc/tegra/tegra210_dmic.c
@@ -534,11 +534,9 @@ static int tegra210_dmic_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_dmic_remove(struct platform_device *pdev)
+static void tegra210_dmic_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra210_dmic_pm_ops = {
@@ -561,7 +559,7 @@ static struct platform_driver tegra210_dmic_driver = {
.pm = &tegra210_dmic_pm_ops,
},
.probe = tegra210_dmic_probe,
- .remove = tegra210_dmic_remove,
+ .remove_new = tegra210_dmic_remove,
};
module_platform_driver(tegra210_dmic_driver)
diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c
index 39ffa4d76b59..21724cd3525e 100644
--- a/sound/soc/tegra/tegra210_i2s.c
+++ b/sound/soc/tegra/tegra210_i2s.c
@@ -931,11 +931,9 @@ static int tegra210_i2s_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_i2s_remove(struct platform_device *pdev)
+static void tegra210_i2s_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra210_i2s_pm_ops = {
@@ -958,7 +956,7 @@ static struct platform_driver tegra210_i2s_driver = {
.pm = &tegra210_i2s_pm_ops,
},
.probe = tegra210_i2s_probe,
- .remove = tegra210_i2s_remove,
+ .remove_new = tegra210_i2s_remove,
};
module_platform_driver(tegra210_i2s_driver)
diff --git a/sound/soc/tegra/tegra210_mixer.c b/sound/soc/tegra/tegra210_mixer.c
index 16e679a95658..035e9035b533 100644
--- a/sound/soc/tegra/tegra210_mixer.c
+++ b/sound/soc/tegra/tegra210_mixer.c
@@ -656,11 +656,9 @@ static int tegra210_mixer_platform_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_mixer_platform_remove(struct platform_device *pdev)
+static void tegra210_mixer_platform_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra210_mixer_pm_ops = {
@@ -677,7 +675,7 @@ static struct platform_driver tegra210_mixer_driver = {
.pm = &tegra210_mixer_pm_ops,
},
.probe = tegra210_mixer_platform_probe,
- .remove = tegra210_mixer_platform_remove,
+ .remove_new = tegra210_mixer_platform_remove,
};
module_platform_driver(tegra210_mixer_driver);
diff --git a/sound/soc/tegra/tegra210_mvc.c b/sound/soc/tegra/tegra210_mvc.c
index 725385e17d84..44f465e11bee 100644
--- a/sound/soc/tegra/tegra210_mvc.c
+++ b/sound/soc/tegra/tegra210_mvc.c
@@ -748,11 +748,9 @@ static int tegra210_mvc_platform_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_mvc_platform_remove(struct platform_device *pdev)
+static void tegra210_mvc_platform_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra210_mvc_pm_ops = {
@@ -769,7 +767,7 @@ static struct platform_driver tegra210_mvc_driver = {
.pm = &tegra210_mvc_pm_ops,
},
.probe = tegra210_mvc_platform_probe,
- .remove = tegra210_mvc_platform_remove,
+ .remove_new = tegra210_mvc_platform_remove,
};
module_platform_driver(tegra210_mvc_driver)
diff --git a/sound/soc/tegra/tegra210_ope.c b/sound/soc/tegra/tegra210_ope.c
index 3dd2bdec657b..98e726432615 100644
--- a/sound/soc/tegra/tegra210_ope.c
+++ b/sound/soc/tegra/tegra210_ope.c
@@ -347,11 +347,9 @@ static int tegra210_ope_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_ope_remove(struct platform_device *pdev)
+static void tegra210_ope_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static int __maybe_unused tegra210_ope_runtime_suspend(struct device *dev)
@@ -410,7 +408,7 @@ static struct platform_driver tegra210_ope_driver = {
.pm = &tegra210_ope_pm_ops,
},
.probe = tegra210_ope_probe,
- .remove = tegra210_ope_remove,
+ .remove_new = tegra210_ope_remove,
};
module_platform_driver(tegra210_ope_driver)
diff --git a/sound/soc/tegra/tegra210_sfc.c b/sound/soc/tegra/tegra210_sfc.c
index 368f077e7bee..e9df1ffc8a58 100644
--- a/sound/soc/tegra/tegra210_sfc.c
+++ b/sound/soc/tegra/tegra210_sfc.c
@@ -3584,11 +3584,9 @@ static int tegra210_sfc_platform_probe(struct platform_device *pdev)
return 0;
}
-static int tegra210_sfc_platform_remove(struct platform_device *pdev)
+static void tegra210_sfc_platform_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra210_sfc_pm_ops = {
@@ -3605,7 +3603,7 @@ static struct platform_driver tegra210_sfc_driver = {
.pm = &tegra210_sfc_pm_ops,
},
.probe = tegra210_sfc_platform_probe,
- .remove = tegra210_sfc_platform_remove,
+ .remove_new = tegra210_sfc_platform_remove,
};
module_platform_driver(tegra210_sfc_driver)
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index ef011a488ceb..d2e8078e444a 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -592,13 +592,11 @@ err_unset_ahub:
return ret;
}
-static int tegra30_ahub_remove(struct platform_device *pdev)
+static void tegra30_ahub_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
ahub = NULL;
-
- return 0;
}
static const struct dev_pm_ops tegra30_ahub_pm_ops = {
@@ -610,7 +608,7 @@ static const struct dev_pm_ops tegra30_ahub_pm_ops = {
static struct platform_driver tegra30_ahub_driver = {
.probe = tegra30_ahub_probe,
- .remove = tegra30_ahub_remove,
+ .remove_new = tegra30_ahub_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = tegra30_ahub_of_match,
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index c26f960c6afd..644280603095 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -531,7 +531,7 @@ err:
return ret;
}
-static int tegra30_i2s_platform_remove(struct platform_device *pdev)
+static void tegra30_i2s_platform_remove(struct platform_device *pdev)
{
struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev);
@@ -545,8 +545,6 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static const struct dev_pm_ops tegra30_i2s_pm_ops = {
@@ -563,7 +561,7 @@ static struct platform_driver tegra30_i2s_driver = {
.pm = &tegra30_i2s_pm_ops,
},
.probe = tegra30_i2s_platform_probe,
- .remove = tegra30_i2s_platform_remove,
+ .remove_new = tegra30_i2s_platform_remove,
};
module_platform_driver(tegra30_i2s_driver);
diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c
index 438e2fa843a0..1028b5efcfff 100644
--- a/sound/soc/ti/ams-delta.c
+++ b/sound/soc/ti/ams-delta.c
@@ -578,7 +578,7 @@ static int ams_delta_probe(struct platform_device *pdev)
return 0;
}
-static int ams_delta_remove(struct platform_device *pdev)
+static void ams_delta_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
@@ -586,7 +586,6 @@ static int ams_delta_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
card->dev = NULL;
- return 0;
}
#define DRV_NAME "ams-delta-audio"
@@ -596,7 +595,7 @@ static struct platform_driver ams_delta_driver = {
.name = DRV_NAME,
},
.probe = ams_delta_probe,
- .remove = ams_delta_remove,
+ .remove_new = ams_delta_remove,
};
module_platform_driver(ams_delta_driver);
diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c
index 3ccd0cfca008..97dd1634b6be 100644
--- a/sound/soc/ti/davinci-i2s.c
+++ b/sound/soc/ti/davinci-i2s.c
@@ -739,7 +739,7 @@ err_put_clk:
return ret;
}
-static int davinci_i2s_remove(struct platform_device *pdev)
+static void davinci_i2s_remove(struct platform_device *pdev)
{
struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
@@ -748,8 +748,6 @@ static int davinci_i2s_remove(struct platform_device *pdev)
clk_disable(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
-
- return 0;
}
static const struct of_device_id davinci_i2s_match[] __maybe_unused = {
@@ -760,7 +758,7 @@ MODULE_DEVICE_TABLE(of, davinci_i2s_match);
static struct platform_driver davinci_mcbsp_driver = {
.probe = davinci_i2s_probe,
- .remove = davinci_i2s_remove,
+ .remove_new = davinci_i2s_remove,
.driver = {
.name = "davinci-mcbsp",
.of_match_table = of_match_ptr(davinci_i2s_match),
diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c
index 578254549d2d..c0892be2992b 100644
--- a/sound/soc/ti/davinci-mcasp.c
+++ b/sound/soc/ti/davinci-mcasp.c
@@ -2461,11 +2461,9 @@ err:
return ret;
}
-static int davinci_mcasp_remove(struct platform_device *pdev)
+static void davinci_mcasp_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -2531,7 +2529,7 @@ static const struct dev_pm_ops davinci_mcasp_pm_ops = {
static struct platform_driver davinci_mcasp_driver = {
.probe = davinci_mcasp_probe,
- .remove = davinci_mcasp_remove,
+ .remove_new = davinci_mcasp_remove,
.driver = {
.name = "davinci-mcasp",
.pm = &davinci_mcasp_pm_ops,
diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c
index 0dc0475670ff..ad37785e05d8 100644
--- a/sound/soc/ti/omap-hdmi.c
+++ b/sound/soc/ti/omap-hdmi.c
@@ -398,12 +398,11 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
return 0;
}
-static int omap_hdmi_audio_remove(struct platform_device *pdev)
+static void omap_hdmi_audio_remove(struct platform_device *pdev)
{
struct hdmi_audio_data *ad = platform_get_drvdata(pdev);
snd_soc_unregister_card(ad->card);
- return 0;
}
static struct platform_driver hdmi_audio_driver = {
@@ -411,7 +410,7 @@ static struct platform_driver hdmi_audio_driver = {
.name = DRV_NAME,
},
.probe = omap_hdmi_audio_probe,
- .remove = omap_hdmi_audio_remove,
+ .remove_new = omap_hdmi_audio_remove,
};
module_platform_driver(hdmi_audio_driver);
diff --git a/sound/soc/ti/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c
index 7c539a41a6a3..21fa7b978799 100644
--- a/sound/soc/ti/omap-mcbsp.c
+++ b/sound/soc/ti/omap-mcbsp.c
@@ -1412,7 +1412,7 @@ static int asoc_mcbsp_probe(struct platform_device *pdev)
return sdma_pcm_platform_register(&pdev->dev, "tx", "rx");
}
-static int asoc_mcbsp_remove(struct platform_device *pdev)
+static void asoc_mcbsp_remove(struct platform_device *pdev)
{
struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
@@ -1421,8 +1421,6 @@ static int asoc_mcbsp_remove(struct platform_device *pdev)
if (cpu_latency_qos_request_active(&mcbsp->pm_qos_req))
cpu_latency_qos_remove_request(&mcbsp->pm_qos_req);
-
- return 0;
}
static struct platform_driver asoc_mcbsp_driver = {
@@ -1432,7 +1430,7 @@ static struct platform_driver asoc_mcbsp_driver = {
},
.probe = asoc_mcbsp_probe,
- .remove = asoc_mcbsp_remove,
+ .remove_new = asoc_mcbsp_remove,
};
module_platform_driver(asoc_mcbsp_driver);
diff --git a/sound/soc/uniphier/evea.c b/sound/soc/uniphier/evea.c
index 42403ae8e31b..d90b3e4b0104 100644
--- a/sound/soc/uniphier/evea.c
+++ b/sound/soc/uniphier/evea.c
@@ -536,7 +536,7 @@ err_out_clock:
return ret;
}
-static int evea_remove(struct platform_device *pdev)
+static void evea_remove(struct platform_device *pdev)
{
struct evea_priv *evea = platform_get_drvdata(pdev);
@@ -546,8 +546,6 @@ static int evea_remove(struct platform_device *pdev)
clk_disable_unprepare(evea->clk_exiv);
clk_disable_unprepare(evea->clk);
-
- return 0;
}
static const struct of_device_id evea_of_match[] __maybe_unused = {
@@ -562,7 +560,7 @@ static struct platform_driver evea_codec_driver = {
.of_match_table = of_match_ptr(evea_of_match),
},
.probe = evea_probe,
- .remove = evea_remove,
+ .remove_new = evea_remove,
};
module_platform_driver(evea_codec_driver);
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 325e75e96136..e0ab4534fe3e 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -134,7 +134,7 @@ static int mop500_probe(struct platform_device *pdev)
return ret;
}
-static int mop500_remove(struct platform_device *pdev)
+static void mop500_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
@@ -143,8 +143,6 @@ static int mop500_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
mop500_ab8500_remove(card);
mop500_of_node_put();
-
- return 0;
}
static const struct of_device_id snd_soc_mop500_match[] = {
@@ -159,7 +157,7 @@ static struct platform_driver snd_soc_mop500_driver = {
.of_match_table = snd_soc_mop500_match,
},
.probe = mop500_probe,
- .remove = mop500_remove,
+ .remove_new = mop500_remove,
};
module_platform_driver(snd_soc_mop500_driver);
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 6fb1a5c207bc..44e88dad8584 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -791,7 +791,7 @@ err_reg_plat:
return ret;
}
-static int ux500_msp_drv_remove(struct platform_device *pdev)
+static void ux500_msp_drv_remove(struct platform_device *pdev)
{
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
@@ -802,8 +802,6 @@ static int ux500_msp_drv_remove(struct platform_device *pdev)
prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp);
-
- return 0;
}
static const struct of_device_id ux500_msp_i2s_match[] = {
@@ -818,7 +816,7 @@ static struct platform_driver msp_i2s_driver = {
.of_match_table = ux500_msp_i2s_match,
},
.probe = ux500_msp_drv_probe,
- .remove = ux500_msp_drv_remove,
+ .remove_new = ux500_msp_drv_remove,
};
module_platform_driver(msp_i2s_driver);
diff --git a/sound/soc/xilinx/xlnx_formatter_pcm.c b/sound/soc/xilinx/xlnx_formatter_pcm.c
index ff1fe62fea70..299cfb5e2022 100644
--- a/sound/soc/xilinx/xlnx_formatter_pcm.c
+++ b/sound/soc/xilinx/xlnx_formatter_pcm.c
@@ -687,7 +687,7 @@ clk_err:
return ret;
}
-static int xlnx_formatter_pcm_remove(struct platform_device *pdev)
+static void xlnx_formatter_pcm_remove(struct platform_device *pdev)
{
int ret = 0;
struct xlnx_pcm_drv_data *adata = dev_get_drvdata(&pdev->dev);
@@ -703,7 +703,6 @@ static int xlnx_formatter_pcm_remove(struct platform_device *pdev)
dev_err(&pdev->dev, "audio formatter reset failed\n");
clk_disable_unprepare(adata->axi_clk);
- return 0;
}
static const struct of_device_id xlnx_formatter_pcm_of_match[] = {
@@ -714,7 +713,7 @@ MODULE_DEVICE_TABLE(of, xlnx_formatter_pcm_of_match);
static struct platform_driver xlnx_formatter_pcm_driver = {
.probe = xlnx_formatter_pcm_probe,
- .remove = xlnx_formatter_pcm_remove,
+ .remove_new = xlnx_formatter_pcm_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = xlnx_formatter_pcm_of_match,
diff --git a/sound/soc/xilinx/xlnx_spdif.c b/sound/soc/xilinx/xlnx_spdif.c
index 7342048e9875..d52d5fc7b5b8 100644
--- a/sound/soc/xilinx/xlnx_spdif.c
+++ b/sound/soc/xilinx/xlnx_spdif.c
@@ -312,12 +312,11 @@ clk_err:
return ret;
}
-static int xlnx_spdif_remove(struct platform_device *pdev)
+static void xlnx_spdif_remove(struct platform_device *pdev)
{
struct spdif_dev_data *ctx = dev_get_drvdata(&pdev->dev);
clk_disable_unprepare(ctx->axi_clk);
- return 0;
}
static struct platform_driver xlnx_spdif_driver = {
@@ -326,7 +325,7 @@ static struct platform_driver xlnx_spdif_driver = {
.of_match_table = xlnx_spdif_of_match,
},
.probe = xlnx_spdif_probe,
- .remove = xlnx_spdif_remove,
+ .remove_new = xlnx_spdif_remove,
};
module_platform_driver(xlnx_spdif_driver);
diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c
index a8f156540b50..287407714af4 100644
--- a/sound/soc/xtensa/xtfpga-i2s.c
+++ b/sound/soc/xtensa/xtfpga-i2s.c
@@ -605,7 +605,7 @@ err:
return err;
}
-static int xtfpga_i2s_remove(struct platform_device *pdev)
+static void xtfpga_i2s_remove(struct platform_device *pdev)
{
struct xtfpga_i2s *i2s = dev_get_drvdata(&pdev->dev);
@@ -618,7 +618,6 @@ static int xtfpga_i2s_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
xtfpga_i2s_runtime_suspend(&pdev->dev);
- return 0;
}
#ifdef CONFIG_OF
@@ -636,7 +635,7 @@ static const struct dev_pm_ops xtfpga_i2s_pm_ops = {
static struct platform_driver xtfpga_i2s_driver = {
.probe = xtfpga_i2s_probe,
- .remove = xtfpga_i2s_remove,
+ .remove_new = xtfpga_i2s_remove,
.driver = {
.name = "xtfpga-i2s",
.of_match_table = of_match_ptr(xtfpga_i2s_of_match),
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 2942c8c7a236..31bac355ec4d 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -2069,13 +2069,11 @@ static int cs4231_probe(struct platform_device *op)
return -ENODEV;
}
-static int cs4231_remove(struct platform_device *op)
+static void cs4231_remove(struct platform_device *op)
{
struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
snd_card_free(chip->card);
-
- return 0;
}
static const struct of_device_id cs4231_match[] = {
@@ -2097,7 +2095,7 @@ static struct platform_driver cs4231_driver = {
.of_match_table = cs4231_match,
},
.probe = cs4231_probe,
- .remove = cs4231_remove,
+ .remove_new = cs4231_remove,
};
module_platform_driver(cs4231_driver);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 3881e1c1b08a..376aed136a45 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2656,14 +2656,12 @@ _err:
return err;
}
-static int dbri_remove(struct platform_device *op)
+static void dbri_remove(struct platform_device *op)
{
struct snd_card *card = dev_get_drvdata(&op->dev);
snd_dbri_free(card->private_data);
snd_card_free(card);
-
- return 0;
}
static const struct of_device_id dbri_match[] = {
@@ -2684,7 +2682,7 @@ static struct platform_driver dbri_sbus_driver = {
.of_match_table = dbri_match,
},
.probe = dbri_probe,
- .remove = dbri_remove,
+ .remove_new = dbri_remove,
};
module_platform_driver(dbri_sbus_driver);