aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/nau8821.txt55
-rw-r--r--Documentation/devicetree/bindings/sound/nuvoton,nau8821.yaml125
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt101
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml160
-rw-r--r--sound/soc/codecs/Kconfig1
-rw-r--r--sound/soc/codecs/rt5645.c50
-rw-r--r--sound/soc/codecs/rt722-sdca-sdw.c2
-rw-r--r--sound/soc/codecs/rt722-sdca.c3
-rw-r--r--sound/soc/codecs/tas2781-i2c.c1
-rw-r--r--sound/soc/dwc/dwc-i2s.c65
-rw-r--r--sound/soc/dwc/dwc-pcm.c8
-rw-r--r--sound/soc/dwc/local.h24
-rw-r--r--sound/soc/fsl/imx-pcm-rpmsg.c12
-rw-r--r--sound/soc/soc-core.c144
-rw-r--r--sound/soc/sof/amd/acp.c34
-rw-r--r--sound/soc/sof/amd/acp.h4
16 files changed, 533 insertions, 256 deletions
diff --git a/Documentation/devicetree/bindings/sound/nau8821.txt b/Documentation/devicetree/bindings/sound/nau8821.txt
deleted file mode 100644
index 7c84e7c7327a..000000000000
--- a/Documentation/devicetree/bindings/sound/nau8821.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-Nuvoton NAU88L21 audio codec
-
-This device supports I2C only.
-
-Required properties:
- - compatible : Must be "nuvoton,nau8821"
-
- - reg : the I2C address of the device. This is either 0x1B (CSB=0) or 0x54 (CSB=1).
-
-Optional properties:
- - nuvoton,jkdet-enable: Enable jack detection via JKDET pin.
- - nuvoton,jkdet-pull-enable: Enable JKDET pin pull. If set - pin pull enabled,
- otherwise pin in high impedance state.
- - nuvoton,jkdet-pull-up: Pull-up JKDET pin. If set then JKDET pin is pull up, otherwise pull down.
- - nuvoton,jkdet-polarity: JKDET pin polarity. 0 - active high, 1 - active low.
-
- - nuvoton,vref-impedance: VREF Impedance selection
- 0 - Open
- 1 - 25 kOhm
- 2 - 125 kOhm
- 3 - 2.5 kOhm
-
- - nuvoton,micbias-voltage: Micbias voltage level.
- 0 - VDDA
- 1 - VDDA
- 2 - VDDA * 1.1
- 3 - VDDA * 1.2
- 4 - VDDA * 1.3
- 5 - VDDA * 1.4
- 6 - VDDA * 1.53
- 7 - VDDA * 1.53
-
- - nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
- - nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
-
- - nuvoton,dmic-clk-threshold: the ADC threshold of DMIC clock.
- - nuvoton,key_enable: Headset button detection switch.
-
-Example:
-
- headset: nau8821@1b {
- compatible = "nuvoton,nau8821";
- reg = <0x1b>;
- interrupt-parent = <&gpio>;
- interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
- nuvoton,jkdet-enable;
- nuvoton,jkdet-pull-enable;
- nuvoton,jkdet-pull-up;
- nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
- nuvoton,vref-impedance = <2>;
- nuvoton,micbias-voltage = <6>;
- nuvoton,jack-insert-debounce = <7>;
- nuvoton,jack-eject-debounce = <7>;
- nuvoton,dmic-clk-threshold = 3072000;
- };
diff --git a/Documentation/devicetree/bindings/sound/nuvoton,nau8821.yaml b/Documentation/devicetree/bindings/sound/nuvoton,nau8821.yaml
new file mode 100644
index 000000000000..fc2f4ce4db88
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nuvoton,nau8821.yaml
@@ -0,0 +1,125 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/nuvoton,nau8821.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NAU88L21 audio codec
+
+maintainers:
+ - Seven Lee <[email protected]>
+
+allOf:
+ - $ref: dai-common.yaml#
+
+properties:
+ compatible:
+ const: nuvoton,nau8821
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ nuvoton,jkdet-enable:
+ description: Enable jack detection via JKDET pin.
+ type: boolean
+
+ nuvoton,jkdet-pull-enable:
+ description: Enable JKDET pin pull. If set - pin pull enabled,
+ otherwise pin in high impedance state.
+ type: boolean
+
+ nuvoton,jkdet-pull-up:
+ description: Pull-up JKDET pin. If set then JKDET pin is pull up,
+ otherwise pull down.
+ type: boolean
+
+ nuvoton,key-enable:
+ description: handles key press detection.
+ type: boolean
+
+ nuvoton,jkdet-polarity:
+ description: JKDET pin polarity.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum:
+ - 0 # active high
+ - 1 # active low
+ default: 1
+
+ nuvoton,micbias-voltage:
+ description: MICBIAS output level select.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum:
+ - 0 # VDDA
+ - 1 # VDDA * 1
+ - 2 # VDDA * 1.1
+ - 3 # VDDA * 1.2
+ - 4 # VDDA * 1.3
+ - 5 # VDDA * 1.4
+ - 6 # VDDA * 1.53
+ - 7 # VDDA * 1.53
+ default: 6
+
+ nuvoton,vref-impedance:
+ description: VMID Tie-off impedance select.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum:
+ - 0 # open
+ - 1 # 25KOhms
+ - 2 # 125KOhms
+ - 3 # 2.5KOhms
+ default: 2
+
+ nuvoton,jack-insert-debounce:
+ description: number from 0 to 7 that sets debounce time to 2^(n+2)ms.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 7
+ default: 7
+
+ nuvoton,jack-eject-debounce:
+ description: number from 0 to 7 that sets debounce time to 2^(n+2)ms.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ maximum: 7
+ default: 0
+
+ nuvoton,dmic-clk-threshold:
+ description: DMIC clock speed expected value. Unit is Hz.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ default: 3072000
+
+ '#sound-dai-cells':
+ const: 0
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ codec@1b {
+ compatible = "nuvoton,nau8821";
+ reg = <0x1b>;
+ interrupt-parent = <&gpio>;
+ interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
+ nuvoton,jkdet-enable;
+ nuvoton,jkdet-pull-enable;
+ nuvoton,jkdet-pull-up;
+ nuvoton,key-enable;
+ nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
+ nuvoton,micbias-voltage = <6>;
+ nuvoton,vref-impedance = <2>;
+ nuvoton,jack-insert-debounce = <7>;
+ nuvoton,jack-eject-debounce = <0>;
+ nuvoton,dmic-clk-threshold = <3072000>;
+ #sound-dai-cells = <0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt b/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt
deleted file mode 100644
index e7d17dda55db..000000000000
--- a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-msm8916 analog audio CODEC
-
-Bindings for codec Analog IP which is integrated in pmic pm8916,
-
-## Bindings for codec core on pmic:
-
-Required properties
- - compatible = "qcom,pm8916-wcd-analog-codec";
- - reg: represents the slave base address provided to the peripheral.
- - interrupts: List of interrupts in given SPMI peripheral.
- - interrupt-names: Names specified to above list of interrupts in same
- order. List of supported interrupt names are:
- "cdc_spk_cnp_int" - Speaker click and pop interrupt.
- "cdc_spk_clip_int" - Speaker clip interrupt.
- "cdc_spk_ocp_int" - Speaker over current protect interrupt.
- "mbhc_ins_rem_det1" - jack insert removal detect interrupt 1.
- "mbhc_but_rel_det" - button release interrupt.
- "mbhc_but_press_det" - button press event
- "mbhc_ins_rem_det" - jack insert removal detect interrupt.
- "mbhc_switch_int" - multi button headset interrupt.
- "cdc_ear_ocp_int" - Earphone over current protect interrupt.
- "cdc_hphr_ocp_int" - Headphone R over current protect interrupt.
- "cdc_hphl_ocp_det" - Headphone L over current protect interrupt.
- "cdc_ear_cnp_int" - earphone cnp interrupt.
- "cdc_hphr_cnp_int" - hphr click and pop interrupt.
- "cdc_hphl_cnp_int" - hphl click and pop interrupt.
-
- - clocks: Handle to mclk.
- - clock-names: should be "mclk"
- - vdd-cdc-io-supply: phandle to VDD_CDC_IO regulator DT node.
- - vdd-cdc-tx-rx-cx-supply: phandle to VDD_CDC_TX/RX/CX regulator DT node.
- - vdd-micbias-supply: phandle of VDD_MICBIAS supply's regulator DT node.
-
-Optional Properties:
- - qcom,mbhc-vthreshold-low: Array of 5 threshold voltages in mV for 5 buttons
- detection on headset when the mbhc is powered up
- by internal current source, this is a low power.
- - qcom,mbhc-vthreshold-high: Array of 5 thresold voltages in mV for 5 buttons
- detection on headset when mbhc is powered up
- from micbias.
-- qcom,micbias-lvl: Voltage (mV) for Mic Bias
-- qcom,hphl-jack-type-normally-open: boolean, present if hphl pin on jack is a
- NO (Normally Open). If not specified, then
- its assumed that hphl pin on jack is NC
- (Normally Closed).
-- qcom,gnd-jack-type-normally-open: boolean, present if gnd pin on jack is
- NO (Normally Open). If not specified, then
- its assumed that gnd pin on jack is NC
- (Normally Closed).
-- qcom,micbias1-ext-cap: boolean, present if micbias1 has external capacitor
- connected.
-- qcom,micbias2-ext-cap: boolean, present if micbias2 has external capacitor
- connected.
-
-Example:
-
-spmi_bus {
- ...
- audio-codec@f000{
- compatible = "qcom,pm8916-wcd-analog-codec";
- reg = <0xf000 0x200>;
- reg-names = "pmic-codec-core";
- clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
- clock-names = "mclk";
- qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
- qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
- interrupt-parent = <&spmi_bus>;
- interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
- <0x1 0xf0 0x1 IRQ_TYPE_NONE>,
- <0x1 0xf0 0x2 IRQ_TYPE_NONE>,
- <0x1 0xf0 0x3 IRQ_TYPE_NONE>,
- <0x1 0xf0 0x4 IRQ_TYPE_NONE>,
- <0x1 0xf0 0x5 IRQ_TYPE_NONE>,
- <0x1 0xf0 0x6 IRQ_TYPE_NONE>,
- <0x1 0xf0 0x7 IRQ_TYPE_NONE>,
- <0x1 0xf1 0x0 IRQ_TYPE_NONE>,
- <0x1 0xf1 0x1 IRQ_TYPE_NONE>,
- <0x1 0xf1 0x2 IRQ_TYPE_NONE>,
- <0x1 0xf1 0x3 IRQ_TYPE_NONE>,
- <0x1 0xf1 0x4 IRQ_TYPE_NONE>,
- <0x1 0xf1 0x5 IRQ_TYPE_NONE>;
- interrupt-names = "cdc_spk_cnp_int",
- "cdc_spk_clip_int",
- "cdc_spk_ocp_int",
- "mbhc_ins_rem_det1",
- "mbhc_but_rel_det",
- "mbhc_but_press_det",
- "mbhc_ins_rem_det",
- "mbhc_switch_int",
- "cdc_ear_ocp_int",
- "cdc_hphr_ocp_int",
- "cdc_hphl_ocp_det",
- "cdc_ear_cnp_int",
- "cdc_hphr_cnp_int",
- "cdc_hphl_cnp_int";
- vdd-cdc-io-supply = <&pm8916_l5>;
- vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
- vdd-micbias-supply = <&pm8916_l13>;
- #sound-dai-cells = <1>;
- };
-};
diff --git a/Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml b/Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml
new file mode 100644
index 000000000000..c385028c4296
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml
@@ -0,0 +1,160 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/qcom,pm8916-wcd-analog-codec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm PM8916 WCD Analog Audio Codec
+
+maintainers:
+ - Konrad Dybcio <[email protected]>
+
+description:
+ The analog WCD audio codec found on Qualcomm PM8916 PMIC.
+
+properties:
+ compatible:
+ const: qcom,pm8916-wcd-analog-codec
+
+ reg:
+ maxItems: 1
+
+ reg-names:
+ items:
+ - const: pmic-codec-core
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: mclk
+
+ interrupts:
+ maxItems: 14
+
+ interrupt-names:
+ items:
+ - const: cdc_spk_cnp_int
+ - const: cdc_spk_clip_int
+ - const: cdc_spk_ocp_int
+ - const: mbhc_ins_rem_det1
+ - const: mbhc_but_rel_det
+ - const: mbhc_but_press_det
+ - const: mbhc_ins_rem_det
+ - const: mbhc_switch_int
+ - const: cdc_ear_ocp_int
+ - const: cdc_hphr_ocp_int
+ - const: cdc_hphl_ocp_det
+ - const: cdc_ear_cnp_int
+ - const: cdc_hphr_cnp_int
+ - const: cdc_hphl_cnp_int
+
+ vdd-cdc-io-supply:
+ description: 1.8V buck supply
+
+ vdd-cdc-tx-rx-cx-supply:
+ description: 1.8V SIDO buck supply
+
+ vdd-micbias-supply:
+ description: micbias supply
+
+ qcom,mbhc-vthreshold-low:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description:
+ Array of 5 threshold voltages in mV for 5-button detection on
+ headset when MBHC is powered by an internal current source.
+ minItems: 5
+ maxItems: 5
+
+ qcom,mbhc-vthreshold-high:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description:
+ Array of 5 threshold voltages in mV for 5-button detection on
+ headset when MBHC is powered from micbias.
+ minItems: 5
+ maxItems: 5
+
+ qcom,micbias-lvl:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Voltage (mV) for Mic Bias
+
+ qcom,hphl-jack-type-normally-open:
+ type: boolean
+ description:
+ True if the HPHL pin on the jack is NO (Normally Open), false if it's
+ NC (Normally Closed).
+
+ qcom,gnd-jack-type-normally-open:
+ type: boolean
+ description:
+ True if the GND pin on the jack is NO (Normally Open), false if it's
+ NC (Normally Closed).
+
+ qcom,micbias1-ext-cap:
+ type: boolean
+ description:
+ True if micbias1 has an external capacitor.
+
+ qcom,micbias2-ext-cap:
+ type: boolean
+ description:
+ True if micbias2 has an external capacitor.
+
+ "#sound-dai-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,gcc-msm8916.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ audio-codec@f000{
+ compatible = "qcom,pm8916-wcd-analog-codec";
+ reg = <0xf000 0x200>;
+ reg-names = "pmic-codec-core";
+ clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
+ clock-names = "mclk";
+ qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
+ qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x5 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x6 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x7 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x5 IRQ_TYPE_NONE>;
+ interrupt-names = "cdc_spk_cnp_int",
+ "cdc_spk_clip_int",
+ "cdc_spk_ocp_int",
+ "mbhc_ins_rem_det1",
+ "mbhc_but_rel_det",
+ "mbhc_but_press_det",
+ "mbhc_ins_rem_det",
+ "mbhc_switch_int",
+ "cdc_ear_ocp_int",
+ "cdc_hphr_ocp_int",
+ "cdc_hphl_ocp_det",
+ "cdc_ear_cnp_int",
+ "cdc_hphr_cnp_int",
+ "cdc_hphl_cnp_int";
+ vdd-cdc-io-supply = <&pm8916_l5>;
+ vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
+ vdd-micbias-supply = <&pm8916_l13>;
+ #sound-dai-cells = <1>;
+ };
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 42146b436ac3..88c3dbe47d71 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1720,6 +1720,7 @@ config SND_SOC_STA529
config SND_SOC_STAC9766
tristate
depends on SND_SOC_AC97_BUS
+ select REGMAP_AC97
config SND_SOC_STI_SAS
tristate "codec Audio support for STI SAS codec"
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index a506d940a2ea..5be5ec0260e9 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3258,6 +3258,22 @@ int rt5645_set_jack_detect(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL(rt5645_set_jack_detect);
+static int rt5645_component_set_jack(struct snd_soc_component *component,
+ struct snd_soc_jack *hs_jack, void *data)
+{
+ struct snd_soc_jack *mic_jack = NULL;
+ struct snd_soc_jack *btn_jack = NULL;
+ int *type = (int *)data;
+
+ if (*type & SND_JACK_MICROPHONE)
+ mic_jack = hs_jack;
+ if (*type & (SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3))
+ btn_jack = hs_jack;
+
+ return rt5645_set_jack_detect(component, hs_jack, mic_jack, btn_jack);
+}
+
static void rt5645_jack_detect_work(struct work_struct *work)
{
struct rt5645_priv *rt5645 =
@@ -3532,6 +3548,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt5645 = {
.num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets),
.dapm_routes = rt5645_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes),
+ .set_jack = rt5645_component_set_jack,
.use_pmdown_time = 1,
.endianness = 1,
};
@@ -4182,11 +4199,44 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
regmap_write(rt5645->regmap, RT5645_RESET, 0);
}
+static int __maybe_unused rt5645_sys_suspend(struct device *dev)
+{
+ struct rt5645_priv *rt5645 = dev_get_drvdata(dev);
+
+ del_timer_sync(&rt5645->btn_check_timer);
+ cancel_delayed_work_sync(&rt5645->jack_detect_work);
+ cancel_delayed_work_sync(&rt5645->rcclock_work);
+
+ regcache_cache_only(rt5645->regmap, true);
+ regcache_mark_dirty(rt5645->regmap);
+ return 0;
+}
+
+static int __maybe_unused rt5645_sys_resume(struct device *dev)
+{
+ struct rt5645_priv *rt5645 = dev_get_drvdata(dev);
+
+ regcache_cache_only(rt5645->regmap, false);
+ regcache_sync(rt5645->regmap);
+
+ if (rt5645->hp_jack) {
+ rt5645->jack_type = 0;
+ queue_delayed_work(system_power_efficient_wq,
+ &rt5645->jack_detect_work, msecs_to_jiffies(0));
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops rt5645_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(rt5645_sys_suspend, rt5645_sys_resume)
+};
+
static struct i2c_driver rt5645_i2c_driver = {
.driver = {
.name = "rt5645",
.of_match_table = of_match_ptr(rt5645_of_match),
.acpi_match_table = ACPI_PTR(rt5645_acpi_match),
+ .pm = &rt5645_pm,
},
.probe = rt5645_i2c_probe,
.remove = rt5645_i2c_remove,
diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c
index cc57e4e27805..a9416bd163e8 100644
--- a/sound/soc/codecs/rt722-sdca-sdw.c
+++ b/sound/soc/codecs/rt722-sdca-sdw.c
@@ -175,7 +175,7 @@ static int rt722_sdca_update_status(struct sdw_slave *slave,
* This also could sync with the cache value as the rt722_sdca_jack_init set.
*/
sdw_write_no_pm(rt722->slave, SDW_SCP_SDCA_INTMASK1,
- SDW_SCP_SDCA_INTMASK_SDCA_0 | SDW_SCP_SDCA_INTMASK_SDCA_6);
+ SDW_SCP_SDCA_INTMASK_SDCA_6);
sdw_write_no_pm(rt722->slave, SDW_SCP_SDCA_INTMASK2,
SDW_SCP_SDCA_INTMASK_SDCA_8);
}
diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c
index 9c0d34366c9e..0e1c65a20392 100644
--- a/sound/soc/codecs/rt722-sdca.c
+++ b/sound/soc/codecs/rt722-sdca.c
@@ -191,8 +191,7 @@ static void rt722_sdca_jack_detect_handler(struct work_struct *work)
return;
/* SDW_SCP_SDCA_INT_SDCA_6 is used for jack detection */
- if (rt722->scp_sdca_stat1 & SDW_SCP_SDCA_INT_SDCA_6 ||
- rt722->scp_sdca_stat1 & SDW_SCP_SDCA_INT_SDCA_0) {
+ if (rt722->scp_sdca_stat1 & SDW_SCP_SDCA_INT_SDCA_6) {
ret = rt722_sdca_headset_detect(rt722);
if (ret < 0)
return;
diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c
index 4c59429a42b7..55cd5e3c23a5 100644
--- a/sound/soc/codecs/tas2781-i2c.c
+++ b/sound/soc/codecs/tas2781-i2c.c
@@ -743,7 +743,6 @@ MODULE_DEVICE_TABLE(acpi, tasdevice_acpi_match);
static struct i2c_driver tasdevice_i2c_driver = {
.driver = {
.name = "tas2781-codec",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(tasdevice_of_match),
#ifdef CONFIG_ACPI
.acpi_match_table = ACPI_PTR(tasdevice_acpi_match),
diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c
index 97d652f0e84d..1f1ee14b04e6 100644
--- a/sound/soc/dwc/dwc-i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
@@ -183,7 +183,15 @@ static void i2s_start(struct dw_i2s_dev *dev,
{
struct i2s_clk_config_data *config = &dev->config;
- i2s_write_reg(dev->i2s_base, IER, 1);
+ u32 reg = IER_IEN;
+
+ if (dev->tdm_slots) {
+ reg |= (dev->tdm_slots - 1) << IER_TDM_SLOTS_SHIFT;
+ reg |= IER_INTF_TYPE;
+ reg |= dev->frame_offset << IER_FRAME_OFF_SHIFT;
+ }
+
+ i2s_write_reg(dev->i2s_base, IER, reg);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
i2s_write_reg(dev->i2s_base, ITER, 1);
@@ -233,13 +241,15 @@ static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
dev->xfer_resolution);
i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
dev->fifo_th - 1);
- i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
+ i2s_write_reg(dev->i2s_base, TER(ch_reg), TER_TXCHEN |
+ dev->tdm_mask << TER_TXSLOT_SHIFT);
} else {
i2s_write_reg(dev->i2s_base, RCR(ch_reg),
dev->xfer_resolution);
i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
dev->fifo_th - 1);
- i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
+ i2s_write_reg(dev->i2s_base, RER(ch_reg), RER_RXCHEN |
+ dev->tdm_mask << RER_RXSLOT_SHIFT);
}
}
@@ -276,6 +286,9 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
+ if (dev->tdm_slots)
+ config->data_width = 32;
+
config->chan_nr = params_channels(params);
switch (config->chan_nr) {
@@ -384,14 +397,58 @@ static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
ret = -EINVAL;
break;
}
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_LEFT_J:
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ dev->frame_offset = 1;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ dev->frame_offset = 0;
+ break;
+ default:
+ dev_err(dev->dev, "DAI format unsupported");
+ return -EINVAL;
+ }
+
return ret;
}
+static int dw_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+{
+ struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
+
+ if (slot_width != 32)
+ return -EINVAL;
+
+ if (slots < 0 || slots > 16)
+ return -EINVAL;
+
+ if (rx_mask != tx_mask)
+ return -EINVAL;
+
+ if (!rx_mask)
+ return -EINVAL;
+
+ dev->tdm_slots = slots;
+ dev->tdm_mask = rx_mask;
+
+ dev->l_reg = RSLOT_TSLOT(ffs(rx_mask) - 1);
+ dev->r_reg = RSLOT_TSLOT(fls(rx_mask) - 1);
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops dw_i2s_dai_ops = {
.hw_params = dw_i2s_hw_params,
.prepare = dw_i2s_prepare,
.trigger = dw_i2s_trigger,
.set_fmt = dw_i2s_set_fmt,
+ .set_tdm_slot = dw_i2s_set_tdm_slot,
};
#ifdef CONFIG_PM
@@ -726,6 +783,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
if (irq >= 0) {
ret = dw_pcm_register(pdev);
dev->use_pio = true;
+ dev->l_reg = LRBR_LTHR(0);
+ dev->r_reg = RRBR_RTHR(0);
} else {
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
0);
diff --git a/sound/soc/dwc/dwc-pcm.c b/sound/soc/dwc/dwc-pcm.c
index 9f25631d43d3..f99262b89008 100644
--- a/sound/soc/dwc/dwc-pcm.c
+++ b/sound/soc/dwc/dwc-pcm.c
@@ -31,8 +31,8 @@ static unsigned int dw_pcm_tx_##sample_bits(struct dw_i2s_dev *dev, \
int i; \
\
for (i = 0; i < dev->fifo_th; i++) { \
- iowrite32(p[tx_ptr][0], dev->i2s_base + LRBR_LTHR(0)); \
- iowrite32(p[tx_ptr][1], dev->i2s_base + RRBR_RTHR(0)); \
+ iowrite32(p[tx_ptr][0], dev->i2s_base + dev->l_reg); \
+ iowrite32(p[tx_ptr][1], dev->i2s_base + dev->r_reg); \
period_pos++; \
if (++tx_ptr >= runtime->buffer_size) \
tx_ptr = 0; \
@@ -51,8 +51,8 @@ static unsigned int dw_pcm_rx_##sample_bits(struct dw_i2s_dev *dev, \
int i; \
\
for (i = 0; i < dev->fifo_th; i++) { \
- p[rx_ptr][0] = ioread32(dev->i2s_base + LRBR_LTHR(0)); \
- p[rx_ptr][1] = ioread32(dev->i2s_base + RRBR_RTHR(0)); \
+ p[rx_ptr][0] = ioread32(dev->i2s_base + dev->l_reg); \
+ p[rx_ptr][1] = ioread32(dev->i2s_base + dev->r_reg); \
period_pos++; \
if (++rx_ptr >= runtime->buffer_size) \
rx_ptr = 0; \
diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h
index ba4e397099be..4ce96bac2f39 100644
--- a/sound/soc/dwc/local.h
+++ b/sound/soc/dwc/local.h
@@ -25,6 +25,13 @@
#define RXFFR 0x014
#define TXFFR 0x018
+/* Enable register fields */
+#define IER_TDM_SLOTS_SHIFT 8
+#define IER_FRAME_OFF_SHIFT 5
+#define IER_FRAME_OFF BIT(5)
+#define IER_INTF_TYPE BIT(1)
+#define IER_IEN BIT(0)
+
/* Interrupt status register fields */
#define ISR_TXFO BIT(5)
#define ISR_TXFE BIT(4)
@@ -46,6 +53,15 @@
#define TFCR(x) (0x40 * x + 0x04C)
#define RFF(x) (0x40 * x + 0x050)
#define TFF(x) (0x40 * x + 0x054)
+#define RSLOT_TSLOT(x) (0x4 * (x) + 0x224)
+
+/* Receive enable register fields */
+#define RER_RXSLOT_SHIFT 8
+#define RER_RXCHEN BIT(0)
+
+/* Transmit enable register fields */
+#define TER_TXSLOT_SHIFT 8
+#define TER_TXCHEN BIT(0)
/* I2SCOMPRegisters */
#define I2S_COMP_PARAM_2 0x01F0
@@ -105,6 +121,8 @@ struct dw_i2s_dev {
u32 ccr;
u32 xfer_resolution;
u32 fifo_th;
+ u32 l_reg;
+ u32 r_reg;
/* data related to DMA transfers b/w i2s and DMAC */
union dw_i2s_snd_dma_data play_dma_data;
@@ -114,6 +132,12 @@ struct dw_i2s_dev {
/* data related to PIO transfers */
bool use_pio;
+
+ /* data related to TDM mode */
+ u32 tdm_slots;
+ u32 tdm_mask;
+ u32 frame_offset;
+
struct snd_pcm_substream __rcu *tx_substream;
struct snd_pcm_substream __rcu *rx_substream;
unsigned int (*tx_fn)(struct dw_i2s_dev *dev,
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index 765dad607bf6..d63782b8bdef 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -228,6 +228,10 @@ static int imx_rpmsg_pcm_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct rpmsg_info *info = dev_get_drvdata(component->dev);
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
+ struct snd_pcm_hardware pcm_hardware;
struct rpmsg_msg *msg;
int ret = 0;
int cmd;
@@ -255,10 +259,11 @@ static int imx_rpmsg_pcm_open(struct snd_soc_component *component,
info->send_message(msg, info);
- imx_rpmsg_pcm_hardware.period_bytes_max =
- imx_rpmsg_pcm_hardware.buffer_bytes_max / 2;
+ pcm_hardware = imx_rpmsg_pcm_hardware;
+ pcm_hardware.buffer_bytes_max = rpmsg->buffer_size;
+ pcm_hardware.period_bytes_max = pcm_hardware.buffer_bytes_max / 2;
- snd_soc_set_runtime_hwparams(substream, &imx_rpmsg_pcm_hardware);
+ snd_soc_set_runtime_hwparams(substream, &pcm_hardware);
ret = snd_pcm_hw_constraint_integer(substream->runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
@@ -597,7 +602,6 @@ static int imx_rpmsg_pcm_new(struct snd_soc_component *component,
if (ret)
return ret;
- imx_rpmsg_pcm_hardware.buffer_bytes_max = rpmsg->buffer_size;
return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_WC,
pcm->card->dev, rpmsg->buffer_size);
}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1a0bde23f5e6..94e856d67a46 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -238,6 +238,21 @@ static inline void snd_soc_debugfs_exit(void) { }
#endif
+static inline int snd_soc_dlc_component_is_empty(struct snd_soc_dai_link_component *dlc)
+{
+ return !(dlc->name || dlc->of_node);
+}
+
+static inline int snd_soc_dlc_component_is_invalid(struct snd_soc_dai_link_component *dlc)
+{
+ return (dlc->name && dlc->of_node);
+}
+
+static inline int snd_soc_dlc_dai_is_empty(struct snd_soc_dai_link_component *dlc)
+{
+ return !dlc->dai_name;
+}
+
static int snd_soc_rtd_add_component(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_component *component)
{
@@ -829,102 +844,100 @@ static int soc_dai_link_sanity_check(struct snd_soc_card *card,
struct snd_soc_dai_link *link)
{
int i;
- struct snd_soc_dai_link_component *cpu, *codec, *platform;
+ struct snd_soc_dai_link_component *dlc;
- for_each_link_codecs(link, i, codec) {
+ /* Codec check */
+ for_each_link_codecs(link, i, dlc) {
/*
* Codec must be specified by 1 of name or OF node,
* not both or neither.
*/
- if (!!codec->name == !!codec->of_node) {
- dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
- link->name);
- return -EINVAL;
- }
+ if (snd_soc_dlc_component_is_invalid(dlc))
+ goto component_invalid;
+
+ if (snd_soc_dlc_component_is_empty(dlc))
+ goto component_empty;
/* Codec DAI name must be specified */
- if (!codec->dai_name) {
- dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
- link->name);
- return -EINVAL;
- }
+ if (snd_soc_dlc_dai_is_empty(dlc))
+ goto dai_empty;
/*
* Defer card registration if codec component is not added to
* component list.
*/
- if (!soc_find_component(codec)) {
- dev_dbg(card->dev,
- "ASoC: codec component %s not found for link %s\n",
- codec->name, link->name);
- return -EPROBE_DEFER;
- }
+ if (!soc_find_component(dlc))
+ goto component_not_find;
}
- for_each_link_platforms(link, i, platform) {
+ /* Platform check */
+ for_each_link_platforms(link, i, dlc) {
/*
* Platform may be specified by either name or OF node, but it
* can be left unspecified, then no components will be inserted
* in the rtdcom list
*/
- if (!!platform->name == !!platform->of_node) {
- dev_err(card->dev,
- "ASoC: Neither/both platform name/of_node are set for %s\n",
- link->name);
- return -EINVAL;
- }
+ if (snd_soc_dlc_component_is_invalid(dlc))
+ goto component_invalid;
+
+ if (snd_soc_dlc_component_is_empty(dlc))
+ goto component_empty;
/*
* Defer card registration if platform component is not added to
* component list.
*/
- if (!soc_find_component(platform)) {
- dev_dbg(card->dev,
- "ASoC: platform component %s not found for link %s\n",
- platform->name, link->name);
- return -EPROBE_DEFER;
- }
+ if (!soc_find_component(dlc))
+ goto component_not_find;
}
- for_each_link_cpus(link, i, cpu) {
+ /* CPU check */
+ for_each_link_cpus(link, i, dlc) {
/*
* CPU device may be specified by either name or OF node, but
* can be left unspecified, and will be matched based on DAI
* name alone..
*/
- if (cpu->name && cpu->of_node) {
- dev_err(card->dev,
- "ASoC: Neither/both cpu name/of_node are set for %s\n",
- link->name);
- return -EINVAL;
- }
+ if (snd_soc_dlc_component_is_invalid(dlc))
+ goto component_invalid;
- /*
- * Defer card registration if cpu dai component is not added to
- * component list.
- */
- if ((cpu->of_node || cpu->name) &&
- !soc_find_component(cpu)) {
- dev_dbg(card->dev,
- "ASoC: cpu component %s not found for link %s\n",
- cpu->name, link->name);
- return -EPROBE_DEFER;
- }
- /*
- * At least one of CPU DAI name or CPU device name/node must be
- * specified
- */
- if (!cpu->dai_name &&
- !(cpu->name || cpu->of_node)) {
- dev_err(card->dev,
- "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
- link->name);
- return -EINVAL;
+ if (snd_soc_dlc_component_is_empty(dlc)) {
+ /*
+ * At least one of CPU DAI name or CPU device name/node must be specified
+ */
+ if (snd_soc_dlc_dai_is_empty(dlc))
+ goto component_dai_empty;
+ } else {
+ /*
+ * Defer card registration if Component is not added
+ */
+ if (!soc_find_component(dlc))
+ goto component_not_find;
}
}
return 0;
+
+component_invalid:
+ dev_err(card->dev, "ASoC: Both Component name/of_node are set for %s\n", link->name);
+ return -EINVAL;
+
+component_empty:
+ dev_err(card->dev, "ASoC: Neither Component name/of_node are set for %s\n", link->name);
+ return -EINVAL;
+
+component_not_find:
+ dev_err(card->dev, "ASoC: Component %s not found for link %s\n", dlc->name, link->name);
+ return -EPROBE_DEFER;
+
+dai_empty:
+ dev_err(card->dev, "ASoC: DAI name is not set for %s\n", link->name);
+ return -EINVAL;
+
+component_dai_empty:
+ dev_err(card->dev, "ASoC: Neither DAI/Component name/of_node are set for %s\n", link->name);
+ return -EINVAL;
}
/**
@@ -3235,11 +3248,12 @@ EXPORT_SYMBOL_GPL(snd_soc_get_stream_cpu);
int snd_soc_get_dai_id(struct device_node *ep)
{
struct snd_soc_component *component;
- struct snd_soc_dai_link_component dlc;
+ struct snd_soc_dai_link_component dlc = {
+ .of_node = of_graph_get_port_parent(ep),
+ };
int ret;
- dlc.of_node = of_graph_get_port_parent(ep);
- dlc.name = NULL;
+
/*
* For example HDMI case, HDMI has video/sound port,
* but ALSA SoC needs sound port number only.
@@ -3264,8 +3278,6 @@ int snd_soc_get_dlc(const struct of_phandle_args *args, struct snd_soc_dai_link_
struct snd_soc_component *pos;
int ret = -EPROBE_DEFER;
- dlc->of_node = args->np;
-
mutex_lock(&client_mutex);
for_each_component(pos) {
struct device_node *component_of_node = soc_component_to_node(pos);
@@ -3319,6 +3331,10 @@ int snd_soc_get_dlc(const struct of_phandle_args *args, struct snd_soc_dai_link_
break;
}
+
+ if (ret == 0)
+ dlc->of_node = args->np;
+
mutex_unlock(&client_mutex);
return ret;
}
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index afb505461ea1..c450931ae77e 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -28,12 +28,14 @@ static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
return 0;
}
-static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data)
+static int smn_read(struct pci_dev *dev, u32 smn_addr)
{
+ u32 data = 0;
+
pci_write_config_dword(dev, 0x60, smn_addr);
- pci_read_config_dword(dev, 0x64, data);
+ pci_read_config_dword(dev, 0x64, &data);
- return 0;
+ return data;
}
static void init_dma_descriptor(struct acp_dev_data *adata)
@@ -150,15 +152,13 @@ int configure_and_run_dma(struct acp_dev_data *adata, unsigned int src_addr,
static int psp_mbox_ready(struct acp_dev_data *adata, bool ack)
{
struct snd_sof_dev *sdev = adata->dev;
- int timeout;
+ int ret;
u32 data;
- for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
- msleep(20);
- smn_read(adata->smn_dev, MP0_C2PMSG_114_REG, &data);
- if (data & MBOX_READY_MASK)
- return 0;
- }
+ ret = read_poll_timeout(smn_read, data, data & MBOX_READY_MASK, MBOX_DELAY_US,
+ ACP_PSP_TIMEOUT_US, false, adata->smn_dev, MP0_C2PMSG_114_REG);
+ if (!ret)
+ return 0;
dev_err(sdev->dev, "PSP error status %x\n", data & MBOX_STATUS_MASK);
@@ -177,23 +177,19 @@ static int psp_mbox_ready(struct acp_dev_data *adata, bool ack)
static int psp_send_cmd(struct acp_dev_data *adata, int cmd)
{
struct snd_sof_dev *sdev = adata->dev;
- int ret, timeout;
+ int ret;
u32 data;
if (!cmd)
return -EINVAL;
/* Get a non-zero Doorbell value from PSP */
- for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
- msleep(MBOX_DELAY);
- smn_read(adata->smn_dev, MP0_C2PMSG_73_REG, &data);
- if (data)
- break;
- }
+ ret = read_poll_timeout(smn_read, data, data, MBOX_DELAY_US, ACP_PSP_TIMEOUT_US, false,
+ adata->smn_dev, MP0_C2PMSG_73_REG);
- if (!timeout) {
+ if (ret) {
dev_err(sdev->dev, "Failed to get Doorbell from MBOX %x\n", MP0_C2PMSG_73_REG);
- return -EINVAL;
+ return ret;
}
/* Check if PSP is ready for new command */
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index dc624f727aa3..c3659dbc3745 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -61,12 +61,12 @@
#define HOST_BRIDGE_CZN 0x1630
#define HOST_BRIDGE_RMB 0x14B5
#define ACP_SHA_STAT 0x8000
-#define ACP_PSP_TIMEOUT_COUNTER 5
+#define ACP_PSP_TIMEOUT_US 1000000
#define ACP_EXT_INTR_ERROR_STAT 0x20000000
#define MP0_C2PMSG_114_REG 0x3810AC8
#define MP0_C2PMSG_73_REG 0x3810A24
#define MBOX_ACP_SHA_DMA_COMMAND 0x70000
-#define MBOX_DELAY 1000
+#define MBOX_DELAY_US 1000
#define MBOX_READY_MASK 0x80000000
#define MBOX_STATUS_MASK 0xFFFF