aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/adi,adau7002.txt19
-rw-r--r--Documentation/devicetree/bindings/sound/adi,adau7002.yaml40
-rw-r--r--Documentation/devicetree/bindings/sound/rt5640.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml158
-rw-r--r--Documentation/devicetree/bindings/sound/tlv320aic3x.txt97
-rw-r--r--include/uapi/sound/intel/avs/tokens.h4
-rw-r--r--sound/soc/amd/ps/acp63.h9
-rw-r--r--sound/soc/amd/ps/pci-ps.c205
-rw-r--r--sound/soc/amd/raven/acp3x-i2s.c8
-rw-r--r--sound/soc/atmel/atmel-classd.c6
-rw-r--r--sound/soc/atmel/atmel-pdmic.c6
-rw-r--r--sound/soc/codecs/88pm860x-codec.c6
-rw-r--r--sound/soc/codecs/ac97.c6
-rw-r--r--sound/soc/codecs/adau7002.c6
-rw-r--r--sound/soc/codecs/bt-sco.c6
-rw-r--r--sound/soc/codecs/cq93vc.c6
-rw-r--r--sound/soc/codecs/da7213.c30
-rw-r--r--sound/soc/codecs/da7213.h3
-rw-r--r--sound/soc/codecs/mc13783.c6
-rw-r--r--sound/soc/codecs/rt5640.c4
-rw-r--r--sound/soc/codecs/rt5640.h2
-rw-r--r--sound/soc/codecs/rt711-sdca.c15
-rw-r--r--sound/soc/codecs/rt711-sdca.h8
-rw-r--r--sound/soc/codecs/wl1273.c6
-rw-r--r--sound/soc/codecs/wm8940.c116
-rw-r--r--sound/soc/codecs/wm8940.h3
-rw-r--r--sound/soc/intel/avs/Makefile2
-rw-r--r--sound/soc/intel/avs/control.c105
-rw-r--r--sound/soc/intel/avs/control.h23
-rw-r--r--sound/soc/intel/avs/messages.c29
-rw-r--r--sound/soc/intel/avs/messages.h33
-rw-r--r--sound/soc/intel/avs/path.c62
-rw-r--r--sound/soc/intel/avs/topology.c76
-rw-r--r--sound/soc/intel/avs/topology.h3
-rw-r--r--sound/soc/pxa/e740_wm9705.c6
-rw-r--r--sound/soc/pxa/e750_wm9705.c6
-rw-r--r--sound/soc/pxa/e800_wm9712.c6
-rw-r--r--sound/soc/pxa/spitz.c6
-rw-r--r--sound/soc/sof/amd/acp-dsp-offset.h4
-rw-r--r--sound/soc/sof/amd/acp-loader.c7
-rw-r--r--sound/soc/sof/amd/acp.h2
-rw-r--r--sound/soc/sof/core.c3
-rw-r--r--sound/soc/sof/ipc3-topology.c7
-rw-r--r--sound/soc/sof/mediatek/mt8195/mt8195.c5
-rw-r--r--sound/soc/sof/mediatek/mt8195/mt8195.h2
-rw-r--r--sound/soc/sof/nocodec.c6
46 files changed, 846 insertions, 325 deletions
diff --git a/Documentation/devicetree/bindings/sound/adi,adau7002.txt b/Documentation/devicetree/bindings/sound/adi,adau7002.txt
deleted file mode 100644
index f144ee1abf85..000000000000
--- a/Documentation/devicetree/bindings/sound/adi,adau7002.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter
-
-Required properties:
-
- - compatible: Must be "adi,adau7002"
-
-Optional properties:
-
- - IOVDD-supply: Phandle and specifier for the power supply providing the IOVDD
- supply as covered in Documentation/devicetree/bindings/regulator/regulator.txt
-
- If this property is not present it is assumed that the supply pin is
- hardwired to always on.
-
-Example:
- adau7002: pdm-to-i2s {
- compatible = "adi,adau7002";
- IOVDD-supply = <&supply>;
- };
diff --git a/Documentation/devicetree/bindings/sound/adi,adau7002.yaml b/Documentation/devicetree/bindings/sound/adi,adau7002.yaml
new file mode 100644
index 000000000000..fcca0fde7d86
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/adi,adau7002.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/adi,adau7002.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+allOf:
+ - $ref: dai-common.yaml#
+
+properties:
+ compatible:
+ const: adi,adau7002
+
+ IOVDD-supply:
+ description:
+ IOVDD power supply, if skipped then it is assumed that the supply pin is
+ hardwired to always on.
+
+ wakeup-delay-ms:
+ description:
+ Delay after power up needed for device to settle.
+
+required:
+ - compatible
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ audio-codec {
+ compatible = "adi,adau7002";
+ IOVDD-supply = <&pp1800_l15a>;
+ #sound-dai-cells = <0>;
+ wakeup-delay-ms = <80>;
+ };
diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt
index ff1228713f7e..0c398581d52b 100644
--- a/Documentation/devicetree/bindings/sound/rt5640.txt
+++ b/Documentation/devicetree/bindings/sound/rt5640.txt
@@ -20,6 +20,9 @@ Optional properties:
- realtek,in3-differential
Boolean. Indicate MIC1/2/3 input are differential, rather than single-ended.
+- realtek,lout-differential
+ Boolean. Indicate LOUT output is differential, rather than stereo.
+
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
- realtek,dmic1-data-pin
diff --git a/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml b/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
new file mode 100644
index 000000000000..f0375bbf4c40
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+# Copyright (C) 2022 Texas Instruments Incorporated
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/ti,tlv320aic3x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments TLV320AIC3x Codec
+
+description: |
+ TLV320AIC3x are a series of low-power stereo audio codecs with stereo
+ headphone amplifier, as well as multiple inputs and outputs programmable in
+ single-ended or fully differential configurations.
+
+ The serial control bus supports SPI or I2C protocols, while the serial audio
+ data bus is programmable for I2S, left/right-justified, DSP, or TDM modes.
+
+ The following pins can be referred in the sound node's audio routing property:
+
+ CODEC output pins:
+ LLOUT
+ RLOUT
+ MONO_LOUT
+ HPLOUT
+ HPROUT
+ HPLCOM
+ HPRCOM
+
+ CODEC input pins for TLV320AIC3104:
+ MIC2L
+ MIC2R
+ LINE1L
+ LINE1R
+
+ CODEC input pins for other compatible codecs:
+ MIC3L
+ MIC3R
+ LINE1L
+ LINE2L
+ LINE1R
+ LINE2R
+
+maintainers:
+ - Jai Luthra <j-luthra@ti.com>
+
+properties:
+ compatible:
+ enum:
+ - ti,tlv320aic3x
+ - ti,tlv320aic33
+ - ti,tlv320aic3007
+ - ti,tlv320aic3106
+ - ti,tlv320aic3104
+
+ reg:
+ maxItems: 1
+
+ reset-gpios:
+ maxItems: 1
+ description:
+ GPIO specification for the active low RESET input.
+
+ gpio-reset:
+ maxItems: 1
+ description:
+ Deprecated, please use reset-gpios instead.
+ deprecated: true
+
+ ai3x-gpio-func:
+ description: AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ maxItems: 2
+
+ ai3x-micbias-vg:
+ description: MicBias required voltage. If node is omitted then MicBias is powered down.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ oneOf:
+ - const: 1
+ description: MICBIAS output is powered to 2.0V.
+ - const: 2
+ description: MICBIAS output is powered to 2.5V.
+ - const: 3
+ description: MICBIAS output is connected to AVDD.
+
+ ai3x-ocmv:
+ description: Output Common-Mode Voltage selection.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ oneOf:
+ - const: 0
+ description: 1.35V
+ - const: 1
+ description: 1.5V
+ - const: 2
+ description: 1.65V
+ - const: 3
+ description: 1.8V
+
+ AVDD-supply:
+ description: Analog DAC voltage.
+
+ IOVDD-supply:
+ description: I/O voltage.
+
+ DRVDD-supply:
+ description: ADC analog and output driver voltage.
+
+ DVDD-supply:
+ description: Digital core voltage.
+
+ '#sound-dai-cells':
+ const: 0
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tlv320aic3x_i2c: audio-codec@1b {
+ compatible = "ti,tlv320aic3x";
+ reg = <0x1b>;
+
+ reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+
+ AVDD-supply = <&regulator>;
+ IOVDD-supply = <&regulator>;
+ DRVDD-supply = <&regulator>;
+ DVDD-supply = <&regulator>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ tlv320aic3x_spi: audio-codec@0 {
+ compatible = "ti,tlv320aic3x";
+ reg = <0>; /* CS number */
+ #sound-dai-cells = <0>;
+
+ AVDD-supply = <&regulator>;
+ IOVDD-supply = <&regulator>;
+ DRVDD-supply = <&regulator>;
+ DVDD-supply = <&regulator>;
+ ai3x-ocmv = <0>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
deleted file mode 100644
index 20931a63fd64..000000000000
--- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-Texas Instruments - tlv320aic3x Codec module
-
-The tlv320aic3x serial control bus communicates through both I2C and SPI bus protocols
-
-Required properties:
-
-- compatible - "string" - One of:
- "ti,tlv320aic3x" - Generic TLV320AIC3x device
- "ti,tlv320aic33" - TLV320AIC33
- "ti,tlv320aic3007" - TLV320AIC3007
- "ti,tlv320aic3106" - TLV320AIC3106
- "ti,tlv320aic3104" - TLV320AIC3104
-
-
-- reg - <int> - I2C slave address
-
-
-Optional properties:
-
-- reset-gpios - GPIO specification for the active low RESET input.
-- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
- - Not supported on tlv320aic3104
-- ai3x-micbias-vg - MicBias Voltage required.
- 1 - MICBIAS output is powered to 2.0V,
- 2 - MICBIAS output is powered to 2.5V,
- 3 - MICBIAS output is connected to AVDD,
- If this node is not mentioned or if the value is incorrect, then MicBias
- is powered down.
-- ai3x-ocmv - Output Common-Mode Voltage selection:
- 0 - 1.35V,
- 1 - 1.5V,
- 2 - 1.65V,
- 3 - 1.8V
-- AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the
- device as covered in Documentation/devicetree/bindings/regulator/regulator.txt
-
-Deprecated properties:
-
-- gpio-reset - gpio pin number used for codec reset
-
-CODEC output pins:
- * LLOUT
- * RLOUT
- * MONO_LOUT
- * HPLOUT
- * HPROUT
- * HPLCOM
- * HPRCOM
-
-CODEC input pins for TLV320AIC3104:
- * MIC2L
- * MIC2R
- * LINE1L
- * LINE1R
-
-CODEC input pins for other compatible codecs:
- * MIC3L
- * MIC3R
- * LINE1L
- * LINE2L
- * LINE1R
- * LINE2R
-
-The pins can be used in referring sound node's audio-routing property.
-
-I2C example:
-
-#include <dt-bindings/gpio/gpio.h>
-
-tlv320aic3x: tlv320aic3x@1b {
- compatible = "ti,tlv320aic3x";
- reg = <0x1b>;
-
- reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
-
- AVDD-supply = <&regulator>;
- IOVDD-supply = <&regulator>;
- DRVDD-supply = <&regulator>;
- DVDD-supply = <&regulator>;
-};
-
-SPI example:
-
-spi0: spi@f0000000 {
- tlv320aic3x: codec@0 {
- compatible = "ti,tlv320aic3x";
- reg = <0>; /* CS number */
- #sound-dai-cells = <0>;
- spi-max-frequency = <1000000>;
-
- AVDD-supply = <&regulator>;
- IOVDD-supply = <&regulator>;
- DRVDD-supply = <&regulator>;
- DVDD-supply = <&regulator>;
- ai3x-ocmv = <0>;
- };
-};
diff --git a/include/uapi/sound/intel/avs/tokens.h b/include/uapi/sound/intel/avs/tokens.h
index 754f02b2f444..4ffe546aa409 100644
--- a/include/uapi/sound/intel/avs/tokens.h
+++ b/include/uapi/sound/intel/avs/tokens.h
@@ -108,6 +108,7 @@ enum avs_tplg_token {
AVS_TKN_MOD_CORE_ID_U8 = 1704,
AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
+ AVS_TKN_MOD_KCONTROL_ID_U32 = 1707,
/* struct avs_tplg_path_template */
AVS_TKN_PATH_TMPL_ID_U32 = 1801,
@@ -121,6 +122,9 @@ enum avs_tplg_token {
AVS_TKN_PIN_FMT_INDEX_U32 = 2201,
AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
+
+ /* struct avs_tplg_kcontrol */
+ AVS_TKN_KCONTROL_ID_U32 = 2301,
};
#endif
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h
index 5e7f9c1c1b0e..8f024cb309c9 100644
--- a/sound/soc/amd/ps/acp63.h
+++ b/sound/soc/amd/ps/acp63.h
@@ -11,7 +11,6 @@
#define ACP63_REG_START 0x1240000
#define ACP63_REG_END 0x1250200
#define ACP63_DEVS 3
-#define ACP63_PDM_MODE 1
#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
#define ACP_PGFSM_CNTL_POWER_ON_MASK 1
@@ -54,6 +53,11 @@
/* time in ms for runtime suspend delay */
#define ACP_SUSPEND_DELAY_MS 2000
+#define ACP63_DMIC_ADDR 2
+#define ACP63_PDM_MODE_DEVS 3
+#define ACP63_PDM_DEV_MASK 1
+#define ACP_DMIC_DEV 2
+
enum acp_config {
ACP_CONFIG_0 = 0,
ACP_CONFIG_1,
@@ -102,4 +106,7 @@ struct acp63_dev_data {
struct resource *res;
bool acp63_audio_mode;
struct platform_device *pdev[ACP63_DEVS];
+ u16 pdev_mask;
+ u16 pdev_count;
+ u16 pdm_dev_index;
};
diff --git a/sound/soc/amd/ps/pci-ps.c b/sound/soc/amd/ps/pci-ps.c
index 489f01a20699..401cfd0036be 100644
--- a/sound/soc/amd/ps/pci-ps.c
+++ b/sound/soc/amd/ps/pci-ps.c
@@ -116,6 +116,7 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
struct acp63_dev_data *adata;
struct pdm_dev_data *ps_pdm_data;
u32 val;
+ u16 pdev_index;
adata = dev_id;
if (!adata)
@@ -123,7 +124,8 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
val = acp63_readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
if (val & BIT(PDM_DMA_STAT)) {
- ps_pdm_data = dev_get_drvdata(&adata->pdev[0]->dev);
+ pdev_index = adata->pdm_dev_index;
+ ps_pdm_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
acp63_writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
if (ps_pdm_data->capture_stream)
snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
@@ -132,17 +134,119 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
return IRQ_NONE;
}
+static void get_acp63_device_config(u32 config, struct pci_dev *pci,
+ struct acp63_dev_data *acp_data)
+{
+ struct acpi_device *dmic_dev;
+ const union acpi_object *obj;
+ bool is_dmic_dev = false;
+
+ dmic_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);
+ if (dmic_dev) {
+ if (!acpi_dev_get_property(dmic_dev, "acp-audio-device-type",
+ ACPI_TYPE_INTEGER, &obj) &&
+ obj->integer.value == ACP_DMIC_DEV)
+ is_dmic_dev = true;
+ }
+
+ switch (config) {
+ case ACP_CONFIG_0:
+ case ACP_CONFIG_1:
+ case ACP_CONFIG_2:
+ case ACP_CONFIG_3:
+ case ACP_CONFIG_9:
+ case ACP_CONFIG_15:
+ dev_dbg(&pci->dev, "Audio Mode %d\n", config);
+ break;
+ default:
+ if (is_dmic_dev) {
+ acp_data->pdev_mask = ACP63_PDM_DEV_MASK;
+ acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
+ }
+ break;
+ }
+}
+
+void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo, struct device *parent,
+ struct fwnode_handle *fw_node, char *name, unsigned int id,
+ const struct resource *res, unsigned int num_res,
+ const void *data, size_t size_data)
+{
+ pdevinfo->name = name;
+ pdevinfo->id = id;
+ pdevinfo->parent = parent;
+ pdevinfo->num_res = num_res;
+ pdevinfo->res = res;
+ pdevinfo->data = data;
+ pdevinfo->size_data = size_data;
+ pdevinfo->fwnode = fw_node;
+}
+
+static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr)
+{
+ struct platform_device_info pdevinfo[ACP63_DEVS];
+ struct device *parent;
+ int index;
+ int ret;
+
+ parent = &pci->dev;
+ dev_dbg(&pci->dev,
+ "%s pdev_mask:0x%x pdev_count:0x%x\n", __func__, adata->pdev_mask,
+ adata->pdev_count);
+ if (adata->pdev_mask) {
+ adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+ adata->res->flags = IORESOURCE_MEM;
+ adata->res->start = addr;
+ adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START);
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ }
+
+ switch (adata->pdev_mask) {
+ case ACP63_PDM_DEV_MASK:
+ adata->pdm_dev_index = 0;
+ acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
+ 0, adata->res, 1, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "dmic-codec",
+ 0, NULL, 0, NULL, 0);
+ acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "acp_ps_mach",
+ 0, NULL, 0, NULL, 0);
+ break;
+ default:
+ dev_dbg(&pci->dev, "No PDM devices found\n");
+ goto de_init;
+ }
+
+ for (index = 0; index < adata->pdev_count; index++) {
+ adata->pdev[index] = platform_device_register_full(&pdevinfo[index]);
+ if (IS_ERR(adata->pdev[index])) {
+ dev_err(&pci->dev,
+ "cannot register %s device\n", pdevinfo[index].name);
+ ret = PTR_ERR(adata->pdev[index]);
+ goto unregister_devs;
+ }
+ }
+ return 0;
+unregister_devs:
+ for (--index; index >= 0; index--)
+ platform_device_unregister(adata->pdev[index]);
+de_init:
+ if (acp63_deinit(adata->acp63_base, &pci->dev))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+ return ret;
+}
+
static int snd_acp63_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
struct acp63_dev_data *adata;
- struct platform_device_info pdevinfo[ACP63_DEVS];
- int index, ret;
- int val = 0x00;
- struct acpi_device *adev;
- const union acpi_object *obj;
u32 addr;
- unsigned int irqflags;
+ u32 irqflags;
+ int val;
+ int ret;
irqflags = IRQF_SHARED;
/* Pink Sardine device check */
@@ -182,83 +286,24 @@ static int snd_acp63_probe(struct pci_dev *pci,
ret = acp63_init(adata->acp63_base, &pci->dev);
if (ret)
goto release_regions;
+ ret = devm_request_irq(&pci->dev, pci->irq, acp63_irq_handler,
+ irqflags, "ACP_PCI_IRQ", adata);
+ if (ret) {
+ dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
+ goto de_init;
+ }
val = acp63_readl(adata->acp63_base + ACP_PIN_CONFIG);
- switch (val) {
- case ACP_CONFIG_0:
- case ACP_CONFIG_1:
- case ACP_CONFIG_2:
- case ACP_CONFIG_3:
- case ACP_CONFIG_9:
- case ACP_CONFIG_15:
- dev_info(&pci->dev, "Audio Mode %d\n", val);
- break;
- default:
-
- /* Checking DMIC hardware*/
- adev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), 0x02, 0);
-
- if (!adev)
- break;
-
- if (!acpi_dev_get_property(adev, "acp-audio-device-type",
- ACPI_TYPE_INTEGER, &obj) &&
- obj->integer.value == 2) {
- adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);
- if (!adata->res) {
- ret = -ENOMEM;
- goto de_init;
- }
-
- adata->res->name = "acp_iomem";
- adata->res->flags = IORESOURCE_MEM;
- adata->res->start = addr;
- adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START);
- adata->acp63_audio_mode = ACP63_PDM_MODE;
-
- memset(&pdevinfo, 0, sizeof(pdevinfo));
- pdevinfo[0].name = "acp_ps_pdm_dma";
- pdevinfo[0].id = 0;
- pdevinfo[0].parent = &pci->dev;
- pdevinfo[0].num_res = 1;
- pdevinfo[0].res = adata->res;
-
- pdevinfo[1].name = "dmic-codec";
- pdevinfo[1].id = 0;
- pdevinfo[1].parent = &pci->dev;
-
- pdevinfo[2].name = "acp_ps_mach";
- pdevinfo[2].id = 0;
- pdevinfo[2].parent = &pci->dev;
-
- for (index = 0; index < ACP63_DEVS; index++) {
- adata->pdev[index] =
- platform_device_register_full(&pdevinfo[index]);
-
- if (IS_ERR(adata->pdev[index])) {
- dev_err(&pci->dev,
- "cannot register %s device\n",
- pdevinfo[index].name);
- ret = PTR_ERR(adata->pdev[index]);
- goto unregister_devs;
- }
- ret = devm_request_irq(&pci->dev, pci->irq, acp63_irq_handler,
- irqflags, "ACP_PCI_IRQ", adata);
- if (ret) {
- dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
- goto unregister_devs;
- }
- }
- }
- break;
+ get_acp63_device_config(val, pci, adata);
+ ret = create_acp63_platform_devs(pci, adata, addr);
+ if (ret < 0) {
+ dev_err(&pci->dev, "ACP platform devices creation failed\n");
+ goto de_init;
}
pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pci->dev);
pm_runtime_put_noidle(&pci->dev);
pm_runtime_allow(&pci->dev);
return 0;
-unregister_devs:
- for (--index; index >= 0; index--)
- platform_device_unregister(adata->pdev[index]);
de_init:
if (acp63_deinit(adata->acp63_base, &pci->dev))
dev_err(&pci->dev, "ACP de-init failed\n");
@@ -305,10 +350,8 @@ static void snd_acp63_remove(struct pci_dev *pci)
int ret, index;
adata = pci_get_drvdata(pci);
- if (adata->acp63_audio_mode == ACP63_PDM_MODE) {
- for (index = 0; index < ACP63_DEVS; index++)
- platform_device_unregister(adata->pdev[index]);
- }
+ for (index = 0; index < adata->pdev_count; index++)
+ platform_device_unregister(adata->pdev[index]);
ret = acp63_deinit(adata->acp63_base, &pci->dev);
if (ret)
dev_err(&pci->dev, "ACP de-init failed\n");
diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c
index aa38cef1776d..4ba83689482a 100644
--- a/sound/soc/amd/raven/acp3x-i2s.c
+++ b/sound/soc/amd/raven/acp3x-i2s.c
@@ -315,16 +315,8 @@ static int acp3x_dai_probe(struct platform_device *pdev)
return 0;
}
-static int acp3x_dai_remove(struct platform_device *pdev)
-{
- /* As we use devm_ memory alloc there is nothing TBD here */
-
- return 0;
-}
-
static struct platform_driver acp3x_dai_driver = {
.probe = acp3x_dai_probe,
- .remove = acp3x_dai_remove,
.driver = {
.name = "acp3x_i2s_playcap",
},
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index 87d6d6ed026b..9883e6867fd1 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -616,11 +616,6 @@ unregister_codec:
return ret;
}
-static int atmel_classd_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver atmel_classd_driver = {
.driver = {
.name = "atmel-classd",
@@ -628,7 +623,6 @@ static struct platform_driver atmel_classd_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = atmel_classd_probe,
- .remove = atmel_classd_remove,
};
module_platform_driver(atmel_classd_driver);
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
index 77ff12baead5..12cd40b15644 100644
--- a/sound/soc/atmel/atmel-pdmic.c
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -692,11 +692,6 @@ unregister_codec:
return ret;
}
-static int atmel_pdmic_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver atmel_pdmic_driver = {
.driver = {
.name = "atmel-pdmic",
@@ -704,7 +699,6 @@ static struct platform_driver atmel_pdmic_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = atmel_pdmic_probe,
- .remove = atmel_pdmic_remove,
};
module_platform_driver(atmel_pdmic_driver);
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index fc65283031cd..3574c68e0dda 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1386,17 +1386,11 @@ static int pm860x_codec_probe(struct platform_device *pdev)
return ret;
}
-static int pm860x_codec_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver pm860x_codec_driver = {
.driver = {
.name = "88pm860x-codec",
},
.probe = pm860x_codec_probe,
- .remove = pm860x_codec_remove,
};
module_platform_driver(pm860x_codec_driver);
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index cc12052e1920..0e013edfe63d 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -127,18 +127,12 @@ static int ac97_probe(struct platform_device *pdev)
&soc_component_dev_ac97, &ac97_dai, 1);
}
-static int ac97_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver ac97_codec_driver = {
.driver = {
.name = "ac97-codec",
},
.probe = ac97_probe,
- .remove = ac97_remove,
};
module_platform_driver(ac97_codec_driver);
diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c
index 401bafabc8eb..c9134e1de0b2 100644
--- a/sound/soc/codecs/adau7002.c
+++ b/sound/soc/codecs/adau7002.c
@@ -100,11 +100,6 @@ static int adau7002_probe(struct platform_device *pdev)
&adau7002_dai, 1);
}
-static int adau7002_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
#ifdef CONFIG_OF
static const struct of_device_id adau7002_dt_ids[] = {
{ .compatible = "adi,adau7002", },
@@ -128,7 +123,6 @@ static struct platform_driver adau7002_driver = {
.acpi_match_table = ACPI_PTR(adau7002_acpi_match),
},
.probe = adau7002_probe,
- .remove = adau7002_remove,
};
module_platform_driver(adau7002_driver);
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index 4086b6a53de8..3afcef2dfa35 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -78,11 +78,6 @@ static int bt_sco_probe(struct platform_device *pdev)
bt_sco_dai, ARRAY_SIZE(bt_sco_dai));
}
-static int bt_sco_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static const struct platform_device_id bt_sco_driver_ids[] = {
{
.name = "dfbmcs320",
@@ -109,7 +104,6 @@ static struct platform_driver bt_sco_driver = {
.of_match_table = of_match_ptr(bt_sco_codec_of_match),
},
.probe = bt_sco_probe,
- .remove = bt_sco_remove,
.id_table = bt_sco_driver_ids,
};
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 14403b76c724..32b6a417d0e8 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -134,18 +134,12 @@ static int cq93vc_platform_probe(struct platform_device *pdev)
&soc_component_dev_cq93vc, &cq93vc_dai, 1);
}
-static int cq93vc_platform_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver cq93vc_codec_driver = {
.driver = {
.name = "cq93vc-codec",
},
.probe = cq93vc_platform_probe,
- .remove = cq93vc_platform_remove,
};
module_platform_driver(cq93vc_codec_driver);
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 544ccbcfc884..0068780fe0a7 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1157,13 +1157,31 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
+ u8 dai_clk_mode = DA7213_DAI_BCLKS_PER_WCLK_64;
u8 dai_ctrl = 0;
u8 fs;
+ /* Set channels */
+ switch (params_channels(params)) {
+ case 1:
+ if (da7213->fmt != DA7213_DAI_FORMAT_DSP) {
+ dev_err(component->dev, "Mono supported only in DSP mode\n");
+ return -EINVAL;
+ }
+ dai_ctrl |= DA7213_DAI_MONO_MODE_EN;
+ break;
+ case 2:
+ dai_ctrl &= ~(DA7213_DAI_MONO_MODE_EN);
+ break;
+ default:
+ return -EINVAL;
+ }
+
/* Set DAI format */
switch (params_width(params)) {
case 16:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE;
+ dai_clk_mode = DA7213_DAI_BCLKS_PER_WCLK_32; /* 32bit for 1ch and 2ch */
break;
case 20:
dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE;
@@ -1224,8 +1242,11 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
- dai_ctrl);
+ snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE,
+ DA7213_DAI_BCLKS_PER_WCLK_MASK, dai_clk_mode);
+
+ snd_soc_component_update_bits(component, DA7213_DAI_CTRL,
+ DA7213_DAI_WORD_LENGTH_MASK | DA7213_DAI_MONO_MODE_MASK, dai_ctrl);
snd_soc_component_write(component, DA7213_SR, fs);
return 0;
@@ -1300,19 +1321,24 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
dai_ctrl |= DA7213_DAI_FORMAT_I2S_MODE;
+ da7213->fmt = DA7213_DAI_FORMAT_I2S_MODE;
break;
case SND_SOC_DAIFMT_LEFT_J:
dai_ctrl |= DA7213_DAI_FORMAT_LEFT_J;
+ da7213->fmt = DA7213_DAI_FORMAT_LEFT_J;
break;
case SND_SOC_DAIFMT_RIGHT_J:
dai_ctrl |= DA7213_DAI_FORMAT_RIGHT_J;
+ da7213->fmt = DA7213_DAI_FORMAT_RIGHT_J;
break;
case SND_SOC_DAI_FORMAT_DSP_A: /* L data MSB after FRM LRC */
dai_ctrl |= DA7213_DAI_FORMAT_DSP;
dai_offset = 1;
+ da7213->fmt = DA7213_DAI_FORMAT_DSP;
break;
case SND_SOC_DAI_FORMAT_DSP_B: /* L data MSB during FRM LRC */
dai_ctrl |= DA7213_DAI_FORMAT_DSP;
+ da7213->fmt = DA7213_DAI_FORMAT_DSP;
break;
default:
return -EINVAL;
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 97ccf0ddd2be..4ca9cfdea06d 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -195,6 +195,8 @@
#define DA7213_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
#define DA7213_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
#define DA7213_DAI_WORD_LENGTH_MASK (0x3 << 2)
+#define DA7213_DAI_MONO_MODE_EN (0x1 << 4)
+#define DA7213_DAI_MONO_MODE_MASK (0x1 << 4)
#define DA7213_DAI_EN_SHIFT 7
/* DA7213_DIG_ROUTING_DAI = 0x21 */
@@ -542,6 +544,7 @@ struct da7213_priv {
bool alc_en;
bool fixed_clk_auto_pll;
struct da7213_platform_data *pdata;
+ int fmt;
};
#endif /* _DA7213_H */
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 71490f11d96a..086ac97e8386 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -776,16 +776,10 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
return ret;
}
-static int mc13783_codec_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver mc13783_codec_driver = {
.driver = {
.name = "mc13783-codec",
},
- .remove = mc13783_codec_remove,
};
module_platform_driver_probe(mc13783_codec_driver, mc13783_codec_probe);
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 708e55b7431a..9e6341a68c6b 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2717,6 +2717,10 @@ static int rt5640_probe(struct snd_soc_component *component)
snd_soc_component_update_bits(component, RT5640_IN1_IN2,
RT5640_IN_DF2, RT5640_IN_DF2);
+ if (device_property_read_bool(component->dev, "realtek,lout-differential"))
+ snd_soc_component_update_bits(component, RT5640_DUMMY1,
+ RT5640_EN_LOUT_DF, RT5640_EN_LOUT_DF);
+
if (device_property_read_u32(component->dev, "realtek,dmic1-data-pin",
&val) == 0 && val) {
dmic1_data_pin = val - 1;
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index f58b88e3325b..9847a1ae01f4 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -1978,6 +1978,8 @@
#define RT5640_ZCD_HP_EN (0x1 << 15)
/* General Control 1 (0xfa) */
+#define RT5640_EN_LOUT_DF (0x1 << 14)
+#define RT5640_EN_LOUT_DF_SFT 14
#define RT5640_M_MONO_ADC_L (0x1 << 13)
#define RT5640_M_MONO_ADC_L_SFT 13
#define RT5640_M_MONO_ADC_R (0x1 << 12)
diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
index b78dd5994edb..7cdf184d380b 100644
--- a/sound/soc/codecs/rt711-sdca.c
+++ b/sound/soc/codecs/rt711-sdca.c
@@ -463,6 +463,21 @@ static void rt711_sdca_jack_init(struct rt711_sdca_priv *rt711)
RT711_HP_JD_FINAL_RESULT_CTL_JD12,
RT711_HP_JD_FINAL_RESULT_CTL_JD12);
break;
+ case RT711_JD2_100K:
+ rt711_sdca_index_write(rt711, RT711_VENDOR_REG,
+ RT711_COMBO_JACK_AUTO_CTL3, 0xa47e);
+ rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG,
+ RT711_JD_CTL1, RT711_JD2_DIGITAL_MODE_SEL,
+ RT711_JD2_DIGITAL_MODE_SEL);
+ rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG,
+ RT711_JD_CTL2, RT711_JD2_2PORT_200K_DECODE_HP |
+ RT711_JD2_2PORT_100K_DECODE_MASK | RT711_HP_JD_SEL_JD2,
+ RT711_JD2_2PORT_100K_DECODE_HP | RT711_HP_JD_SEL_JD2);
+ rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG,
+ RT711_CC_DET1,
+ RT711_HP_JD_FINAL_RESULT_CTL_JD12 | RT711_POW_CC1_AGPI,
+ RT711_HP_JD_FINAL_RESULT_CTL_JD12 | RT711_POW_CC1_AGPI_OFF);
+ break;
default:
dev_warn(rt711->component->dev, "Wrong JD source\n");
break;
diff --git a/sound/soc/codecs/rt711-sdca.h b/sound/soc/codecs/rt711-sdca.h
index 498ca687c47b..10e3c801b813 100644
--- a/sound/soc/codecs/rt711-sdca.h
+++ b/sound/soc/codecs/rt711-sdca.h
@@ -127,12 +127,17 @@ struct sdw_stream_data {
/* jack detect control 2 (0x09)(NID:20h) */
#define RT711_JD2_2PORT_200K_DECODE_HP (0x1 << 13)
+#define RT711_JD2_2PORT_100K_DECODE_MASK (0x1 << 12)
+#define RT711_JD2_2PORT_100K_DECODE_HP (0x0 << 12)
#define RT711_HP_JD_SEL_JD1 (0x0 << 1)
#define RT711_HP_JD_SEL_JD2 (0x1 << 1)
/* CC DET1 (0x11)(NID:20h) */
#define RT711_HP_JD_FINAL_RESULT_CTL_JD12 (0x1 << 10)
#define RT711_HP_JD_FINAL_RESULT_CTL_CCDET (0x0 << 10)
+#define RT711_POW_CC1_AGPI (0x1 << 5)
+#define RT711_POW_CC1_AGPI_ON (0x1 << 5)
+#define RT711_POW_CC1_AGPI_OFF (0x0 << 5)
/* Parameter & Verb control (0x1a)(NID:20h) */
#define RT711_HIDDEN_REG_SW_RESET (0x1 << 14)
@@ -226,7 +231,8 @@ enum {
enum rt711_sdca_jd_src {
RT711_JD_NULL,
RT711_JD1,
- RT711_JD2
+ RT711_JD2,
+ RT711_JD2_100K
};
enum rt711_sdca_ver {
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 626278e4c923..737ca82cf976 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -484,11 +484,6 @@ static int wl1273_platform_probe(struct platform_device *pdev)
&wl1273_dai, 1);
}
-static int wl1273_platform_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
MODULE_ALIAS("platform:wl1273-codec");
static struct platform_driver wl1273_platform_driver = {
@@ -496,7 +491,6 @@ static struct platform_driver wl1273_platform_driver = {
.name = "wl1273-codec",
},
.probe = wl1273_platform_probe,
- .remove = wl1273_platform_remove,
};
module_platform_driver(wl1273_platform_driver);
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 8dac9fd88547..8eb4782c9232 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -37,7 +37,9 @@
#include "wm8940.h"
struct wm8940_priv {
- unsigned int sysclk;
+ unsigned int mclk;
+ unsigned int fs;
+
struct regmap *regmap;
};
@@ -387,17 +389,24 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
+static int wm8940_update_clocks(struct snd_soc_dai *dai);
static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
+ struct wm8940_priv *priv = snd_soc_component_get_drvdata(component);
u16 iface = snd_soc_component_read(component, WM8940_IFACE) & 0xFD9F;
u16 addcntrl = snd_soc_component_read(component, WM8940_ADDCNTRL) & 0xFFF1;
u16 companding = snd_soc_component_read(component,
WM8940_COMPANDINGCTL) & 0xFFDF;
int ret;
+ priv->fs = params_rate(params);
+ ret = wm8940_update_clocks(dai);
+ if (ret)
+ return ret;
+
/* LoutR control */
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
&& params_channels(params) == 2)
@@ -611,24 +620,6 @@ static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
return 0;
}
-static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_component *component = codec_dai->component;
- struct wm8940_priv *wm8940 = snd_soc_component_get_drvdata(component);
-
- switch (freq) {
- case 11289600:
- case 12000000:
- case 12288000:
- case 16934400:
- case 18432000:
- wm8940->sysclk = freq;
- return 0;
- }
- return -EINVAL;
-}
-
static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
int div_id, int div)
{
@@ -653,6 +644,78 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
return ret;
}
+static unsigned int wm8940_get_mclkdiv(unsigned int f_in, unsigned int f_out,
+ int *mclkdiv)
+{
+ unsigned int ratio = 2 * f_in / f_out;
+
+ if (ratio <= 2) {
+ *mclkdiv = WM8940_MCLKDIV_1;
+ ratio = 2;
+ } else if (ratio == 3) {
+ *mclkdiv = WM8940_MCLKDIV_1_5;
+ } else if (ratio == 4) {
+ *mclkdiv = WM8940_MCLKDIV_2;
+ } else if (ratio <= 6) {
+ *mclkdiv = WM8940_MCLKDIV_3;
+ ratio = 6;
+ } else if (ratio <= 8) {
+ *mclkdiv = WM8940_MCLKDIV_4;
+ ratio = 8;
+ } else if (ratio <= 12) {
+ *mclkdiv = WM8940_MCLKDIV_6;
+ ratio = 12;
+ } else if (ratio <= 16) {
+ *mclkdiv = WM8940_MCLKDIV_8;
+ ratio = 16;
+ } else {
+ *mclkdiv = WM8940_MCLKDIV_12;
+ ratio = 24;
+ }
+
+ return f_out * ratio / 2;
+}
+
+static int wm8940_update_clocks(struct snd_soc_dai *dai)
+{
+ struct snd_soc_component *codec = dai->component;
+ struct wm8940_priv *priv = snd_soc_component_get_drvdata(codec);
+ unsigned int fs256;
+ unsigned int fpll = 0;
+ unsigned int f;
+ int mclkdiv;
+
+ if (!priv->mclk || !priv->fs)
+ return 0;
+
+ fs256 = 256 * priv->fs;
+
+ f = wm8940_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
+ if (f != priv->mclk) {
+ /* The PLL performs best around 90MHz */
+ fpll = wm8940_get_mclkdiv(22500000, fs256, &mclkdiv);
+ }
+
+ wm8940_set_dai_pll(dai, 0, 0, priv->mclk, fpll);
+ wm8940_set_dai_clkdiv(dai, WM8940_MCLKDIV, mclkdiv);
+
+ return 0;
+}
+
+static int wm8940_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_component *codec = dai->component;
+ struct wm8940_priv *priv = snd_soc_component_get_drvdata(codec);
+
+ if (dir != SND_SOC_CLOCK_IN)
+ return -EINVAL;
+
+ priv->mclk = freq;
+
+ return wm8940_update_clocks(dai);
+}
+
#define WM8940_RATES SNDRV_PCM_RATE_8000_48000
#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
@@ -697,6 +760,17 @@ static int wm8940_probe(struct snd_soc_component *component)
int ret;
u16 reg;
+ /*
+ * Check chip ID for wm8940 - value of 0x00 offset
+ * SOFTWARE_RESET on write
+ * CHIP_ID on read
+ */
+ reg = snd_soc_component_read(component, WM8940_SOFTRESET);
+ if (reg != WM8940_CHIP_ID) {
+ dev_err(component->dev, "Wrong wm8940 chip ID: 0x%x\n", reg);
+ return -ENODEV;
+ }
+
ret = wm8940_reset(component);
if (ret < 0) {
dev_err(component->dev, "Failed to issue reset\n");
@@ -709,9 +783,7 @@ static int wm8940_probe(struct snd_soc_component *component)
if (ret < 0)
return ret;
- if (!pdata)
- dev_warn(component->dev, "No platform data supplied\n");
- else {
+ if (pdata) {
reg = snd_soc_component_read(component, WM8940_OUTPUTCTL);
ret = snd_soc_component_write(component, WM8940_OUTPUTCTL, reg | pdata->vroi);
if (ret < 0)
diff --git a/sound/soc/codecs/wm8940.h b/sound/soc/codecs/wm8940.h
index 0d4f53ada2e6..86bbf902ef5a 100644
--- a/sound/soc/codecs/wm8940.h
+++ b/sound/soc/codecs/wm8940.h
@@ -95,5 +95,8 @@ struct wm8940_setup_data {
#define WM8940_OPCLKDIV_3 2
#define WM8940_OPCLKDIV_4 3
+/* Chip ID */
+#define WM8940_CHIP_ID 0x8940
+
#endif /* _WM8940_H */
diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile
index 1c6924a1ebca..460ee6599daf 100644
--- a/sound/soc/intel/avs/Makefile
+++ b/sound/soc/intel/avs/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
snd-soc-avs-objs := dsp.o ipc.o messages.o utils.o core.o loader.o \
- topology.o path.o pcm.o board_selection.o
+ topology.o path.o pcm.o board_selection.o control.o
snd-soc-avs-objs += cldma.o
snd-soc-avs-objs += skl.o apl.o
diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c
new file mode 100644
index 000000000000..a8b14b784f8a
--- /dev/null
+++ b/sound/soc/intel/avs/control.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+//
+// Authors: Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+// Cezary Rojewski <cezary.rojewski@intel.com>
+//
+
+#include <sound/soc.h>
+#include "avs.h"
+#include "control.h"
+#include "messages.h"
+#include "path.h"
+
+static struct avs_dev *avs_get_kcontrol_adev(struct snd_kcontrol *kcontrol)
+{
+ struct snd_soc_dapm_widget *w;
+
+ w = snd_soc_dapm_kcontrol_widget(kcontrol);
+
+ return to_avs_dev(w->dapm->component->dev);
+}
+
+static struct avs_path_module *avs_get_kcontrol_module(struct avs_dev *adev, u32 id)
+{
+ struct avs_path *path;
+ struct avs_path_pipeline *ppl;
+ struct avs_path_module *mod;
+
+ list_for_each_entry(path, &adev->path_list, node)
+ list_for_each_entry(ppl, &path->ppl_list, node)
+ list_for_each_entry(mod, &ppl->mod_list, node)
+ if (mod->template->ctl_id && mod->template->ctl_id == id)
+ return mod;
+
+ return NULL;
+}
+
+int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+ struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private;
+ struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol);
+ struct avs_volume_cfg *dspvols = NULL;
+ struct avs_path_module *active_module;
+ size_t num_dspvols;
+ int ret = 0;
+
+ /* prevent access to modules while path is being constructed */
+ mutex_lock(&adev->path_mutex);
+
+ active_module = avs_get_kcontrol_module(adev, ctl_data->id);
+ if (active_module) {
+ ret = avs_ipc_peakvol_get_volume(adev, active_module->module_id,
+ active_module->instance_id, &dspvols,
+ &num_dspvols);
+ if (!ret)
+ ucontrol->value.integer.value[0] = dspvols[0].target_volume;
+
+ ret = AVS_IPC_RET(ret);
+ kfree(dspvols);
+ } else {
+ ucontrol->value.integer.value[0] = ctl_data->volume;
+ }
+
+ mutex_unlock(&adev->path_mutex);
+ return ret;
+}
+
+int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+ struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private;
+ struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol);
+ long *volume = &ctl_data->volume;
+ struct avs_path_module *active_module;
+ struct avs_volume_cfg dspvol = {0};
+ long ctlvol = ucontrol->value.integer.value[0];
+ int ret = 0, changed = 0;
+
+ if (ctlvol < 0 || ctlvol > mc->max)
+ return -EINVAL;
+
+ /* prevent access to modules while path is being constructed */
+ mutex_lock(&adev->path_mutex);
+
+ if (*volume != ctlvol) {
+ *volume = ctlvol;
+ changed = 1;
+ }
+
+ active_module = avs_get_kcontrol_module(adev, ctl_data->id);
+ if (active_module) {
+ dspvol.channel_id = AVS_ALL_CHANNELS_MASK;
+ dspvol.target_volume = *volume;
+
+ ret = avs_ipc_peakvol_set_volume(adev, active_module->module_id,
+ active_module->instance_id, &dspvol);
+ ret = AVS_IPC_RET(ret);
+ }
+
+ mutex_unlock(&adev->path_mutex);
+
+ return ret ? ret : changed;
+}
diff --git a/sound/soc/intel/avs/control.h b/sound/soc/intel/avs/control.h
new file mode 100644
index 000000000000..08631bde13c3
--- /dev/null
+++ b/sound/soc/intel/avs/control.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+ *
+ * Authors: Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ * Cezary Rojewski <cezary.rojewski@intel.com>
+ */
+
+#ifndef __SOUND_SOC_INTEL_AVS_CTRL_H
+#define __SOUND_SOC_INTEL_AVS_CTRL_H
+
+#include <sound/control.h>
+
+struct avs_control_data {
+ u32 id;
+
+ long volume;
+};
+
+int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+
+#endif
diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c
index e11ae4246416..f887ab5b0311 100644
--- a/sound/soc/intel/avs/messages.c
+++ b/sound/soc/intel/avs/messages.c
@@ -702,6 +702,35 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
(u8 *)&cpr_fmt, sizeof(cpr_fmt));
}
+int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg *vol)
+{
+ return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, (u8 *)vol,
+ sizeof(*vol));
+}
+
+int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg **vols, size_t *num_vols)
+{
+ size_t payload_size;
+ u8 *payload;
+ int ret;
+
+ ret = avs_ipc_get_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, NULL, 0,
+ &payload, &payload_size);
+ if (ret)
+ return ret;
+
+ /* Non-zero payload expected for PEAKVOL_VOLUME. */
+ if (!payload_size)
+ return -EREMOTEIO;
+
+ *vols = (struct avs_volume_cfg *)payload;
+ *num_vols = payload_size / sizeof(**vols);
+
+ return 0;
+}
+
#ifdef CONFIG_DEBUG_FS
int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size)
{
diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h
index 9dd835527e02..d3b60ae7d743 100644
--- a/sound/soc/intel/avs/messages.h
+++ b/sound/soc/intel/avs/messages.h
@@ -561,6 +561,12 @@ int avs_ipc_set_system_time(struct avs_dev *adev);
#define AVS_COPIER_MOD_UUID \
GUID_INIT(0x9BA00C83, 0xCA12, 0x4A83, 0x94, 0x3C, 0x1F, 0xA2, 0xE8, 0x2F, 0x9D, 0xDA)
+#define AVS_PEAKVOL_MOD_UUID \
+ GUID_INIT(0x8A171323, 0x94A3, 0x4E1D, 0xAF, 0xE9, 0xFE, 0x5D, 0xBA, 0xa4, 0xC3, 0x93)
+
+#define AVS_GAIN_MOD_UUID \
+ GUID_INIT(0x61BCA9A8, 0x18D0, 0x4A18, 0x8E, 0x7B, 0x26, 0x39, 0x21, 0x98, 0x04, 0xB7)
+
#define AVS_KPBUFF_MOD_UUID \
GUID_INIT(0xA8A0CB32, 0x4A77, 0x4DB1, 0x85, 0xC7, 0x53, 0xD7, 0xEE, 0x07, 0xBC, 0xE6)
@@ -729,6 +735,19 @@ struct avs_copier_cfg {
struct avs_copier_gtw_cfg gtw_cfg;
} __packed;
+struct avs_volume_cfg {
+ u32 channel_id;
+ u32 target_volume;
+ u32 curve_type;
+ u32 reserved; /* alignment */
+ u64 curve_duration;
+} __packed;
+
+struct avs_peakvol_cfg {
+ struct avs_modcfg_base base;
+ struct avs_volume_cfg vols[];
+} __packed;
+
struct avs_micsel_cfg {
struct avs_modcfg_base base;
struct avs_audio_format out_fmt;
@@ -802,6 +821,20 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
const struct avs_audio_format *src_fmt,
const struct avs_audio_format *sink_fmt);
+enum avs_peakvol_runtime_param {
+ AVS_PEAKVOL_VOLUME = 0,
+};
+
+enum avs_audio_curve_type {
+ AVS_AUDIO_CURVE_NONE = 0,
+ AVS_AUDIO_CURVE_WINDOWS_FADE = 1,
+};
+
+int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg *vol);
+int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+ struct avs_volume_cfg **vols, size_t *num_vols);
+
#define AVS_PROBE_INST_ID 0
enum avs_probe_runtime_param {
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index ce157a8d6552..05302ab705ae 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -10,6 +10,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "avs.h"
+#include "control.h"
#include "path.h"
#include "topology.h"
@@ -264,6 +265,65 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
return ret;
}
+static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod)
+{
+ struct avs_tplg_module *t = mod->template;
+ struct avs_tplg_path_template *path_tmpl;
+ struct snd_soc_dapm_widget *w;
+ int i;
+
+ path_tmpl = t->owner->owner->owner;
+ w = path_tmpl->w;
+
+ for (i = 0; i < w->num_kcontrols; i++) {
+ struct avs_control_data *ctl_data;
+ struct soc_mixer_control *mc;
+
+ mc = (struct soc_mixer_control *)w->kcontrols[i]->private_value;
+ ctl_data = (struct avs_control_data *)mc->dobj.private;
+ if (ctl_data->id == t->ctl_id)
+ return ctl_data;
+ }
+
+ return NULL;
+}
+
+static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod)
+{
+ struct avs_tplg_module *t = mod->template;
+ struct avs_control_data *ctl_data;
+ struct avs_peakvol_cfg *cfg;
+ int volume = S32_MAX;
+ size_t size;
+ int ret;
+
+ ctl_data = avs_get_module_control(mod);
+ if (ctl_data)
+ volume = ctl_data->volume;
+
+ /* As 2+ channels controls are unsupported, have a single block for all channels. */
+ size = struct_size(cfg, vols, 1);
+ cfg = kzalloc(size, GFP_KERNEL);
+ if (!cfg)
+ return -ENOMEM;
+
+ cfg->base.cpc = t->cfg_base->cpc;
+ cfg->base.ibs = t->cfg_base->ibs;
+ cfg->base.obs = t->cfg_base->obs;
+ cfg->base.is_pages = t->cfg_base->is_pages;
+ cfg->base.audio_fmt = *t->in_fmt;
+ cfg->vols[0].target_volume = volume;
+ cfg->vols[0].channel_id = AVS_ALL_CHANNELS_MASK;
+ cfg->vols[0].curve_type = AVS_AUDIO_CURVE_NONE;
+ cfg->vols[0].curve_duration = 0;
+
+ ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
+ t->domain, cfg, size, &mod->instance_id);
+
+ kfree(cfg);
+ return ret;
+}
+
static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod)
{
struct avs_tplg_module *t = mod->template;
@@ -465,6 +525,8 @@ static struct avs_module_create avs_module_create[] = {
{ &AVS_MIXOUT_MOD_UUID, avs_modbase_create },
{ &AVS_KPBUFF_MOD_UUID, avs_modbase_create },
{ &AVS_COPIER_MOD_UUID, avs_copier_create },
+ { &AVS_PEAKVOL_MOD_UUID, avs_peakvol_create },
+ { &AVS_GAIN_MOD_UUID, avs_peakvol_create },
{ &AVS_MICSEL_MOD_UUID, avs_micsel_create },
{ &AVS_MUX_MOD_UUID, avs_mux_create },
{ &AVS_UPDWMIX_MOD_UUID, avs_updown_mix_create },
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index e845eaf0a1e7..5fee7a8ec06a 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -13,6 +13,7 @@
#include <sound/soc-topology.h>
#include <uapi/sound/intel/avs/tokens.h>
#include "avs.h"
+#include "control.h"
#include "topology.h"
/* Get pointer to vendor array at the specified offset. */
@@ -1070,6 +1071,12 @@ static const struct avs_tplg_token_parser module_parsers[] = {
.offset = offsetof(struct avs_tplg_module, cfg_ext),
.parse = avs_parse_modcfg_ext_ptr,
},
+ {
+ .token = AVS_TKN_MOD_KCONTROL_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_tplg_module, ctl_id),
+ .parse = avs_parse_byte_token,
+ },
};
static struct avs_tplg_module *
@@ -1435,6 +1442,16 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
return 0;
}
+static int avs_widget_ready(struct snd_soc_component *comp, int index,
+ struct snd_soc_dapm_widget *w,
+ struct snd_soc_tplg_dapm_widget *dw)
+{
+ struct avs_tplg_path_template *template = w->priv;
+
+ template->w = w;
+ return 0;
+}
+
static int avs_dai_load(struct snd_soc_component *comp, int index,
struct snd_soc_dai_driver *dai_drv, struct snd_soc_tplg_pcm *pcm,
struct snd_soc_dai *dai)
@@ -1586,9 +1603,68 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
return avs_tplg_parse_bindings(comp, tuples, remaining);
}
+#define AVS_CONTROL_OPS_VOLUME 257
+
+static const struct snd_soc_tplg_kcontrol_ops avs_control_ops[] = {
+ {
+ .id = AVS_CONTROL_OPS_VOLUME,
+ .get = avs_control_volume_get,
+ .put = avs_control_volume_put,
+ },
+};
+
+static const struct avs_tplg_token_parser control_parsers[] = {
+ {
+ .token = AVS_TKN_KCONTROL_ID_U32,
+ .type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+ .offset = offsetof(struct avs_control_data, id),
+ .parse = avs_parse_word_token,
+ },
+};
+
+static int
+avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_new *ctmpl,
+ struct snd_soc_tplg_ctl_hdr *hdr)
+{
+ struct snd_soc_tplg_vendor_array *tuples;
+ struct snd_soc_tplg_mixer_control *tmc;
+ struct avs_control_data *ctl_data;
+ struct soc_mixer_control *mc;
+ size_t block_size;
+ int ret;
+
+ switch (hdr->type) {
+ case SND_SOC_TPLG_TYPE_MIXER:
+ tmc = container_of(hdr, typeof(*tmc), hdr);
+ tuples = tmc->priv.array;
+ block_size = le32_to_cpu(tmc->priv.size);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ctl_data = devm_kzalloc(comp->card->dev, sizeof(*ctl_data), GFP_KERNEL);
+ if (!ctl_data)
+ return -ENOMEM;
+
+ ret = parse_dictionary_entries(comp, tuples, block_size, ctl_data, 1, sizeof(*ctl_data),
+ AVS_TKN_KCONTROL_ID_U32, control_parsers,
+ ARRAY_SIZE(control_parsers));
+ if (ret)
+ return ret;
+
+ mc = (struct soc_mixer_control *)ctmpl->private_value;
+ mc->dobj.private = ctl_data;
+ return 0;
+}
+
static struct snd_soc_tplg_ops avs_tplg_ops = {
+ .io_ops = avs_control_ops,
+ .io_ops_count = ARRAY_SIZE(avs_control_ops),
+ .control_load = avs_control_load,
.dapm_route_load = avs_route_load,
.widget_load = avs_widget_load,
+ .widget_ready = avs_widget_ready,
.dai_load = avs_dai_load,
.link_load = avs_link_load,
.manifest = avs_manifest,
diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h
index 68e5f6312353..6e1c8e9b2496 100644
--- a/sound/soc/intel/avs/topology.h
+++ b/sound/soc/intel/avs/topology.h
@@ -138,6 +138,8 @@ struct avs_tplg_path_template_id {
struct avs_tplg_path_template {
u32 id;
+ struct snd_soc_dapm_widget *w;
+
struct list_head path_list;
struct avs_tplg *owner;
@@ -180,6 +182,7 @@ struct avs_tplg_module {
u8 core_id;
u8 domain;
struct avs_tplg_modcfg_ext *cfg_ext;
+ u32 ctl_id;
struct avs_tplg_pipeline *owner;
/* Pipeline modules management. */
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index 4e0e9b778d4c..ec37da331a91 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -145,18 +145,12 @@ static int e740_probe(struct platform_device *pdev)
return ret;
}
-static int e740_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver e740_driver = {
.driver = {
.name = "e740-audio",
.pm = &snd_soc_pm_ops,
},
.probe = e740_probe,
- .remove = e740_remove,
};
module_platform_driver(e740_driver);
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 7a1e0d8bfd11..60b22d4f92a7 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -124,18 +124,12 @@ static int e750_probe(struct platform_device *pdev)
return ret;
}
-static int e750_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver e750_driver = {
.driver = {
.name = "e750-audio",
.pm = &snd_soc_pm_ops,
},
.probe = e750_probe,
- .remove = e750_remove,
};
module_platform_driver(e750_driver);
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index a39c494127cf..c7756acd888a 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -124,18 +124,12 @@ static int e800_probe(struct platform_device *pdev)
return ret;
}
-static int e800_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver e800_driver = {
.driver = {
.name = "e800-audio",
.pm = &snd_soc_pm_ops,
},
.probe = e800_probe,
- .remove = e800_remove,
};
module_platform_driver(e800_driver);
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 44303b6eb228..70442315f5c5 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -306,18 +306,12 @@ static int spitz_probe(struct platform_device *pdev)
return ret;
}
-static int spitz_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver spitz_driver = {
.driver = {
.name = "spitz-audio",
.pm = &snd_soc_pm_ops,
},
.probe = spitz_probe,
- .remove = spitz_remove,
};
module_platform_driver(spitz_driver);
diff --git a/sound/soc/sof/amd/acp-dsp-offset.h b/sound/soc/sof/amd/acp-dsp-offset.h
index de5726251dc6..920155dee819 100644
--- a/sound/soc/sof/amd/acp-dsp-offset.h
+++ b/sound/soc/sof/amd/acp-dsp-offset.h
@@ -85,4 +85,8 @@
#define ACP_SCRATCH_REG_0 0x10000
#define ACP6X_DSP_FUSION_RUNSTALL 0x0644
+
+/* Cache window registers */
+#define ACP_DSP0_CACHE_OFFSET0 0x0420
+#define ACP_DSP0_CACHE_SIZE0 0x0424
#endif
diff --git a/sound/soc/sof/amd/acp-loader.c b/sound/soc/sof/amd/acp-loader.c
index 090c8b18c83c..a4bce5a3ae48 100644
--- a/sound/soc/sof/amd/acp-loader.c
+++ b/sound/soc/sof/amd/acp-loader.c
@@ -151,6 +151,7 @@ static void configure_pte_for_fw_loading(int type, int num_pages, struct acp_dev
int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
{
struct pci_dev *pci = to_pci_dev(sdev->dev);
+ const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
struct acp_dev_data *adata;
unsigned int src_addr, size_fw;
u32 page_count, dma_size;
@@ -183,6 +184,12 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev)
if (ret < 0)
dev_err(sdev->dev, "acp dma transfer status: %d\n", ret);
+ if (desc->rev > 3) {
+ /* Cache Window enable */
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP0_CACHE_OFFSET0, desc->sram_pte_offset);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP0_CACHE_SIZE0, SRAM1_SIZE | BIT(31));
+ }
+
/* Free memory once DMA is complete */
dma_size = (PAGE_ALIGN(sdev->basefw.fw->size) >> PAGE_SHIFT) * ACP_PAGE_SIZE;
dma_free_coherent(&pci->dev, dma_size, adata->bin_buf, adata->sha_dma_addr);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index 09e16ef8afa0..4314094a97fd 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -72,6 +72,8 @@
#define EXCEPT_MAX_HDR_SIZE 0x400
#define AMD_STACK_DUMP_SIZE 32
+#define SRAM1_SIZE 0x13A000
+
enum clock_source {
ACP_CLOCK_96M = 0,
ACP_CLOCK_48M,
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
index 625977a29d8a..26a3f7c8c914 100644
--- a/sound/soc/sof/core.c
+++ b/sound/soc/sof/core.c
@@ -362,6 +362,9 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
sdev->first_boot = true;
dev_set_drvdata(dev, sdev);
+ if (sof_core_debug)
+ dev_info(dev, "sof_debug value: %#x\n", sof_core_debug);
+
/* check IPC support */
if (!(BIT(plat_data->ipc_type) & plat_data->desc->ipc_supported_mask)) {
dev_err(dev, "ipc_type %d is not supported on this platform, mask is %#x\n",
diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
index b94cc40485ed..989395999d6e 100644
--- a/sound/soc/sof/ipc3-topology.c
+++ b/sound/soc/sof/ipc3-topology.c
@@ -1651,6 +1651,7 @@ static int sof_ipc3_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *
static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol)
{
struct sof_ipc_ctrl_data *cdata;
+ size_t priv_size_check;
int ret;
if (scontrol->max_size < (sizeof(*cdata) + sizeof(struct sof_abi_hdr))) {
@@ -1694,8 +1695,10 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_
goto err;
}
- if (cdata->data->size + sizeof(struct sof_abi_hdr) != scontrol->priv_size) {
- dev_err(sdev->dev, "Conflict in bytes vs. priv size.\n");
+ priv_size_check = cdata->data->size + sizeof(struct sof_abi_hdr);
+ if (priv_size_check != scontrol->priv_size) {
+ dev_err(sdev->dev, "Conflict in bytes (%zu) vs. priv size (%zu).\n",
+ priv_size_check, scontrol->priv_size);
ret = -EINVAL;
goto err;
}
diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c
index 3c81e84fcecf..7c831e18483c 100644
--- a/sound/soc/sof/mediatek/mt8195/mt8195.c
+++ b/sound/soc/sof/mediatek/mt8195/mt8195.c
@@ -215,11 +215,6 @@ static int platform_parse_resource(struct platform_device *pdev, void *data)
adsp->pa_sram = (phys_addr_t)mmio->start;
adsp->sramsize = resource_size(mmio);
- if (adsp->sramsize < TOTAL_SIZE_SHARED_SRAM_FROM_TAIL) {
- dev_err(dev, "adsp SRAM(%#x) is not enough for share\n",
- adsp->sramsize);
- return -EINVAL;
- }
dev_dbg(dev, "sram pbase=%pa,%#x\n", &adsp->pa_sram, adsp->sramsize);
diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.h b/sound/soc/sof/mediatek/mt8195/mt8195.h
index 7ffd523f936c..b4229170049f 100644
--- a/sound/soc/sof/mediatek/mt8195/mt8195.h
+++ b/sound/soc/sof/mediatek/mt8195/mt8195.h
@@ -139,8 +139,6 @@ struct snd_sof_dev;
#define DSP_MBOX1_BAR 6
#define DSP_MBOX2_BAR 7
-#define TOTAL_SIZE_SHARED_SRAM_FROM_TAIL 0x0
-
#define SIZE_SHARED_DRAM_DL 0x40000 /*Shared buffer for Downlink*/
#define SIZE_SHARED_DRAM_UL 0x40000 /*Shared buffer for Uplink*/
diff --git a/sound/soc/sof/nocodec.c b/sound/soc/sof/nocodec.c
index 3537805070ad..b13bfdeb2b70 100644
--- a/sound/soc/sof/nocodec.c
+++ b/sound/soc/sof/nocodec.c
@@ -103,14 +103,8 @@ static int sof_nocodec_probe(struct platform_device *pdev)
return devm_snd_soc_register_card(&pdev->dev, card);
}
-static int sof_nocodec_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
static struct platform_driver sof_nocodec_audio = {
.probe = sof_nocodec_probe,
- .remove = sof_nocodec_remove,
.driver = {
.name = "sof-nocodec",
.pm = &snd_soc_pm_ops,