sound updates for 6.8-rc1
It was a clam development cycle. There were an ALSA core extension for subformat PCM bits and a few ASoC core changes to support N:M mappings, while the most of remaining changes are driver-specific. Core: - API extensions for properly limiting PCM format bits via subformat - Enhanced support for N:M CPU:CODEC mappings in the core and in audio-graph-card2 ASoC: - Lots of SOF updates: fallback support to older IPC versions, notification on control changes with IPC4. Also supports for ACPI parse for the ES83xx driver that reduces quirks. - Device tree support for describing parts of the card which can be active over suspend (for very low power playback or wake word use cases) - Support for more AMD and Intel systems, NXP i.MX8m MICFIL, Qualcomm SM8250, SM8550, SM8650 and X1E80100 - Drop of Freescale MPC8610 code that is no longer supported HD-audio: - More CS35L41 codec extensions for Dell, HP and Lenovo models - TAS2781 codec extensions for Lenovo and co - New PCM subformat supports Others: - More enhancement for Scarlett2 USB mixer support - Various kselftest fixes -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmWfzJgOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE/NHg//VT0JRZDKqAZMUIaFZswUIKgoUy9fY9WaePO+ db38uFzjuTC1ZN1PIDFnU0bQ2uL7IYF/xnceqitk+G76+Wt/pcDP/1hX+F9UhsVd wgRrihBeNRtSmPku8cwKu+duD/46439JyWo34PdHm8FxNoyilBx6fIApk6JqB57V HYU3ZFtQE84s8TmPHefasLeewY5thFtWYXLAaEZR5oohyXUTN0Np7h7vG8nchh1F zZOwoQ+nBo607PwUoXd0BFYkcuXwHlK4vLVmAM05KPaH1Q/kesEecYMhIVbnDHOj a4caMz+/tMbNbw3/GRsg8HgIeiyp1NoyC4LAqufa+Pj6BgPREVra5j8XoxAnCxXr 8X8EDtBds6frMzqtQyNvTkyRCf3Iki8fhz60Re5nEkoXLcv34E3kleQDLG/FnHqC qeH0J3FEed84Gf6KrnpjkPHLFRx5ZKyahOHZ7Xc76fUYMCwvczkc5CKeG2EoivE4 koEkhlQU1gnNyjNTTi4JchWis+EZG/oNA91eud1lMDm320lFJmxdZ5z31xZubVvs WTcMStgHCDPIKOeSBuwBCYFwugMtV/o/ejE567E4bxVC5ZA/zbxyvpxU9iDAjUNK T0JdPf/KKy1YJiNe9xuJn9/1ZpV6BXFCl7b7wILV+ZbGduOczoMCEH5T7dwAmZqq /lQtT/8= =yVxc -----END PGP SIGNATURE----- Merge tag 'sound-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "It was a calm development cycle. There were an ALSA core extension for subformat PCM bits and a few ASoC core changes to support N:M mappings, while the most of remaining changes are driver-specific. Core: - API extensions for properly limiting PCM format bits via subformat - Enhanced support for N:M CPU:CODEC mappings in the core and in audio-graph-card2 ASoC: - Lots of SOF updates: fallback support to older IPC versions, notification on control changes with IPC4. Also supports for ACPI parse for the ES83xx driver that reduces quirks. - Device tree support for describing parts of the card which can be active over suspend (for very low power playback or wake word use cases) - Support for more AMD and Intel systems, NXP i.MX8m MICFIL, Qualcomm SM8250, SM8550, SM8650 and X1E80100 - Drop of Freescale MPC8610 code that is no longer supported HD-audio: - More CS35L41 codec extensions for Dell, HP and Lenovo models - TAS2781 codec extensions for Lenovo and co - New PCM subformat supports Others: - More enhancement for Scarlett2 USB mixer support - Various kselftest fixes" * tag 'sound-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (337 commits) kselftest/alsa - conf: Stringify the printed errno in sysfs_get() kselftest/alsa - mixer-test: Fix the print format specifier warning kselftest/alsa - mixer-test: Fix the print format specifier warning kselftest/alsa - mixer-test: fix the number of parameters to ksft_exit_fail_msg() ALSA: hda/tas2781: annotate calibration data endianness ALSA: hda/realtek: Fix mute and mic-mute LEDs for HP Envy X360 13-ay0xxx ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140 ALSA: ac97: fix build regression ALSA: hda: cs35l41: Support more HP models without _DSD ALSA: hda/tas2781: add fixup for Lenovo 14ARB7 ALSA: hda/tas2781: add TAS2563 support for 14ARB7 ALSA: hda/tas2781: add configurable global i2c address ALSA: hda/tas2781: add ptrs to calibration functions ALSA: hda: Add driver properties for cs35l41 for Lenovo Legion Slim 7 Gen 8 serie ALSA: hda/realtek: enable SND_PCI_QUIRK for Lenovo Legion Slim 7 Gen 8 (2023) serie ALSA: hda/tas2781: configure the amp after firmware load ALSA: mark all struct bus_type as const ASoC: pxa: sspa: Don't select SND_ARM ASoC: rt5663: cancel the work when system suspends ALSA: scarlett2: Add PCM Input Switch for Solo Gen 4 ...
This commit is contained in:
commit
7912a6391f
@ -39,7 +39,7 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soundwire-controller@3250000 {
|
||||
soundwire@3250000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x3250000 0x2000>;
|
||||
|
@ -19,6 +19,12 @@ definitions:
|
||||
properties:
|
||||
mclk-fs:
|
||||
$ref: simple-card.yaml#/definitions/mclk-fs
|
||||
playback-only:
|
||||
description: port connection used only for playback
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
capture-only:
|
||||
description: port connection used only for capture
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
||||
endpoint-base:
|
||||
allOf:
|
||||
|
@ -1,38 +0,0 @@
|
||||
Everest ES8328 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : Should be "everest,es8328" or "everest,es8388"
|
||||
- DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V
|
||||
- AVDD-supply : Regulator providing analog supply voltage 3.3V
|
||||
- PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V
|
||||
- IPVDD-supply : Regulator providing analog output voltage 3.3V
|
||||
- clocks : A 22.5792 or 11.2896 MHz clock
|
||||
- reg : the I2C address of the device for I2C, the chip select number for SPI
|
||||
|
||||
Pins on the device (for linking into audio routes):
|
||||
|
||||
* LOUT1
|
||||
* LOUT2
|
||||
* ROUT1
|
||||
* ROUT2
|
||||
* LINPUT1
|
||||
* RINPUT1
|
||||
* LINPUT2
|
||||
* RINPUT2
|
||||
* Mic Bias
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
codec: es8328@11 {
|
||||
compatible = "everest,es8328";
|
||||
DVDD-supply = <®_3p3v>;
|
||||
AVDD-supply = <®_3p3v>;
|
||||
PVDD-supply = <®_3p3v>;
|
||||
HPVDD-supply = <®_3p3v>;
|
||||
clocks = <&clks 169>;
|
||||
reg = <0x11>;
|
||||
};
|
77
Documentation/devicetree/bindings/sound/everest,es8328.yaml
Normal file
77
Documentation/devicetree/bindings/sound/everest,es8328.yaml
Normal file
@ -0,0 +1,77 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/everest,es8328.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Everest ES8328 audio CODEC
|
||||
|
||||
description:
|
||||
Everest Audio Codec, which can be connected via I2C or SPI.
|
||||
Pins on the device (for linking into audio routes) are
|
||||
* LOUT1
|
||||
* LOUT2
|
||||
* ROUT1
|
||||
* ROUT2
|
||||
* LINPUT1
|
||||
* RINPUT1
|
||||
* LINPUT2
|
||||
* RINPUT2
|
||||
* Mic Bias
|
||||
|
||||
maintainers:
|
||||
- David Yang <yangxiaohua@everest-semi.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- everest,es8328
|
||||
- everest,es8388
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: A 22.5792 or 11.2896 MHz clock
|
||||
|
||||
DVDD-supply:
|
||||
description: Regulator providing digital core supply voltage 1.8 - 3.6V
|
||||
|
||||
AVDD-supply:
|
||||
description: Regulator providing analog supply voltage 3.3V
|
||||
|
||||
PVDD-supply:
|
||||
description: Regulator providing digital IO supply voltage 1.8 - 3.6V
|
||||
|
||||
HPVDD-supply:
|
||||
description: Regulator providing analog output voltage 3.3V
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- DVDD-supply
|
||||
- AVDD-supply
|
||||
- PVDD-supply
|
||||
- HPVDD-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
es8328: codec@11 {
|
||||
compatible = "everest,es8328";
|
||||
reg = <0x11>;
|
||||
AVDD-supply = <®_3p3v>;
|
||||
DVDD-supply = <®_3p3v>;
|
||||
HPVDD-supply = <®_3p3v>;
|
||||
PVDD-supply = <®_3p3v>;
|
||||
clocks = <&clks 169>;
|
||||
};
|
||||
};
|
@ -1,36 +0,0 @@
|
||||
fsl,mqs audio CODEC
|
||||
|
||||
Required properties:
|
||||
- compatible : Must contain one of "fsl,imx6sx-mqs", "fsl,codec-mqs"
|
||||
"fsl,imx8qm-mqs", "fsl,imx8qxp-mqs", "fsl,imx93-mqs".
|
||||
- clocks : A list of phandles + clock-specifiers, one for each entry in
|
||||
clock-names
|
||||
- clock-names : "mclk" - must required.
|
||||
"core" - required if compatible is "fsl,imx8qm-mqs", it
|
||||
is for register access.
|
||||
- gpr : A phandle of General Purpose Registers in IOMUX Controller.
|
||||
Required if compatible is "fsl,imx6sx-mqs".
|
||||
|
||||
Required if compatible is "fsl,imx8qm-mqs":
|
||||
- power-domains: A phandle of PM domain provider node.
|
||||
- reg: Offset and length of the register set for the device.
|
||||
|
||||
Example:
|
||||
|
||||
mqs: mqs {
|
||||
compatible = "fsl,imx6sx-mqs";
|
||||
gpr = <&gpr>;
|
||||
clocks = <&clks IMX6SX_CLK_SAI1>;
|
||||
clock-names = "mclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mqs: mqs@59850000 {
|
||||
compatible = "fsl,imx8qm-mqs";
|
||||
reg = <0x59850000 0x10000>;
|
||||
clocks = <&clk IMX8QM_AUD_MQS_IPG>,
|
||||
<&clk IMX8QM_AUD_MQS_HMCLK>;
|
||||
clock-names = "core", "mclk";
|
||||
power-domains = <&pd_mqs0>;
|
||||
status = "disabled";
|
||||
};
|
105
Documentation/devicetree/bindings/sound/fsl,mqs.yaml
Normal file
105
Documentation/devicetree/bindings/sound/fsl,mqs.yaml
Normal file
@ -0,0 +1,105 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/fsl,mqs.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP Medium Quality Sound (MQS)
|
||||
|
||||
maintainers:
|
||||
- Shengjiu Wang <shengjiu.wang@nxp.com>
|
||||
- Chancel Liu <chancel.liu@nxp.com>
|
||||
|
||||
description: |
|
||||
Medium quality sound (MQS) is used to generate medium quality audio
|
||||
via a standard GPIO in the pinmux, allowing the user to connect
|
||||
stereo speakers or headphones to a power amplifier without an
|
||||
additional DAC chip.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx6sx-mqs
|
||||
- fsl,imx8qm-mqs
|
||||
- fsl,imx8qxp-mqs
|
||||
- fsl,imx93-mqs
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
gpr:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle to the General Purpose Register (GPR) node
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx8qm-mqs
|
||||
- fsl,imx8qxp-mqs
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Master clock
|
||||
- description: Clock for register access
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: core
|
||||
required:
|
||||
- reg
|
||||
- power-domains
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Master clock
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
required:
|
||||
- gpr
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx6sx-clock.h>
|
||||
mqs0: mqs {
|
||||
compatible = "fsl,imx6sx-mqs";
|
||||
gpr = <&gpr>;
|
||||
clocks = <&clks IMX6SX_CLK_SAI1>;
|
||||
clock-names = "mclk";
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
mqs1: mqs@59850000 {
|
||||
compatible = "fsl,imx8qm-mqs";
|
||||
reg = <0x59850000 0x10000>;
|
||||
clocks = <&mqs0_lpcg 0>, <&mqs0_lpcg 1>;
|
||||
clock-names = "mclk", "core";
|
||||
power-domains = <&pd IMX_SC_R_MQS_0>;
|
||||
};
|
@ -38,7 +38,10 @@ properties:
|
||||
- const: txfifo
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
items:
|
||||
- description: WAKEUPMIX Audio XCVR Interrupt 1
|
||||
- description: WAKEUPMIX Audio XCVR Interrupt 2
|
||||
minItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
@ -78,6 +81,23 @@ required:
|
||||
- dma-names
|
||||
- resets
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx93-xcvr
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -15,6 +15,7 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt8188-es8326
|
||||
- mediatek,mt8188-mt6359-evb
|
||||
- mediatek,mt8188-nau8825
|
||||
- mediatek,mt8188-rt5682s
|
||||
|
@ -89,6 +89,14 @@ properties:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 3072000
|
||||
|
||||
nuvoton,dmic-slew-rate:
|
||||
description: The range 0 to 7 represents the speed of DMIC slew rate.
|
||||
The lowest value 0 means the slowest rate and the highest value
|
||||
7 means the fastest rate.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
maximum: 7
|
||||
default: 0
|
||||
|
||||
nuvoton,left-input-single-end:
|
||||
description: Enable left input with single-ended settings if set.
|
||||
For the headset mic application, the single-ended control is
|
||||
@ -127,6 +135,7 @@ examples:
|
||||
nuvoton,jack-insert-debounce = <7>;
|
||||
nuvoton,jack-eject-debounce = <0>;
|
||||
nuvoton,dmic-clk-threshold = <3072000>;
|
||||
nuvoton,dmic-slew-rate = <0>;
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
@ -11,12 +11,18 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7280-lpass-rx-macro
|
||||
- qcom,sm8250-lpass-rx-macro
|
||||
- qcom,sm8450-lpass-rx-macro
|
||||
- qcom,sm8550-lpass-rx-macro
|
||||
- qcom,sc8280xp-lpass-rx-macro
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,sc7280-lpass-rx-macro
|
||||
- qcom,sm8250-lpass-rx-macro
|
||||
- qcom,sm8450-lpass-rx-macro
|
||||
- qcom,sm8550-lpass-rx-macro
|
||||
- qcom,sc8280xp-lpass-rx-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sm8650-lpass-rx-macro
|
||||
- qcom,x1e80100-lpass-rx-macro
|
||||
- const: qcom,sm8550-lpass-rx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -96,8 +102,9 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm8550-lpass-rx-macro
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm8550-lpass-rx-macro
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
@ -11,13 +11,19 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7280-lpass-tx-macro
|
||||
- qcom,sm6115-lpass-tx-macro
|
||||
- qcom,sm8250-lpass-tx-macro
|
||||
- qcom,sm8450-lpass-tx-macro
|
||||
- qcom,sm8550-lpass-tx-macro
|
||||
- qcom,sc8280xp-lpass-tx-macro
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,sc7280-lpass-tx-macro
|
||||
- qcom,sm6115-lpass-tx-macro
|
||||
- qcom,sm8250-lpass-tx-macro
|
||||
- qcom,sm8450-lpass-tx-macro
|
||||
- qcom,sm8550-lpass-tx-macro
|
||||
- qcom,sc8280xp-lpass-tx-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sm8650-lpass-tx-macro
|
||||
- qcom,x1e80100-lpass-tx-macro
|
||||
- const: qcom,sm8550-lpass-tx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -118,8 +124,9 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm8550-lpass-tx-macro
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm8550-lpass-tx-macro
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
@ -11,12 +11,18 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7280-lpass-va-macro
|
||||
- qcom,sm8250-lpass-va-macro
|
||||
- qcom,sm8450-lpass-va-macro
|
||||
- qcom,sm8550-lpass-va-macro
|
||||
- qcom,sc8280xp-lpass-va-macro
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,sc7280-lpass-va-macro
|
||||
- qcom,sm8250-lpass-va-macro
|
||||
- qcom,sm8450-lpass-va-macro
|
||||
- qcom,sm8550-lpass-va-macro
|
||||
- qcom,sc8280xp-lpass-va-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sm8650-lpass-va-macro
|
||||
- qcom,x1e80100-lpass-va-macro
|
||||
- const: qcom,sm8550-lpass-va-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -11,12 +11,18 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7280-lpass-wsa-macro
|
||||
- qcom,sm8250-lpass-wsa-macro
|
||||
- qcom,sm8450-lpass-wsa-macro
|
||||
- qcom,sm8550-lpass-wsa-macro
|
||||
- qcom,sc8280xp-lpass-wsa-macro
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,sc7280-lpass-wsa-macro
|
||||
- qcom,sm8250-lpass-wsa-macro
|
||||
- qcom,sm8450-lpass-wsa-macro
|
||||
- qcom,sm8550-lpass-wsa-macro
|
||||
- qcom,sc8280xp-lpass-wsa-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sm8650-lpass-wsa-macro
|
||||
- qcom,x1e80100-lpass-wsa-macro
|
||||
- const: qcom,sm8550-lpass-wsa-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -94,8 +100,9 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm8550-lpass-wsa-macro
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm8550-lpass-wsa-macro
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
@ -21,6 +21,11 @@ properties:
|
||||
- lenovo,yoga-c630-sndcard
|
||||
- qcom,db845c-sndcard
|
||||
- const: qcom,sdm845-sndcard
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sm8550-sndcard
|
||||
- qcom,sm8650-sndcard
|
||||
- const: qcom,sm8450-sndcard
|
||||
- enum:
|
||||
- qcom,apq8016-sbc-sndcard
|
||||
- qcom,msm8916-qdsp6-sndcard
|
||||
@ -30,6 +35,7 @@ properties:
|
||||
- qcom,sdm845-sndcard
|
||||
- qcom,sm8250-sndcard
|
||||
- qcom,sm8450-sndcard
|
||||
- qcom,x1e80100-sndcard
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
|
@ -201,9 +201,9 @@ examples:
|
||||
- |
|
||||
codec@1,0{
|
||||
compatible = "slim217,250";
|
||||
reg = <1 0>;
|
||||
reg = <1 0>;
|
||||
reset-gpios = <&tlmm 64 0>;
|
||||
slim-ifc-dev = <&wcd9340_ifd>;
|
||||
slim-ifc-dev = <&wcd9340_ifd>;
|
||||
#sound-dai-cells = <1>;
|
||||
interrupt-parent = <&tlmm>;
|
||||
interrupts = <54 4>;
|
||||
|
@ -51,7 +51,7 @@ examples:
|
||||
reg = <0x03210000 0x2000>;
|
||||
wcd938x_rx: codec@0,4 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 4>;
|
||||
reg = <0 4>;
|
||||
qcom,rx-port-mapping = <1 2 3 4 5>;
|
||||
};
|
||||
};
|
||||
@ -62,7 +62,7 @@ examples:
|
||||
reg = <0x03230000 0x2000>;
|
||||
wcd938x_tx: codec@0,3 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 3>;
|
||||
reg = <0 3>;
|
||||
qcom,tx-port-mapping = <2 3 4 5>;
|
||||
};
|
||||
};
|
||||
|
@ -137,7 +137,7 @@ examples:
|
||||
reg = <0x03210000 0x2000>;
|
||||
wcd938x_rx: codec@0,4 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 4>;
|
||||
reg = <0 4>;
|
||||
qcom,rx-port-mapping = <1 2 3 4 5>;
|
||||
};
|
||||
};
|
||||
@ -148,7 +148,7 @@ examples:
|
||||
reg = <0x03230000 0x2000>;
|
||||
wcd938x_tx: codec@0,3 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 3>;
|
||||
reg = <0 3>;
|
||||
qcom,tx-port-mapping = <2 3 4 5>;
|
||||
};
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
soundwire-controller@3250000 {
|
||||
soundwire@3250000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x3250000 0x2000>;
|
||||
|
@ -48,7 +48,7 @@ examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
soundwire-controller {
|
||||
soundwire {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
|
@ -9,20 +9,6 @@ title: Renesas R-Car Sound Driver
|
||||
maintainers:
|
||||
- Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
|
||||
definitions:
|
||||
port-def:
|
||||
$ref: audio-graph-port.yaml#/definitions/port-base
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9a-f]+)?":
|
||||
$ref: audio-graph-port.yaml#/definitions/endpoint-base
|
||||
properties:
|
||||
playback:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
capture:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
|
||||
compatible:
|
||||
@ -125,7 +111,17 @@ properties:
|
||||
|
||||
# ports is below
|
||||
port:
|
||||
$ref: "#/definitions/port-def"
|
||||
$ref: audio-graph-port.yaml#/definitions/port-base
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9a-f]+)?":
|
||||
$ref: audio-graph-port.yaml#/definitions/endpoint-base
|
||||
properties:
|
||||
playback:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
capture:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
unevaluatedProperties: false
|
||||
|
||||
rcar_sound,dvc:
|
||||
description: DVC subnode.
|
||||
@ -269,7 +265,7 @@ patternProperties:
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
'^port(@[0-9a-f]+)?$':
|
||||
$ref: "#/definitions/port-def"
|
||||
$ref: "#/properties/port"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -501,19 +497,19 @@ examples:
|
||||
rcar_sound,dai {
|
||||
dai0 {
|
||||
playback = <&ssi5>, <&src5>;
|
||||
capture = <&ssi6>;
|
||||
capture = <&ssi6>;
|
||||
};
|
||||
dai1 {
|
||||
playback = <&ssi3>;
|
||||
};
|
||||
dai2 {
|
||||
capture = <&ssi4>;
|
||||
capture = <&ssi4>;
|
||||
};
|
||||
dai3 {
|
||||
playback = <&ssi7>;
|
||||
};
|
||||
dai4 {
|
||||
capture = <&ssi8>;
|
||||
capture = <&ssi8>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -527,7 +523,7 @@ examples:
|
||||
frame-master = <&rsnd_endpoint0>;
|
||||
|
||||
playback = <&ssi0>, <&src0>, <&dvc0>;
|
||||
capture = <&ssi1>, <&src1>, <&dvc1>;
|
||||
capture = <&ssi1>, <&src1>, <&dvc1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -16,7 +16,7 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g043-ssi # RZ/G2UL
|
||||
- renesas,r9a07g043-ssi # RZ/G2UL and RZ/Five
|
||||
- renesas,r9a07g044-ssi # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-ssi # RZ/V2L
|
||||
- const: renesas,rz-ssi
|
||||
|
@ -17,6 +17,13 @@ properties:
|
||||
pair of strings, the first being the connection's sink, the second
|
||||
being the connection's source.
|
||||
|
||||
ignore-suspend-widgets:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description: |
|
||||
A list of audio sound widgets which are marked ignoring system suspend.
|
||||
Paths between these endpoints are still active over suspend of the main
|
||||
application processor that the current operating system is running.
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: User specified audio sound card name
|
||||
|
@ -90,7 +90,7 @@ examples:
|
||||
ldoin-supply = <®_3v3>;
|
||||
clocks = <&clks 201>;
|
||||
clock-names = "mclk";
|
||||
aic32x4-gpio-func= <
|
||||
aic32x4-gpio-func = <
|
||||
0xff /* AIC32X4_MFPX_DEFAULT_VALUE */
|
||||
0xff /* AIC32X4_MFPX_DEFAULT_VALUE */
|
||||
0x04 /* MFP3 AIC32X4_MFP3_GPIO_ENABLED */
|
||||
|
@ -234,7 +234,7 @@ corresponding soft power control. In this case it is necessary to create
|
||||
a virtual widget - a widget with no control bits e.g.
|
||||
::
|
||||
|
||||
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
|
||||
This can be used to merge to signal paths together in software.
|
||||
|
||||
|
@ -8259,11 +8259,14 @@ L: linux-input@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/input/joystick/fsia6b.c
|
||||
|
||||
FOCUSRITE SCARLETT GEN 2/3 MIXER DRIVER
|
||||
FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett)
|
||||
M: Geoffrey D. Bennett <g@b4.vu>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
|
||||
W: https://github.com/geoffreybennett/scarlett-gen2
|
||||
B: https://github.com/geoffreybennett/scarlett-gen2/issues
|
||||
T: git https://github.com/geoffreybennett/scarlett-gen2.git
|
||||
F: include/uapi/sound/scarlett2.h
|
||||
F: sound/usb/mixer_scarlett2.c
|
||||
|
||||
FORCEDETH GIGABIT ETHERNET DRIVER
|
||||
@ -8568,7 +8571,6 @@ L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Maintained
|
||||
F: sound/soc/fsl/fsl*
|
||||
F: sound/soc/fsl/imx*
|
||||
F: sound/soc/fsl/mpc8610_hpcd.c
|
||||
|
||||
FREESCALE SOC SOUND QMC DRIVER
|
||||
M: Herve Codina <herve.codina@bootlin.com>
|
||||
|
@ -446,7 +446,7 @@
|
||||
tegra_ac97: ac97@70002000 {
|
||||
status = "okay";
|
||||
nvidia,codec-reset-gpio =
|
||||
<&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_HIGH>;
|
||||
<&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>;
|
||||
nvidia,codec-sync-gpio =
|
||||
<&gpio TEGRA_GPIO(P, 0) GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ static void __init edb93xx_register_i2c(void)
|
||||
* EDB93xx SPI peripheral handling
|
||||
*************************************************************************/
|
||||
static struct cs4271_platform_data edb93xx_cs4271_data = {
|
||||
.gpio_nreset = -EINVAL, /* filled in later */
|
||||
/* Intentionally left blank */
|
||||
};
|
||||
|
||||
static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
|
||||
@ -114,14 +114,38 @@ static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
|
||||
/* Intentionally left blank */
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table edb93xx_cs4272_edb9301_gpio_table = {
|
||||
.dev_id = "spi0.0", /* CS0 on SPI0 */
|
||||
.table = {
|
||||
GPIO_LOOKUP("A", 1, "reset", GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table edb93xx_cs4272_edb9302_gpio_table = {
|
||||
.dev_id = "spi0.0", /* CS0 on SPI0 */
|
||||
.table = {
|
||||
GPIO_LOOKUP("H", 2, "reset", GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table edb93xx_cs4272_edb9315_gpio_table = {
|
||||
.dev_id = "spi0.0", /* CS0 on SPI0 */
|
||||
.table = {
|
||||
GPIO_LOOKUP("B", 6, "reset", GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static void __init edb93xx_register_spi(void)
|
||||
{
|
||||
if (machine_is_edb9301() || machine_is_edb9302())
|
||||
edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
|
||||
gpiod_add_lookup_table(&edb93xx_cs4272_edb9301_gpio_table);
|
||||
else if (machine_is_edb9302a() || machine_is_edb9307a())
|
||||
edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
|
||||
gpiod_add_lookup_table(&edb93xx_cs4272_edb9302_gpio_table);
|
||||
else if (machine_is_edb9315a())
|
||||
edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
|
||||
gpiod_add_lookup_table(&edb93xx_cs4272_edb9315_gpio_table);
|
||||
|
||||
gpiod_add_lookup_table(&edb93xx_spi_cs_gpio_table);
|
||||
ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
|
||||
|
@ -164,7 +164,7 @@ static struct i2c_board_info vision_i2c_info[] __initdata = {
|
||||
* SPI CS4271 Audio Codec
|
||||
*************************************************************************/
|
||||
static struct cs4271_platform_data vision_cs4271_data = {
|
||||
.gpio_nreset = EP93XX_GPIO_LINE_H(2),
|
||||
/* Intentionally left blank */
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
@ -241,6 +241,15 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table vision_spi_cs4271_gpio_table = {
|
||||
.dev_id = "spi0.0", /* cs4271 @ CS0 */
|
||||
.table = {
|
||||
/* RESET */
|
||||
GPIO_LOOKUP_IDX("H", 2, NULL, 0, GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table vision_spi_cs_gpio_table = {
|
||||
.dev_id = "spi0",
|
||||
.table = {
|
||||
@ -292,6 +301,7 @@ static void __init vision_init_machine(void)
|
||||
|
||||
ep93xx_register_i2c(vision_i2c_info,
|
||||
ARRAY_SIZE(vision_i2c_info));
|
||||
gpiod_add_lookup_table(&vision_spi_cs4271_gpio_table);
|
||||
gpiod_add_lookup_table(&vision_spi_mmc_gpio_table);
|
||||
gpiod_add_lookup_table(&vision_spi_cs_gpio_table);
|
||||
ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
|
||||
|
@ -32,9 +32,18 @@
|
||||
|
||||
#include "crag6410.h"
|
||||
|
||||
static struct gpiod_lookup_table wm0010_gpiod_table = {
|
||||
.dev_id = "spi0.0", /* SPI device name */
|
||||
.table = {
|
||||
/* Active high for Glenfarclas Rev 2 */
|
||||
GPIO_LOOKUP("GPION", 6,
|
||||
"reset", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct wm0010_pdata wm0010_pdata = {
|
||||
.gpio_reset = S3C64XX_GPN(6),
|
||||
.reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
|
||||
/* Intentionally left blank */
|
||||
};
|
||||
|
||||
static struct spi_board_info wm1253_devs[] = {
|
||||
@ -61,10 +70,19 @@ static struct spi_board_info balblair_devs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table wm5100_gpiod_table = {
|
||||
.dev_id = "1-001a", /* Device 001a on I2C bus 1 */
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPION", 7,
|
||||
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("wm5100", 3,
|
||||
"hp-pol", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct wm5100_pdata wm5100_pdata = {
|
||||
.ldo_ena = S3C64XX_GPN(7),
|
||||
.irq_flags = IRQF_TRIGGER_HIGH,
|
||||
.gpio_base = CODEC_GPIO_BASE,
|
||||
|
||||
.in_mode = {
|
||||
WM5100_IN_DIFF,
|
||||
@ -73,7 +91,6 @@ static struct wm5100_pdata wm5100_pdata = {
|
||||
WM5100_IN_SE,
|
||||
},
|
||||
|
||||
.hp_pol = CODEC_GPIO_BASE + 3,
|
||||
.jack_modes = {
|
||||
{ WM5100_MICDET_MICBIAS3, 0, 0 },
|
||||
{ WM5100_MICDET_MICBIAS2, 1, 1 },
|
||||
@ -110,9 +127,16 @@ static struct wm8996_retune_mobile_config wm8996_retune[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table wm8996_gpiod_table = {
|
||||
.dev_id = "1-001a", /* Device 001a on I2C bus 1 */
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPION", 7,
|
||||
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static struct wm8996_pdata wm8996_pdata __initdata = {
|
||||
.ldo_ena = S3C64XX_GPN(7),
|
||||
.gpio_base = CODEC_GPIO_BASE,
|
||||
.micdet_def = 1,
|
||||
.inl_mode = WM8996_DIFFERRENTIAL_1,
|
||||
.inr_mode = WM8996_DIFFERRENTIAL_1,
|
||||
@ -296,12 +320,20 @@ static const struct i2c_board_info wm6230_i2c_devs[] = {
|
||||
};
|
||||
|
||||
static struct wm2200_pdata wm2200_pdata = {
|
||||
.ldo_ena = S3C64XX_GPN(7),
|
||||
.gpio_defaults = {
|
||||
[2] = 0x0005, /* GPIO3 24.576MHz output clock */
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table wm2200_gpiod_table = {
|
||||
.dev_id = "1-003a", /* Device 003a on I2C bus 1 */
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPION", 7,
|
||||
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct i2c_board_info wm2200_i2c[] = {
|
||||
{ I2C_BOARD_INFO("wm2200", 0x3a),
|
||||
.platform_data = &wm2200_pdata, },
|
||||
@ -337,18 +369,21 @@ static const struct {
|
||||
{ .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" },
|
||||
{ .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" },
|
||||
{ .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin",
|
||||
.spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
|
||||
.spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs),
|
||||
.gpiod_table = &wm0010_gpiod_table },
|
||||
{ .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" },
|
||||
{ .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" },
|
||||
{ .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair",
|
||||
.spi_devs = balblair_devs,
|
||||
.num_spi_devs = ARRAY_SIZE(balblair_devs) },
|
||||
{ .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu",
|
||||
.i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
|
||||
.i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs),
|
||||
.gpiod_table = &wm8996_gpiod_table },
|
||||
{ .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory",
|
||||
.i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
|
||||
{ .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman",
|
||||
.i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
|
||||
.i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs),
|
||||
.gpiod_table = &wm5100_gpiod_table },
|
||||
{ .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
|
||||
{ .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
|
||||
.i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs),
|
||||
@ -362,7 +397,8 @@ static const struct {
|
||||
.num_spi_devs = ARRAY_SIZE(wm5102_spi_devs),
|
||||
.gpiod_table = &wm5102_gpiod_table },
|
||||
{ .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1",
|
||||
.i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) },
|
||||
.i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c),
|
||||
.gpiod_table = &wm2200_gpiod_table },
|
||||
};
|
||||
|
||||
static int wlf_gf_module_probe(struct i2c_client *i2c)
|
||||
|
@ -39,8 +39,6 @@
|
||||
#include <linux/mfd/wm831x/irq.h>
|
||||
#include <linux/mfd/wm831x/gpio.h>
|
||||
|
||||
#include <sound/wm1250-ev1.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
@ -713,13 +711,16 @@ static struct wm831x_pdata glenfarclas_pmic_pdata = {
|
||||
.disable_touch = true,
|
||||
};
|
||||
|
||||
static struct wm1250_ev1_pdata wm1250_ev1_pdata = {
|
||||
.gpios = {
|
||||
[WM1250_EV1_GPIO_CLK_ENA] = S3C64XX_GPN(12),
|
||||
[WM1250_EV1_GPIO_CLK_SEL0] = S3C64XX_GPL(12),
|
||||
[WM1250_EV1_GPIO_CLK_SEL1] = S3C64XX_GPL(13),
|
||||
[WM1250_EV1_GPIO_OSR] = S3C64XX_GPL(14),
|
||||
[WM1250_EV1_GPIO_MASTER] = S3C64XX_GPL(8),
|
||||
static struct gpiod_lookup_table crag_wm1250_ev1_gpiod_table = {
|
||||
/* The WM1250-EV1 is device 0027 on I2C bus 1 */
|
||||
.dev_id = "1-0027",
|
||||
.table = {
|
||||
GPIO_LOOKUP("GPION", 12, "clk-ena", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("GPIOL", 12, "clk-sel0", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("GPIOL", 13, "clk-sel1", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("GPIOL", 14, "osr", GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("GPIOL", 8, "master", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
@ -733,9 +734,7 @@ static struct i2c_board_info i2c_devs1[] = {
|
||||
{ I2C_BOARD_INFO("wlf-gf-module", 0x24) },
|
||||
{ I2C_BOARD_INFO("wlf-gf-module", 0x25) },
|
||||
{ I2C_BOARD_INFO("wlf-gf-module", 0x26) },
|
||||
|
||||
{ I2C_BOARD_INFO("wm1250-ev1", 0x27),
|
||||
.platform_data = &wm1250_ev1_pdata },
|
||||
{ I2C_BOARD_INFO("wm1250-ev1", 0x27), },
|
||||
};
|
||||
|
||||
static struct s3c2410_platform_i2c i2c1_pdata = {
|
||||
@ -862,6 +861,7 @@ static void __init crag6410_machine_init(void)
|
||||
|
||||
gpiod_add_lookup_table(&crag_pmic_gpiod_table);
|
||||
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
|
||||
gpiod_add_lookup_table(&crag_wm1250_ev1_gpiod_table);
|
||||
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
|
||||
|
||||
samsung_keypad_set_platdata(&crag6410_keypad_data);
|
||||
|
@ -1265,10 +1265,7 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct sdw_stream_runtime *sruntime;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int ret, i;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(ctrl->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
@ -1279,33 +1276,7 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
sruntime = sdw_alloc_stream(dai->name);
|
||||
if (!sruntime) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
ctrl->sruntime[dai->id] = sruntime;
|
||||
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||
ret = snd_soc_dai_set_stream(codec_dai, sruntime,
|
||||
substream->stream);
|
||||
if (ret < 0 && ret != -ENOTSUPP) {
|
||||
dev_err(dai->dev, "Failed to set sdw stream on %s\n",
|
||||
codec_dai->name);
|
||||
goto err_set_stream;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_set_stream:
|
||||
sdw_release_stream(sruntime);
|
||||
err_alloc:
|
||||
pm_runtime_mark_last_busy(ctrl->dev);
|
||||
pm_runtime_put_autosuspend(ctrl->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
|
||||
@ -1314,8 +1285,6 @@ static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
|
||||
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
|
||||
|
||||
swrm_wait_for_wr_fifo_done(ctrl);
|
||||
sdw_release_stream(ctrl->sruntime[dai->id]);
|
||||
ctrl->sruntime[dai->id] = NULL;
|
||||
pm_runtime_mark_last_busy(ctrl->dev);
|
||||
pm_runtime_put_autosuspend(ctrl->dev);
|
||||
|
||||
|
@ -3067,6 +3067,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
|
||||
#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
|
||||
#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
|
||||
#define PCI_DEVICE_ID_INTEL_HDA_ARL 0x7728
|
||||
#define PCI_DEVICE_ID_INTEL_HDA_RPL_S 0x7a50
|
||||
#define PCI_DEVICE_ID_INTEL_HDA_ADL_S 0x7ad0
|
||||
#define PCI_DEVICE_ID_INTEL_HDA_MTL 0x7e28
|
||||
|
@ -410,7 +410,7 @@ int snd_ac97_pcm_close(struct ac97_pcm *pcm);
|
||||
int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime);
|
||||
|
||||
/* ad hoc AC97 device driver access */
|
||||
extern struct bus_type ac97_bus_type;
|
||||
extern const struct bus_type ac97_bus_type;
|
||||
|
||||
/* AC97 platform_data adding function */
|
||||
static inline void snd_ac97_dev_add_pdata(struct snd_ac97 *ac97, void *data)
|
||||
|
@ -9,7 +9,6 @@
|
||||
#define __CS4271_H
|
||||
|
||||
struct cs4271_platform_data {
|
||||
int gpio_nreset; /* GPIO driving Reset pin, if any */
|
||||
bool amutec_eq_bmutec; /* flag to enable AMUTEC=BMUTEC */
|
||||
|
||||
/*
|
||||
|
@ -141,6 +141,7 @@ struct hda_pcm_stream {
|
||||
hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */
|
||||
u32 rates; /* supported rates */
|
||||
u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */
|
||||
u32 subformats; /* for S32_LE format, SNDRV_PCM_SUBFMTBIT_* */
|
||||
unsigned int maxbps; /* supported max. bit per sample */
|
||||
const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
|
||||
struct hda_pcm_ops ops;
|
||||
@ -448,8 +449,8 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
|
||||
#define snd_hda_codec_cleanup_stream(codec, nid) \
|
||||
__snd_hda_codec_cleanup_stream(codec, nid, 0)
|
||||
|
||||
#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \
|
||||
snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp)
|
||||
#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, subfmtp, bpsp) \
|
||||
snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, subfmtp, bpsp)
|
||||
#define snd_hda_is_supported_format(codec, nid, fmt) \
|
||||
snd_hdac_is_supported_format(&(codec)->core, nid, fmt)
|
||||
|
||||
|
@ -33,7 +33,7 @@ struct hda_device_id;
|
||||
/*
|
||||
* exported bus type
|
||||
*/
|
||||
extern struct bus_type snd_hda_bus_type;
|
||||
extern const struct bus_type snd_hda_bus_type;
|
||||
|
||||
/*
|
||||
* generic arrays
|
||||
@ -140,13 +140,14 @@ int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
|
||||
hda_nid_t *conn_list, int max_conns);
|
||||
int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
|
||||
hda_nid_t *start_id);
|
||||
unsigned int snd_hdac_calc_stream_format(unsigned int rate,
|
||||
unsigned int channels,
|
||||
snd_pcm_format_t format,
|
||||
unsigned int maxbps,
|
||||
unsigned short spdif_ctls);
|
||||
unsigned int snd_hdac_stream_format_bits(snd_pcm_format_t format, snd_pcm_subformat_t subformat,
|
||||
unsigned int maxbits);
|
||||
unsigned int snd_hdac_stream_format(unsigned int channels, unsigned int bits, unsigned int rate);
|
||||
unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bits,
|
||||
unsigned int rate, unsigned short spdif_ctls);
|
||||
int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
|
||||
u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
|
||||
u32 *ratesp, u64 *formatsp, u32 *subformatsp,
|
||||
unsigned int *bpsp);
|
||||
bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
|
||||
unsigned int format);
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
struct snd_pcm_hardware {
|
||||
unsigned int info; /* SNDRV_PCM_INFO_* */
|
||||
u64 formats; /* SNDRV_PCM_FMTBIT_* */
|
||||
u32 subformats; /* for S32_LE, SNDRV_PCM_SUBFMTBIT_* */
|
||||
unsigned int rates; /* SNDRV_PCM_RATE_* */
|
||||
unsigned int rate_min; /* min rate */
|
||||
unsigned int rate_max; /* max rate */
|
||||
@ -217,6 +218,12 @@ struct snd_pcm_ops {
|
||||
#define SNDRV_PCM_FMTBIT_U20 SNDRV_PCM_FMTBIT_U20_BE
|
||||
#endif
|
||||
|
||||
#define _SNDRV_PCM_SUBFMTBIT(fmt) BIT((__force int)SNDRV_PCM_SUBFORMAT_##fmt)
|
||||
#define SNDRV_PCM_SUBFMTBIT_STD _SNDRV_PCM_SUBFMTBIT(STD)
|
||||
#define SNDRV_PCM_SUBFMTBIT_MSBITS_MAX _SNDRV_PCM_SUBFMTBIT(MSBITS_MAX)
|
||||
#define SNDRV_PCM_SUBFMTBIT_MSBITS_20 _SNDRV_PCM_SUBFMTBIT(MSBITS_20)
|
||||
#define SNDRV_PCM_SUBFMTBIT_MSBITS_24 _SNDRV_PCM_SUBFMTBIT(MSBITS_24)
|
||||
|
||||
struct snd_pcm_file {
|
||||
struct snd_pcm_substream *substream;
|
||||
int no_compat_mmap;
|
||||
|
@ -362,6 +362,8 @@ static inline int params_physical_width(const struct snd_pcm_hw_params *p)
|
||||
return snd_pcm_format_physical_width(params_format(p));
|
||||
}
|
||||
|
||||
int snd_pcm_hw_params_bits(const struct snd_pcm_hw_params *p);
|
||||
|
||||
static inline void
|
||||
params_set_format(struct snd_pcm_hw_params *p, snd_pcm_format_t fmt)
|
||||
{
|
||||
|
@ -31,6 +31,13 @@ enum rt5682s_dai_clks {
|
||||
RT5682S_DAI_NUM_CLKS,
|
||||
};
|
||||
|
||||
enum {
|
||||
RT5682S_LDO_1_607V,
|
||||
RT5682S_LDO_1_5V,
|
||||
RT5682S_LDO_1_406V,
|
||||
RT5682S_LDO_1_731V,
|
||||
};
|
||||
|
||||
struct rt5682s_platform_data {
|
||||
enum rt5682s_dmic1_data_pin dmic1_data_pin;
|
||||
enum rt5682s_dmic1_clk_pin dmic1_clk_pin;
|
||||
@ -38,6 +45,7 @@ struct rt5682s_platform_data {
|
||||
unsigned int dmic_clk_rate;
|
||||
unsigned int dmic_delay;
|
||||
unsigned int amic_delay;
|
||||
unsigned int ldo_dacref;
|
||||
bool dmic_clk_driving_high;
|
||||
|
||||
const char *dai_clk_names[RT5682S_DAI_NUM_CLKS];
|
||||
|
@ -195,6 +195,9 @@ int graph_util_is_ports0(struct device_node *port);
|
||||
int graph_util_parse_dai(struct device *dev, struct device_node *ep,
|
||||
struct snd_soc_dai_link_component *dlc, int *is_single_link);
|
||||
|
||||
int graph_util_parse_link_direction(struct device_node *np,
|
||||
bool *is_playback_only, bool *is_capture_only);
|
||||
|
||||
#ifdef DEBUG
|
||||
static inline void simple_util_debug_dai(struct simple_util_priv *priv,
|
||||
char *name,
|
||||
|
@ -620,6 +620,7 @@ enum snd_soc_trigger_order {
|
||||
struct snd_soc_pcm_stream {
|
||||
const char *stream_name;
|
||||
u64 formats; /* SNDRV_PCM_FMTBIT_* */
|
||||
u32 subformats; /* for S32_LE format, SNDRV_PCM_SUBFMTBIT_* */
|
||||
unsigned int rates; /* SNDRV_PCM_RATE_* */
|
||||
unsigned int rate_min; /* min rate */
|
||||
unsigned int rate_max; /* max rate */
|
||||
@ -655,8 +656,45 @@ struct snd_soc_dai_link_component {
|
||||
struct of_phandle_args *dai_args;
|
||||
};
|
||||
|
||||
struct snd_soc_dai_link_codec_ch_map {
|
||||
unsigned int connected_cpu_id;
|
||||
/*
|
||||
* [dai_link->ch_maps Image sample]
|
||||
*
|
||||
*-------------------------
|
||||
* CPU0 <---> Codec0
|
||||
*
|
||||
* ch-map[0].cpu = 0 ch-map[0].codec = 0
|
||||
*
|
||||
*-------------------------
|
||||
* CPU0 <---> Codec0
|
||||
* CPU1 <---> Codec1
|
||||
* CPU2 <---> Codec2
|
||||
*
|
||||
* ch-map[0].cpu = 0 ch-map[0].codec = 0
|
||||
* ch-map[1].cpu = 1 ch-map[1].codec = 1
|
||||
* ch-map[2].cpu = 2 ch-map[2].codec = 2
|
||||
*
|
||||
*-------------------------
|
||||
* CPU0 <---> Codec0
|
||||
* CPU1 <-+-> Codec1
|
||||
* CPU2 <-/
|
||||
*
|
||||
* ch-map[0].cpu = 0 ch-map[0].codec = 0
|
||||
* ch-map[1].cpu = 1 ch-map[1].codec = 1
|
||||
* ch-map[2].cpu = 2 ch-map[2].codec = 1
|
||||
*
|
||||
*-------------------------
|
||||
* CPU0 <---> Codec0
|
||||
* CPU1 <-+-> Codec1
|
||||
* \-> Codec2
|
||||
*
|
||||
* ch-map[0].cpu = 0 ch-map[0].codec = 0
|
||||
* ch-map[1].cpu = 1 ch-map[1].codec = 1
|
||||
* ch-map[2].cpu = 1 ch-map[2].codec = 2
|
||||
*
|
||||
*/
|
||||
struct snd_soc_dai_link_ch_map {
|
||||
unsigned int cpu;
|
||||
unsigned int codec;
|
||||
unsigned int ch_mask;
|
||||
};
|
||||
|
||||
@ -688,7 +726,9 @@ struct snd_soc_dai_link {
|
||||
struct snd_soc_dai_link_component *codecs;
|
||||
unsigned int num_codecs;
|
||||
|
||||
struct snd_soc_dai_link_codec_ch_map *codec_ch_maps;
|
||||
/* num_ch_maps = max(num_cpu, num_codecs) */
|
||||
struct snd_soc_dai_link_ch_map *ch_maps;
|
||||
|
||||
/*
|
||||
* You MAY specify the link's platform/PCM/DMA driver, either by
|
||||
* device name, or by DT/OF node, but not both. Some forms of link
|
||||
@ -775,6 +815,10 @@ struct snd_soc_dai_link {
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline int snd_soc_link_num_ch_map(struct snd_soc_dai_link *link) {
|
||||
return max(link->num_cpus, link->num_codecs);
|
||||
}
|
||||
|
||||
static inline struct snd_soc_dai_link_component*
|
||||
snd_soc_link_to_cpu(struct snd_soc_dai_link *link, int n) {
|
||||
return &(link)->cpus[n];
|
||||
@ -808,6 +852,12 @@ snd_soc_link_to_platform(struct snd_soc_dai_link *link, int n) {
|
||||
((cpu) = snd_soc_link_to_cpu(link, i)); \
|
||||
(i)++)
|
||||
|
||||
#define for_each_link_ch_maps(link, i, ch_map) \
|
||||
for ((i) = 0; \
|
||||
((i) < snd_soc_link_num_ch_map(link) && \
|
||||
((ch_map) = link->ch_maps + i)); \
|
||||
(i)++)
|
||||
|
||||
/*
|
||||
* Sample 1 : Single CPU/Codec/Platform
|
||||
*
|
||||
@ -889,7 +939,7 @@ snd_soc_link_to_platform(struct snd_soc_dai_link *link, int n) {
|
||||
#define COMP_PLATFORM(_name) { .name = _name }
|
||||
#define COMP_AUX(_name) { .name = _name }
|
||||
#define COMP_CODEC_CONF(_name) { .name = _name }
|
||||
#define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }
|
||||
#define COMP_DUMMY() /* see snd_soc_fill_dummy_dai() */
|
||||
|
||||
extern struct snd_soc_dai_link_component null_dailink_component[0];
|
||||
extern struct snd_soc_dai_link_component snd_soc_dummy_dlc;
|
||||
@ -1163,6 +1213,7 @@ struct snd_soc_pcm_runtime {
|
||||
((i) < (rtd)->dai_link->num_cpus + (rtd)->dai_link->num_codecs) && \
|
||||
((dai) = (rtd)->dais[i]); \
|
||||
(i)++)
|
||||
#define for_each_rtd_ch_maps(rtd, i, ch_maps) for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
|
||||
|
||||
void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd);
|
||||
|
||||
|
@ -57,6 +57,18 @@ enum sof_ipc_type {
|
||||
SOF_IPC_TYPE_COUNT
|
||||
};
|
||||
|
||||
struct sof_loadable_file_profile {
|
||||
enum sof_ipc_type ipc_type;
|
||||
|
||||
const char *fw_path;
|
||||
const char *fw_path_postfix;
|
||||
const char *fw_name;
|
||||
const char *fw_lib_path;
|
||||
const char *fw_lib_path_postfix;
|
||||
const char *tplg_path;
|
||||
const char *tplg_name;
|
||||
};
|
||||
|
||||
/*
|
||||
* SOF Platform data.
|
||||
*/
|
||||
@ -86,6 +98,9 @@ struct snd_sof_pdata {
|
||||
/* descriptor */
|
||||
const struct sof_dev_desc *desc;
|
||||
|
||||
/* platform's preferred IPC type and path overrides */
|
||||
struct sof_loadable_file_profile ipc_file_profile_base;
|
||||
|
||||
/* firmware and topology filenames */
|
||||
const char *fw_filename_prefix;
|
||||
const char *fw_filename;
|
||||
|
@ -51,4 +51,11 @@ struct sof_ipc_dai_sai_params {
|
||||
uint16_t tdm_slot_width;
|
||||
uint16_t reserved2; /* alignment */
|
||||
} __packed;
|
||||
|
||||
/* MICFIL Configuration Request - SOF_IPC_DAI_MICFIL_CONFIG */
|
||||
struct sof_ipc_dai_micfil_params {
|
||||
uint32_t pdm_rate;
|
||||
uint32_t pdm_ch;
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
@ -88,6 +88,7 @@ enum sof_ipc_dai_type {
|
||||
SOF_DAI_AMD_HS, /**< Amd HS */
|
||||
SOF_DAI_AMD_SP_VIRTUAL, /**< AMD ACP SP VIRTUAL */
|
||||
SOF_DAI_AMD_HS_VIRTUAL, /**< AMD ACP HS VIRTUAL */
|
||||
SOF_DAI_IMX_MICFIL, /** < i.MX MICFIL PDM */
|
||||
};
|
||||
|
||||
/* general purpose DAI configuration */
|
||||
@ -117,6 +118,7 @@ struct sof_ipc_dai_config {
|
||||
struct sof_ipc_dai_acpdmic_params acpdmic;
|
||||
struct sof_ipc_dai_acp_params acphs;
|
||||
struct sof_ipc_dai_mtk_afe_params afe;
|
||||
struct sof_ipc_dai_micfil_params micfil;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
|
@ -423,6 +423,12 @@ enum sof_ipc4_fw_config_params {
|
||||
SOF_IPC4_FW_CFG_RESERVED,
|
||||
SOF_IPC4_FW_CFG_POWER_GATING_POLICY,
|
||||
SOF_IPC4_FW_CFG_ASSERT_MODE,
|
||||
SOF_IPC4_FW_RESERVED1,
|
||||
SOF_IPC4_FW_RESERVED2,
|
||||
SOF_IPC4_FW_RESERVED3,
|
||||
SOF_IPC4_FW_RESERVED4,
|
||||
SOF_IPC4_FW_RESERVED5,
|
||||
SOF_IPC4_FW_CONTEXT_SAVE
|
||||
};
|
||||
|
||||
struct sof_ipc4_fw_version {
|
||||
@ -532,6 +538,35 @@ struct sof_ipc4_notify_resource_data {
|
||||
#define SOF_IPC4_DEBUG_SLOT_TELEMETRY 0x4c455400
|
||||
#define SOF_IPC4_DEBUG_SLOT_BROKEN 0x44414544
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_notify_module_data - payload for module notification
|
||||
* @instance_id: instance ID of the originator module of the notification
|
||||
* @module_id: module ID of the originator of the notification
|
||||
* @event_id: module specific event id
|
||||
* @event_data_size: Size of the @event_data (if any) in bytes
|
||||
* @event_data: Optional notification data, module and notification dependent
|
||||
*/
|
||||
struct sof_ipc4_notify_module_data {
|
||||
uint16_t instance_id;
|
||||
uint16_t module_id;
|
||||
uint32_t event_id;
|
||||
uint32_t event_data_size;
|
||||
uint8_t event_data[];
|
||||
} __packed __aligned(4);
|
||||
|
||||
/*
|
||||
* ALSA kcontrol change notification
|
||||
*
|
||||
* The event_id of struct sof_ipc4_notify_module_data is divided into two u16:
|
||||
* upper u16: magic number for ALSA kcontrol types: 0xA15A
|
||||
* lower u16: param_id of the control, which is the type of the control
|
||||
* The event_data contains the struct sof_ipc4_control_msg_payload of the control
|
||||
* which sent the notification.
|
||||
*/
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_MASK GENMASK(31, 16)
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL 0xA15A0000
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_PARAMID_MASK GENMASK(15, 0)
|
||||
|
||||
/** @}*/
|
||||
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@ enum sof_comp_type {
|
||||
SOF_COMP_ASRC, /**< Asynchronous sample rate converter */
|
||||
SOF_COMP_DCBLOCK,
|
||||
SOF_COMP_SMART_AMP, /**< smart amplifier component */
|
||||
SOF_COMP_MODULE_ADAPTER, /**< module adapter */
|
||||
/* keep FILEREAD/FILEWRITE as the last ones */
|
||||
SOF_COMP_FILEREAD = 10000, /**< host test based file IO */
|
||||
SOF_COMP_FILEWRITE = 10001, /**< host test based file IO */
|
||||
@ -59,7 +60,7 @@ struct sof_ipc_comp {
|
||||
|
||||
/* extended data length, 0 if no extended data */
|
||||
uint32_t ext_data_length;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/*
|
||||
* Component Buffers
|
||||
@ -68,14 +69,15 @@ struct sof_ipc_comp {
|
||||
/*
|
||||
* SOF memory capabilities, add new ones at the end
|
||||
*/
|
||||
#define SOF_MEM_CAPS_RAM (1 << 0)
|
||||
#define SOF_MEM_CAPS_ROM (1 << 1)
|
||||
#define SOF_MEM_CAPS_EXT (1 << 2) /**< external */
|
||||
#define SOF_MEM_CAPS_LP (1 << 3) /**< low power */
|
||||
#define SOF_MEM_CAPS_HP (1 << 4) /**< high performance */
|
||||
#define SOF_MEM_CAPS_DMA (1 << 5) /**< DMA'able */
|
||||
#define SOF_MEM_CAPS_CACHE (1 << 6) /**< cacheable */
|
||||
#define SOF_MEM_CAPS_EXEC (1 << 7) /**< executable */
|
||||
#define SOF_MEM_CAPS_RAM BIT(0)
|
||||
#define SOF_MEM_CAPS_ROM BIT(1)
|
||||
#define SOF_MEM_CAPS_EXT BIT(2) /**< external */
|
||||
#define SOF_MEM_CAPS_LP BIT(3) /**< low power */
|
||||
#define SOF_MEM_CAPS_HP BIT(4) /**< high performance */
|
||||
#define SOF_MEM_CAPS_DMA BIT(5) /**< DMA'able */
|
||||
#define SOF_MEM_CAPS_CACHE BIT(6) /**< cacheable */
|
||||
#define SOF_MEM_CAPS_EXEC BIT(7) /**< executable */
|
||||
#define SOF_MEM_CAPS_L3 BIT(8) /**< L3 memory */
|
||||
|
||||
/*
|
||||
* overrun will cause ring buffer overwrite, instead of XRUN.
|
||||
@ -87,6 +89,9 @@ struct sof_ipc_comp {
|
||||
*/
|
||||
#define SOF_BUF_UNDERRUN_PERMITTED BIT(1)
|
||||
|
||||
/* the UUID size in bytes, shared between FW and host */
|
||||
#define SOF_UUID_SIZE 16
|
||||
|
||||
/* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */
|
||||
struct sof_ipc_buffer {
|
||||
struct sof_ipc_comp comp;
|
||||
@ -94,7 +99,7 @@ struct sof_ipc_buffer {
|
||||
uint32_t caps; /**< SOF_MEM_CAPS_ */
|
||||
uint32_t flags; /**< SOF_BUF_ flags defined above */
|
||||
uint32_t reserved; /**< reserved for future use */
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic component config data - must always be after struct sof_ipc_comp */
|
||||
struct sof_ipc_comp_config {
|
||||
@ -107,7 +112,7 @@ struct sof_ipc_comp_config {
|
||||
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[2];
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic host component */
|
||||
struct sof_ipc_comp_host {
|
||||
@ -116,7 +121,7 @@ struct sof_ipc_comp_host {
|
||||
uint32_t direction; /**< SOF_IPC_STREAM_ */
|
||||
uint32_t no_irq; /**< don't send periodic IRQ to host/DSP */
|
||||
uint32_t dmac_config; /**< DMA engine specific */
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic DAI component */
|
||||
struct sof_ipc_comp_dai {
|
||||
@ -126,13 +131,13 @@ struct sof_ipc_comp_dai {
|
||||
uint32_t dai_index; /**< index of this type dai */
|
||||
uint32_t type; /**< DAI type - SOF_DAI_ */
|
||||
uint32_t reserved; /**< reserved */
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic mixer component */
|
||||
struct sof_ipc_comp_mixer {
|
||||
struct sof_ipc_comp comp;
|
||||
struct sof_ipc_comp_config config;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* volume ramping types */
|
||||
enum sof_volume_ramp {
|
||||
@ -140,6 +145,8 @@ enum sof_volume_ramp {
|
||||
SOF_VOLUME_LOG,
|
||||
SOF_VOLUME_LINEAR_ZC,
|
||||
SOF_VOLUME_LOG_ZC,
|
||||
SOF_VOLUME_WINDOWS_FADE,
|
||||
SOF_VOLUME_WINDOWS_NO_FADE,
|
||||
};
|
||||
|
||||
/* generic volume component */
|
||||
@ -151,7 +158,7 @@ struct sof_ipc_comp_volume {
|
||||
uint32_t max_value;
|
||||
uint32_t ramp; /**< SOF_VOLUME_ */
|
||||
uint32_t initial_ramp; /**< ramp space in ms */
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic SRC component */
|
||||
struct sof_ipc_comp_src {
|
||||
@ -161,7 +168,7 @@ struct sof_ipc_comp_src {
|
||||
uint32_t source_rate; /**< source rate or 0 for variable */
|
||||
uint32_t sink_rate; /**< sink rate or 0 for variable */
|
||||
uint32_t rate_mask; /**< SOF_RATE_ supported rates */
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic ASRC component */
|
||||
struct sof_ipc_comp_asrc {
|
||||
@ -187,13 +194,13 @@ struct sof_ipc_comp_asrc {
|
||||
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[4];
|
||||
} __attribute__((packed));
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic MUX component */
|
||||
struct sof_ipc_comp_mux {
|
||||
struct sof_ipc_comp comp;
|
||||
struct sof_ipc_comp_config config;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* generic tone generator component */
|
||||
struct sof_ipc_comp_tone {
|
||||
@ -208,7 +215,7 @@ struct sof_ipc_comp_tone {
|
||||
int32_t period;
|
||||
int32_t repeats;
|
||||
int32_t ramp_step;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/** \brief Types of processing components */
|
||||
enum sof_ipc_process_type {
|
||||
@ -234,8 +241,8 @@ struct sof_ipc_comp_process {
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[7];
|
||||
|
||||
uint8_t data[];
|
||||
} __packed;
|
||||
unsigned char data[];
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* frees components, buffers and pipelines
|
||||
* SOF_IPC_TPLG_COMP_FREE, SOF_IPC_TPLG_PIPE_FREE, SOF_IPC_TPLG_BUFFER_FREE
|
||||
@ -243,13 +250,13 @@ struct sof_ipc_comp_process {
|
||||
struct sof_ipc_free {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
uint32_t id;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct sof_ipc_comp_reply {
|
||||
struct sof_ipc_reply rhdr;
|
||||
uint32_t id;
|
||||
uint32_t offset;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/*
|
||||
* Pipeline
|
||||
@ -274,25 +281,25 @@ struct sof_ipc_pipe_new {
|
||||
uint32_t frames_per_sched;/**< output frames of pipeline, 0 is variable */
|
||||
uint32_t xrun_limit_usecs; /**< report xruns greater than limit */
|
||||
uint32_t time_domain; /**< scheduling time domain */
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* pipeline construction complete - SOF_IPC_TPLG_PIPE_COMPLETE */
|
||||
struct sof_ipc_pipe_ready {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
uint32_t comp_id;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct sof_ipc_pipe_free {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
uint32_t comp_id;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* connect two components in pipeline - SOF_IPC_TPLG_COMP_CONNECT */
|
||||
struct sof_ipc_pipe_comp_connect {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
uint32_t source_id;
|
||||
uint32_t sink_id;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* external events */
|
||||
enum sof_event_types {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define TAS2781_DRV_VER 1
|
||||
#define SMARTAMP_MODULE_NAME "tas2781"
|
||||
#define TAS2781_GLOBAL_ADDR 0x40
|
||||
#define TAS2563_GLOBAL_ADDR 0x48
|
||||
#define TASDEVICE_RATES (SNDRV_PCM_RATE_44100 |\
|
||||
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
|
||||
SNDRV_PCM_RATE_88200)
|
||||
@ -121,6 +122,8 @@ struct tasdevice_priv {
|
||||
bool force_fwload_status;
|
||||
bool playback_started;
|
||||
bool isacpi;
|
||||
unsigned int global_addr;
|
||||
|
||||
int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv,
|
||||
const struct firmware *fmw, int offset);
|
||||
int (*fw_parse_program_data)(struct tasdevice_priv *tas_priv,
|
||||
@ -131,6 +134,9 @@ struct tasdevice_priv {
|
||||
const struct firmware *fmw, int offset);
|
||||
int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv,
|
||||
struct tasdev_blk *block);
|
||||
|
||||
int (*save_calibration)(struct tasdevice_priv *tas_priv);
|
||||
void (*apply_calibration)(struct tasdevice_priv *tas_priv);
|
||||
};
|
||||
|
||||
void tas2781_reset(struct tasdevice_priv *tas_dev);
|
||||
@ -139,6 +145,8 @@ int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
|
||||
struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c);
|
||||
int tasdevice_init(struct tasdevice_priv *tas_priv);
|
||||
void tasdevice_remove(struct tasdevice_priv *tas_priv);
|
||||
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
|
||||
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
|
||||
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
|
||||
unsigned short chn, unsigned int reg, unsigned int *value);
|
||||
int tasdevice_dev_write(struct tasdevice_priv *tas_priv,
|
||||
|
@ -11,12 +11,6 @@
|
||||
#define WM0010_PDATA_H
|
||||
|
||||
struct wm0010_pdata {
|
||||
int gpio_reset;
|
||||
|
||||
/* Set if there is an inverter between the GPIO controlling
|
||||
* the reset signal and the device.
|
||||
*/
|
||||
int reset_active_high;
|
||||
int irq_flags;
|
||||
};
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* linux/sound/wm1250-ev1.h - Platform data for WM1250-EV1
|
||||
*
|
||||
* Copyright 2011 Wolfson Microelectronics. PLC.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_WM1250_EV1_H
|
||||
#define __LINUX_SND_WM1250_EV1_H
|
||||
|
||||
#define WM1250_EV1_NUM_GPIOS 5
|
||||
|
||||
#define WM1250_EV1_GPIO_CLK_ENA 0
|
||||
#define WM1250_EV1_GPIO_CLK_SEL0 1
|
||||
#define WM1250_EV1_GPIO_CLK_SEL1 2
|
||||
#define WM1250_EV1_GPIO_OSR 3
|
||||
#define WM1250_EV1_GPIO_MASTER 4
|
||||
|
||||
|
||||
struct wm1250_ev1_pdata {
|
||||
int gpios[WM1250_EV1_NUM_GPIOS];
|
||||
};
|
||||
|
||||
#endif
|
@ -42,8 +42,6 @@ struct wm2200_micbias {
|
||||
};
|
||||
|
||||
struct wm2200_pdata {
|
||||
int reset; /** GPIO controlling /RESET, if any */
|
||||
int ldo_ena; /** GPIO controlling LODENA, if any */
|
||||
int irq_flags;
|
||||
|
||||
int gpio_defaults[4];
|
||||
|
@ -36,11 +36,7 @@ struct wm5100_jack_mode {
|
||||
#define WM5100_GPIO_SET 0x10000
|
||||
|
||||
struct wm5100_pdata {
|
||||
int reset; /** GPIO controlling /RESET, if any */
|
||||
int ldo_ena; /** GPIO controlling LODENA, if any */
|
||||
int hp_pol; /** GPIO controlling headset polarity, if any */
|
||||
int irq_flags;
|
||||
int gpio_base;
|
||||
|
||||
struct wm5100_jack_mode jack_modes[2];
|
||||
|
||||
|
@ -33,8 +33,6 @@ struct wm8996_retune_mobile_config {
|
||||
struct wm8996_pdata {
|
||||
int irq_flags; /** Set IRQ trigger flags; default active low */
|
||||
|
||||
int ldo_ena; /** GPIO for LDO1; -1 for none */
|
||||
|
||||
int micdet_def; /** Default MICDET_SRC/HP1FB_SRC/MICD_BIAS */
|
||||
|
||||
enum wm8996_inmode inl_mode;
|
||||
@ -42,7 +40,6 @@ struct wm8996_pdata {
|
||||
|
||||
u32 spkmute_seq; /** Value for register 0x802 */
|
||||
|
||||
int gpio_base;
|
||||
u32 gpio_default[5];
|
||||
|
||||
int num_retune_mobile_cfgs;
|
||||
|
@ -142,7 +142,7 @@ struct snd_hwdep_dsp_image {
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15)
|
||||
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 16)
|
||||
|
||||
typedef unsigned long snd_pcm_uframes_t;
|
||||
typedef signed long snd_pcm_sframes_t;
|
||||
@ -267,7 +267,10 @@ typedef int __bitwise snd_pcm_format_t;
|
||||
|
||||
typedef int __bitwise snd_pcm_subformat_t;
|
||||
#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
|
||||
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
|
||||
#define SNDRV_PCM_SUBFORMAT_MSBITS_MAX ((__force snd_pcm_subformat_t) 1)
|
||||
#define SNDRV_PCM_SUBFORMAT_MSBITS_20 ((__force snd_pcm_subformat_t) 2)
|
||||
#define SNDRV_PCM_SUBFORMAT_MSBITS_24 ((__force snd_pcm_subformat_t) 3)
|
||||
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_MSBITS_24
|
||||
|
||||
#define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */
|
||||
#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */
|
||||
|
54
include/uapi/sound/scarlett2.h
Normal file
54
include/uapi/sound/scarlett2.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Focusrite Scarlett 2 Protocol Driver for ALSA
|
||||
* (including Scarlett 2nd Gen, 3rd Gen, 4th Gen, Clarett USB, and
|
||||
* Clarett+ series products)
|
||||
*
|
||||
* Copyright (c) 2023 by Geoffrey D. Bennett <g at b4.vu>
|
||||
*/
|
||||
#ifndef __UAPI_SOUND_SCARLETT2_H
|
||||
#define __UAPI_SOUND_SCARLETT2_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define SCARLETT2_HWDEP_MAJOR 1
|
||||
#define SCARLETT2_HWDEP_MINOR 0
|
||||
#define SCARLETT2_HWDEP_SUBMINOR 0
|
||||
|
||||
#define SCARLETT2_HWDEP_VERSION \
|
||||
((SCARLETT2_HWDEP_MAJOR << 16) | \
|
||||
(SCARLETT2_HWDEP_MINOR << 8) | \
|
||||
SCARLETT2_HWDEP_SUBMINOR)
|
||||
|
||||
#define SCARLETT2_HWDEP_VERSION_MAJOR(v) (((v) >> 16) & 0xFF)
|
||||
#define SCARLETT2_HWDEP_VERSION_MINOR(v) (((v) >> 8) & 0xFF)
|
||||
#define SCARLETT2_HWDEP_VERSION_SUBMINOR(v) ((v) & 0xFF)
|
||||
|
||||
/* Get protocol version */
|
||||
#define SCARLETT2_IOCTL_PVERSION _IOR('S', 0x60, int)
|
||||
|
||||
/* Reboot */
|
||||
#define SCARLETT2_IOCTL_REBOOT _IO('S', 0x61)
|
||||
|
||||
/* Select flash segment */
|
||||
#define SCARLETT2_SEGMENT_ID_SETTINGS 0
|
||||
#define SCARLETT2_SEGMENT_ID_FIRMWARE 1
|
||||
#define SCARLETT2_SEGMENT_ID_COUNT 2
|
||||
|
||||
#define SCARLETT2_IOCTL_SELECT_FLASH_SEGMENT _IOW('S', 0x62, int)
|
||||
|
||||
/* Erase selected flash segment */
|
||||
#define SCARLETT2_IOCTL_ERASE_FLASH_SEGMENT _IO('S', 0x63)
|
||||
|
||||
/* Get selected flash segment erase progress
|
||||
* 1 through to num_blocks, or 255 for complete
|
||||
*/
|
||||
struct scarlett2_flash_segment_erase_progress {
|
||||
unsigned char progress;
|
||||
unsigned char num_blocks;
|
||||
};
|
||||
#define SCARLETT2_IOCTL_GET_ERASE_PROGRESS \
|
||||
_IOR('S', 0x64, struct scarlett2_flash_segment_erase_progress)
|
||||
|
||||
#endif /* __UAPI_SOUND_SCARLETT2_H */
|
@ -35,6 +35,7 @@
|
||||
/* buffers */
|
||||
#define SOF_TKN_BUF_SIZE 100
|
||||
#define SOF_TKN_BUF_CAPS 101
|
||||
#define SOF_TKN_BUF_FLAGS 102
|
||||
|
||||
/* DAI */
|
||||
/* Token retired with ABI 3.2, do not use for new capabilities
|
||||
@ -213,4 +214,8 @@
|
||||
#define SOF_TKN_AMD_ACPI2S_CH 1701
|
||||
#define SOF_TKN_AMD_ACPI2S_TDM_MODE 1702
|
||||
|
||||
/* MICFIL PDM */
|
||||
#define SOF_TKN_IMX_MICFIL_RATE 2000
|
||||
#define SOF_TKN_IMX_MICFIL_CH 2001
|
||||
|
||||
#endif
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <sound/ac97/codec.h>
|
||||
#include <sound/ac97/controller.h>
|
||||
#include <sound/ac97/regs.h>
|
||||
@ -28,8 +29,6 @@ static DEFINE_MUTEX(ac97_controllers_mutex);
|
||||
static DEFINE_IDR(ac97_adapter_idr);
|
||||
static LIST_HEAD(ac97_controllers);
|
||||
|
||||
static struct bus_type ac97_bus_type;
|
||||
|
||||
static inline struct ac97_controller*
|
||||
to_ac97_controller(struct device *ac97_adapter)
|
||||
{
|
||||
@ -531,7 +530,7 @@ static void ac97_bus_remove(struct device *dev)
|
||||
pm_runtime_disable(dev);
|
||||
}
|
||||
|
||||
static struct bus_type ac97_bus_type = {
|
||||
const struct bus_type ac97_bus_type = {
|
||||
.name = "ac97bus",
|
||||
.dev_groups = ac97_dev_groups,
|
||||
.match = ac97_bus_match,
|
||||
|
@ -75,7 +75,7 @@ int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_ac97_reset);
|
||||
|
||||
struct bus_type ac97_bus_type = {
|
||||
const struct bus_type ac97_bus_type = {
|
||||
.name = "ac97",
|
||||
};
|
||||
|
||||
|
@ -266,6 +266,9 @@ static const char * const snd_pcm_access_names[] = {
|
||||
|
||||
static const char * const snd_pcm_subformat_names[] = {
|
||||
SUBFORMAT(STD),
|
||||
SUBFORMAT(MSBITS_MAX),
|
||||
SUBFORMAT(MSBITS_20),
|
||||
SUBFORMAT(MSBITS_24),
|
||||
};
|
||||
|
||||
static const char * const snd_pcm_tstamp_mode_names[] = {
|
||||
|
@ -1706,6 +1706,40 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_hw_param_last);
|
||||
|
||||
/**
|
||||
* snd_pcm_hw_params_bits - Get the number of bits per the sample.
|
||||
* @p: hardware parameters
|
||||
*
|
||||
* Return: The number of bits per sample based on the format,
|
||||
* subformat and msbits the specified hw params has.
|
||||
*/
|
||||
int snd_pcm_hw_params_bits(const struct snd_pcm_hw_params *p)
|
||||
{
|
||||
snd_pcm_subformat_t subformat = params_subformat(p);
|
||||
snd_pcm_format_t format = params_format(p);
|
||||
|
||||
switch (format) {
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
case SNDRV_PCM_FORMAT_U32_LE:
|
||||
case SNDRV_PCM_FORMAT_S32_BE:
|
||||
case SNDRV_PCM_FORMAT_U32_BE:
|
||||
switch (subformat) {
|
||||
case SNDRV_PCM_SUBFORMAT_MSBITS_20:
|
||||
return 20;
|
||||
case SNDRV_PCM_SUBFORMAT_MSBITS_24:
|
||||
return 24;
|
||||
case SNDRV_PCM_SUBFORMAT_MSBITS_MAX:
|
||||
case SNDRV_PCM_SUBFORMAT_STD:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
default:
|
||||
return snd_pcm_format_width(format);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_hw_params_bits);
|
||||
|
||||
static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
|
||||
void *arg)
|
||||
{
|
||||
|
@ -479,6 +479,7 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
|
||||
{
|
||||
const struct snd_interval *i;
|
||||
const struct snd_mask *m;
|
||||
struct snd_mask *m_rw;
|
||||
int err;
|
||||
|
||||
if (!params->msbits) {
|
||||
@ -487,6 +488,22 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
|
||||
params->msbits = snd_interval_value(i);
|
||||
}
|
||||
|
||||
if (params->msbits) {
|
||||
m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
||||
if (snd_mask_single(m)) {
|
||||
snd_pcm_format_t format = (__force snd_pcm_format_t)snd_mask_min(m);
|
||||
|
||||
if (snd_pcm_format_linear(format) &&
|
||||
snd_pcm_format_width(format) != params->msbits) {
|
||||
m_rw = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
|
||||
snd_mask_reset(m_rw,
|
||||
(__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
|
||||
if (snd_mask_empty(m_rw))
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!params->rate_den) {
|
||||
i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
|
||||
if (snd_interval_single(i)) {
|
||||
@ -2483,6 +2500,41 @@ static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params,
|
||||
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
|
||||
}
|
||||
|
||||
static int snd_pcm_hw_rule_subformats(struct snd_pcm_hw_params *params,
|
||||
struct snd_pcm_hw_rule *rule)
|
||||
{
|
||||
struct snd_mask *sfmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
|
||||
struct snd_mask *fmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
||||
u32 *subformats = rule->private;
|
||||
snd_pcm_format_t f;
|
||||
struct snd_mask m;
|
||||
|
||||
snd_mask_none(&m);
|
||||
/* All PCMs support at least the default STD subformat. */
|
||||
snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_STD);
|
||||
|
||||
pcm_for_each_format(f) {
|
||||
if (!snd_mask_test(fmask, (__force unsigned)f))
|
||||
continue;
|
||||
|
||||
if (f == SNDRV_PCM_FORMAT_S32_LE && *subformats)
|
||||
m.bits[0] |= *subformats;
|
||||
else if (snd_pcm_format_linear(f))
|
||||
snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
|
||||
}
|
||||
|
||||
return snd_mask_refine(sfmask, &m);
|
||||
}
|
||||
|
||||
static int snd_pcm_hw_constraint_subformats(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond, u32 *subformats)
|
||||
{
|
||||
return snd_pcm_hw_rule_add(runtime, cond, -1,
|
||||
snd_pcm_hw_rule_subformats, (void *)subformats,
|
||||
SNDRV_PCM_HW_PARAM_SUBFORMAT,
|
||||
SNDRV_PCM_HW_PARAM_FORMAT, -1);
|
||||
}
|
||||
|
||||
static int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
@ -2634,8 +2686,7 @@ static int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT,
|
||||
PARAM_MASK_BIT(SNDRV_PCM_SUBFORMAT_STD));
|
||||
err = snd_pcm_hw_constraint_subformats(runtime, 0, &hw->subformats);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -442,7 +442,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
|
||||
if (snd_BUG_ON(!pool))
|
||||
return -EINVAL;
|
||||
|
||||
cellptr = kvmalloc_array(sizeof(struct snd_seq_event_cell), pool->size,
|
||||
cellptr = kvmalloc_array(pool->size,
|
||||
sizeof(struct snd_seq_event_cell),
|
||||
GFP_KERNEL);
|
||||
if (!cellptr)
|
||||
return -ENOMEM;
|
||||
|
@ -76,7 +76,7 @@ static int hda_uevent(const struct device *dev, struct kobj_uevent_env *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct bus_type snd_hda_bus_type = {
|
||||
const struct bus_type snd_hda_bus_type = {
|
||||
.name = "hdaudio",
|
||||
.match = hda_bus_match,
|
||||
.uevent = hda_uevent,
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <sound/hdaudio.h>
|
||||
#include <sound/hda_regmap.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include "local.h"
|
||||
|
||||
static void setup_fg_nodes(struct hdac_device *codec);
|
||||
@ -725,32 +726,77 @@ static const struct hda_rate_tbl rate_bits[] = {
|
||||
{ 0 } /* terminator */
|
||||
};
|
||||
|
||||
/**
|
||||
* snd_hdac_calc_stream_format - calculate the format bitset
|
||||
* @rate: the sample rate
|
||||
* @channels: the number of channels
|
||||
* @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
|
||||
* @maxbps: the max. bps
|
||||
* @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant)
|
||||
*
|
||||
* Calculate the format bitset from the given rate, channels and th PCM format.
|
||||
*
|
||||
* Return zero if invalid.
|
||||
*/
|
||||
unsigned int snd_hdac_calc_stream_format(unsigned int rate,
|
||||
unsigned int channels,
|
||||
snd_pcm_format_t format,
|
||||
unsigned int maxbps,
|
||||
unsigned short spdif_ctls)
|
||||
static snd_pcm_format_t snd_hdac_format_normalize(snd_pcm_format_t format)
|
||||
{
|
||||
int i;
|
||||
unsigned int val = 0;
|
||||
switch (format) {
|
||||
case SNDRV_PCM_FORMAT_S20_LE:
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
return SNDRV_PCM_FORMAT_S32_LE;
|
||||
|
||||
for (i = 0; rate_bits[i].hz; i++)
|
||||
case SNDRV_PCM_FORMAT_U20_LE:
|
||||
case SNDRV_PCM_FORMAT_U24_LE:
|
||||
return SNDRV_PCM_FORMAT_U32_LE;
|
||||
|
||||
case SNDRV_PCM_FORMAT_S20_BE:
|
||||
case SNDRV_PCM_FORMAT_S24_BE:
|
||||
return SNDRV_PCM_FORMAT_S32_BE;
|
||||
|
||||
case SNDRV_PCM_FORMAT_U20_BE:
|
||||
case SNDRV_PCM_FORMAT_U24_BE:
|
||||
return SNDRV_PCM_FORMAT_U32_BE;
|
||||
|
||||
default:
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hdac_stream_format_bits - obtain bits per sample value.
|
||||
* @format: the PCM format.
|
||||
* @subformat: the PCM subformat.
|
||||
* @maxbits: the maximum bits per sample.
|
||||
*
|
||||
* Return: The number of bits per sample.
|
||||
*/
|
||||
unsigned int snd_hdac_stream_format_bits(snd_pcm_format_t format, snd_pcm_subformat_t subformat,
|
||||
unsigned int maxbits)
|
||||
{
|
||||
struct snd_pcm_hw_params params;
|
||||
unsigned int bits;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
params_set_format(¶ms, snd_hdac_format_normalize(format));
|
||||
snd_mask_set(hw_param_mask(¶ms, SNDRV_PCM_HW_PARAM_SUBFORMAT),
|
||||
(__force unsigned int)subformat);
|
||||
|
||||
bits = snd_pcm_hw_params_bits(¶ms);
|
||||
if (maxbits)
|
||||
return min(bits, maxbits);
|
||||
return bits;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_stream_format_bits);
|
||||
|
||||
/**
|
||||
* snd_hdac_stream_format - convert format parameters to SDxFMT value.
|
||||
* @channels: the number of channels.
|
||||
* @bits: bits per sample.
|
||||
* @rate: the sample rate.
|
||||
*
|
||||
* Return: The format bitset or zero if invalid.
|
||||
*/
|
||||
unsigned int snd_hdac_stream_format(unsigned int channels, unsigned int bits, unsigned int rate)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; rate_bits[i].hz; i++) {
|
||||
if (rate_bits[i].hz == rate) {
|
||||
val = rate_bits[i].hda_fmt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rate_bits[i].hz)
|
||||
return 0;
|
||||
|
||||
@ -758,7 +804,7 @@ unsigned int snd_hdac_calc_stream_format(unsigned int rate,
|
||||
return 0;
|
||||
val |= channels - 1;
|
||||
|
||||
switch (snd_pcm_format_width(format)) {
|
||||
switch (bits) {
|
||||
case 8:
|
||||
val |= AC_FMT_BITS_8;
|
||||
break;
|
||||
@ -766,25 +812,42 @@ unsigned int snd_hdac_calc_stream_format(unsigned int rate,
|
||||
val |= AC_FMT_BITS_16;
|
||||
break;
|
||||
case 20:
|
||||
val |= AC_FMT_BITS_20;
|
||||
break;
|
||||
case 24:
|
||||
val |= AC_FMT_BITS_24;
|
||||
break;
|
||||
case 32:
|
||||
if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
|
||||
val |= AC_FMT_BITS_32;
|
||||
else if (maxbps >= 24)
|
||||
val |= AC_FMT_BITS_24;
|
||||
else
|
||||
val |= AC_FMT_BITS_20;
|
||||
val |= AC_FMT_BITS_32;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (spdif_ctls & AC_DIG1_NONAUDIO)
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_stream_format);
|
||||
|
||||
/**
|
||||
* snd_hdac_spdif_stream_format - convert format parameters to SDxFMT value.
|
||||
* @channels: the number of channels.
|
||||
* @bits: bits per sample.
|
||||
* @rate: the sample rate.
|
||||
* @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant).
|
||||
*
|
||||
* Return: The format bitset or zero if invalid.
|
||||
*/
|
||||
unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bits,
|
||||
unsigned int rate, unsigned short spdif_ctls)
|
||||
{
|
||||
unsigned int val = snd_hdac_stream_format(channels, bits, rate);
|
||||
|
||||
if (val && spdif_ctls & AC_DIG1_NONAUDIO)
|
||||
val |= AC_FMT_TYPE_NON_PCM;
|
||||
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_calc_stream_format);
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_spdif_stream_format);
|
||||
|
||||
static unsigned int query_pcm_param(struct hdac_device *codec, hda_nid_t nid)
|
||||
{
|
||||
@ -817,15 +880,17 @@ static unsigned int query_stream_param(struct hdac_device *codec, hda_nid_t nid)
|
||||
* @nid: NID to query
|
||||
* @ratesp: the pointer to store the detected rate bitflags
|
||||
* @formatsp: the pointer to store the detected formats
|
||||
* @subformatsp: the pointer to store the detected subformats for S32_LE format
|
||||
* @bpsp: the pointer to store the detected format widths
|
||||
*
|
||||
* Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
|
||||
* or @bsps argument is ignored.
|
||||
* Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp,
|
||||
* @subformatsp or @bpsp argument is ignored.
|
||||
*
|
||||
* Returns 0 if successful, otherwise a negative error code.
|
||||
*/
|
||||
int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
|
||||
u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
|
||||
u32 *ratesp, u64 *formatsp, u32 *subformatsp,
|
||||
unsigned int *bpsp)
|
||||
{
|
||||
unsigned int i, val, wcaps;
|
||||
|
||||
@ -848,9 +913,10 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
|
||||
*ratesp = rates;
|
||||
}
|
||||
|
||||
if (formatsp || bpsp) {
|
||||
u64 formats = 0;
|
||||
if (formatsp || subformatsp || bpsp) {
|
||||
unsigned int streams, bps;
|
||||
u32 subformats = 0;
|
||||
u64 formats = 0;
|
||||
|
||||
streams = query_stream_param(codec, nid);
|
||||
if (!streams)
|
||||
@ -866,24 +932,24 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
|
||||
formats |= SNDRV_PCM_FMTBIT_S16_LE;
|
||||
bps = 16;
|
||||
}
|
||||
if (wcaps & AC_WCAP_DIGITAL) {
|
||||
if (val & AC_SUPPCM_BITS_32)
|
||||
formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
|
||||
if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
|
||||
formats |= SNDRV_PCM_FMTBIT_S32_LE;
|
||||
if (val & AC_SUPPCM_BITS_24)
|
||||
bps = 24;
|
||||
else if (val & AC_SUPPCM_BITS_20)
|
||||
bps = 20;
|
||||
} else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
|
||||
AC_SUPPCM_BITS_32)) {
|
||||
if (val & AC_SUPPCM_BITS_20) {
|
||||
formats |= SNDRV_PCM_FMTBIT_S32_LE;
|
||||
if (val & AC_SUPPCM_BITS_32)
|
||||
subformats |= SNDRV_PCM_SUBFMTBIT_MSBITS_20;
|
||||
bps = 20;
|
||||
}
|
||||
if (val & AC_SUPPCM_BITS_24) {
|
||||
formats |= SNDRV_PCM_FMTBIT_S32_LE;
|
||||
subformats |= SNDRV_PCM_SUBFMTBIT_MSBITS_24;
|
||||
bps = 24;
|
||||
}
|
||||
if (val & AC_SUPPCM_BITS_32) {
|
||||
if (wcaps & AC_WCAP_DIGITAL) {
|
||||
formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
|
||||
} else {
|
||||
formats |= SNDRV_PCM_FMTBIT_S32_LE;
|
||||
subformats |= SNDRV_PCM_SUBFMTBIT_MSBITS_MAX;
|
||||
bps = 32;
|
||||
else if (val & AC_SUPPCM_BITS_24)
|
||||
bps = 24;
|
||||
else if (val & AC_SUPPCM_BITS_20)
|
||||
bps = 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */
|
||||
@ -911,6 +977,8 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
|
||||
}
|
||||
if (formatsp)
|
||||
*formatsp = formats;
|
||||
if (subformatsp)
|
||||
*subformatsp = subformats;
|
||||
if (bpsp)
|
||||
*bpsp = bps;
|
||||
}
|
||||
|
@ -671,17 +671,15 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
|
||||
struct hdac_stream *s;
|
||||
bool inited = false;
|
||||
u64 cycle_last = 0;
|
||||
int i = 0;
|
||||
|
||||
list_for_each_entry(s, &bus->stream_list, list) {
|
||||
if (streams & (1 << i)) {
|
||||
if ((streams & (1 << s->index))) {
|
||||
azx_timecounter_init(s, inited, cycle_last);
|
||||
if (!inited) {
|
||||
inited = true;
|
||||
cycle_last = s->tc.cycle_last;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
|
||||
@ -726,14 +724,13 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
|
||||
unsigned int streams)
|
||||
{
|
||||
struct hdac_bus *bus = azx_dev->bus;
|
||||
int i, nwait, timeout;
|
||||
int nwait, timeout;
|
||||
struct hdac_stream *s;
|
||||
|
||||
for (timeout = 5000; timeout; timeout--) {
|
||||
nwait = 0;
|
||||
i = 0;
|
||||
list_for_each_entry(s, &bus->stream_list, list) {
|
||||
if (!(streams & (1 << i++)))
|
||||
if (!(streams & (1 << s->index)))
|
||||
continue;
|
||||
|
||||
if (start) {
|
||||
|
@ -521,6 +521,16 @@ static const struct config_entry config_table[] = {
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
|
||||
.device = PCI_DEVICE_ID_INTEL_HDA_MTL,
|
||||
},
|
||||
/* ArrowLake-S */
|
||||
{
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
|
||||
.device = PCI_DEVICE_ID_INTEL_HDA_ARL_S,
|
||||
},
|
||||
/* ArrowLake */
|
||||
{
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
|
||||
.device = PCI_DEVICE_ID_INTEL_HDA_ARL,
|
||||
},
|
||||
#endif
|
||||
|
||||
/* Lunar Lake */
|
||||
|
@ -191,9 +191,9 @@ snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file,
|
||||
"> 512 bytes to FX\n");
|
||||
return -EIO;
|
||||
}
|
||||
page_data = memdup_user((unsigned char __user *)
|
||||
r.data[3],
|
||||
r.data[2] * sizeof(short));
|
||||
page_data = memdup_array_user((unsigned char __user *)
|
||||
r.data[3],
|
||||
r.data[2], sizeof(short));
|
||||
if (IS_ERR(page_data))
|
||||
return PTR_ERR(page_data);
|
||||
pd = page_data;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Thanks to the ALSA developers, they helped a lot working out
|
||||
* the ALSA part.
|
||||
* Thanks also to Sourceforge for maintaining the old binary drivers,
|
||||
* and the forum, where developers could comunicate.
|
||||
* and the forum, where developers could communicate.
|
||||
*
|
||||
* Now at least i can play Legacy DOOM with MIDI music :-)
|
||||
*/
|
||||
|
@ -1195,7 +1195,7 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
|
||||
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
|
||||
snd_pcm_sgbuf_get_addr(dma->substream,
|
||||
dma->period_bytes * p));
|
||||
/* Force write thru cache. */
|
||||
/* Force write through cache. */
|
||||
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
|
||||
(((adbdma << 2) + pp) << 2));
|
||||
}
|
||||
@ -1237,7 +1237,7 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
|
||||
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
|
||||
snd_pcm_sgbuf_get_addr(dma->substream,
|
||||
dma->period_bytes * p));
|
||||
/* Force write thru cache. */
|
||||
/* Force write through cache. */
|
||||
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
|
||||
}
|
||||
}
|
||||
@ -1466,7 +1466,7 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
|
||||
(((wtdma << 2) + pp) << 2),
|
||||
snd_pcm_sgbuf_get_addr(dma->substream,
|
||||
dma->period_bytes * p));
|
||||
/* Force write thru cache. */
|
||||
/* Force write through cache. */
|
||||
hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
|
||||
(((wtdma << 2) + pp) << 2));
|
||||
}
|
||||
@ -1854,7 +1854,7 @@ vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,
|
||||
vortex_mix_disableinput(vortex, mix, mixin, a);
|
||||
}
|
||||
|
||||
// Connect absolut address to mixin.
|
||||
// Connect absolute address to mixin.
|
||||
static void
|
||||
vortex_connection_adb_mixin(vortex_t * vortex, int en,
|
||||
unsigned char channel, unsigned char source,
|
||||
@ -1880,7 +1880,7 @@ vortex_connection_src_src_adbdma(vortex_t * vortex, int en,
|
||||
ADB_DMA(adbdma));
|
||||
}
|
||||
|
||||
// mix to absolut address.
|
||||
// mix to absolute address.
|
||||
static void
|
||||
vortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,
|
||||
unsigned char mix, unsigned char dest)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <sound/hda_codec.h>
|
||||
#include <sound/soc.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include "hda_local.h"
|
||||
#include "hda_auto_parser.h"
|
||||
#include "hda_jack.h"
|
||||
@ -996,6 +997,11 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41)
|
||||
__be32 halo_sts;
|
||||
int ret;
|
||||
|
||||
if (cs35l41->bypass_fw) {
|
||||
dev_warn(cs35l41->dev, "Bypassing Firmware.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = cs35l41_init_dsp(cs35l41);
|
||||
if (ret) {
|
||||
dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret);
|
||||
@ -1588,6 +1594,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
|
||||
u32 values[HDA_MAX_COMPONENTS];
|
||||
struct acpi_device *adev;
|
||||
struct device *physdev;
|
||||
struct spi_device *spi;
|
||||
const char *sub;
|
||||
char *property;
|
||||
size_t nval;
|
||||
@ -1610,7 +1617,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
|
||||
ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid);
|
||||
if (!ret) {
|
||||
dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n");
|
||||
goto put_physdev;
|
||||
goto out;
|
||||
}
|
||||
|
||||
property = "cirrus,dev-index";
|
||||
@ -1701,8 +1708,20 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
|
||||
hw_cfg->bst_type = CS35L41_EXT_BOOST;
|
||||
|
||||
hw_cfg->valid = true;
|
||||
out:
|
||||
put_device(physdev);
|
||||
|
||||
cs35l41->bypass_fw = false;
|
||||
if (cs35l41->control_bus == SPI) {
|
||||
spi = to_spi_device(cs35l41->dev);
|
||||
if (spi->max_speed_hz < CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ) {
|
||||
dev_warn(cs35l41->dev,
|
||||
"SPI speed is too slow to support firmware download: %d Hz.\n",
|
||||
spi->max_speed_hz);
|
||||
cs35l41->bypass_fw = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@ -1711,14 +1730,13 @@ err:
|
||||
hw_cfg->gpio1.valid = false;
|
||||
hw_cfg->gpio2.valid = false;
|
||||
acpi_dev_put(cs35l41->dacpi);
|
||||
put_physdev:
|
||||
put_device(physdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
|
||||
struct regmap *regmap)
|
||||
struct regmap *regmap, enum control_bus control_bus)
|
||||
{
|
||||
unsigned int regid, reg_revid;
|
||||
struct cs35l41_hda *cs35l41;
|
||||
@ -1737,6 +1755,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
|
||||
cs35l41->dev = dev;
|
||||
cs35l41->irq = irq;
|
||||
cs35l41->regmap = regmap;
|
||||
cs35l41->control_bus = control_bus;
|
||||
dev_set_drvdata(dev, cs35l41);
|
||||
|
||||
ret = cs35l41_hda_read_acpi(cs35l41, device_name, id);
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <linux/firmware/cirrus/cs_dsp.h>
|
||||
#include <linux/firmware/cirrus/wmfw.h>
|
||||
|
||||
#define CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ 1000000
|
||||
|
||||
struct cs35l41_amp_cal_data {
|
||||
u32 calTarget[2];
|
||||
u32 calTime[2];
|
||||
@ -46,6 +48,11 @@ enum cs35l41_hda_gpio_function {
|
||||
CS35l41_SYNC,
|
||||
};
|
||||
|
||||
enum control_bus {
|
||||
I2C,
|
||||
SPI
|
||||
};
|
||||
|
||||
struct cs35l41_hda {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
@ -74,6 +81,9 @@ struct cs35l41_hda {
|
||||
struct cs_dsp cs_dsp;
|
||||
struct acpi_device *dacpi;
|
||||
bool mute_override;
|
||||
enum control_bus control_bus;
|
||||
bool bypass_fw;
|
||||
|
||||
};
|
||||
|
||||
enum halo_state {
|
||||
@ -85,7 +95,7 @@ enum halo_state {
|
||||
extern const struct dev_pm_ops cs35l41_hda_pm_ops;
|
||||
|
||||
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
|
||||
struct regmap *regmap);
|
||||
struct regmap *regmap, enum control_bus control_bus);
|
||||
void cs35l41_hda_remove(struct device *dev);
|
||||
int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id);
|
||||
|
||||
|
@ -30,7 +30,7 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt)
|
||||
return -ENODEV;
|
||||
|
||||
return cs35l41_hda_probe(&clt->dev, device_name, clt->addr, clt->irq,
|
||||
devm_regmap_init_i2c(clt, &cs35l41_regmap_i2c));
|
||||
devm_regmap_init_i2c(clt, &cs35l41_regmap_i2c), I2C);
|
||||
}
|
||||
|
||||
static void cs35l41_hda_i2c_remove(struct i2c_client *clt)
|
||||
|
@ -16,10 +16,6 @@
|
||||
|
||||
struct cs35l41_config {
|
||||
const char *ssid;
|
||||
enum {
|
||||
SPI,
|
||||
I2C
|
||||
} bus;
|
||||
int num_amps;
|
||||
enum {
|
||||
INTERNAL,
|
||||
@ -35,42 +31,72 @@ struct cs35l41_config {
|
||||
};
|
||||
|
||||
static const struct cs35l41_config cs35l41_config_table[] = {
|
||||
{ "10280B27", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10280B28", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10280BEB", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
|
||||
{ "10280C4D", 4, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT }, 0, 1, -1, 1000, 4500, 24 },
|
||||
/*
|
||||
* Device 103C89C6 does have _DSD, however it is setup to use the wrong boost type.
|
||||
* We can override the _DSD to correct the boost type here.
|
||||
* Since this laptop has valid ACPI, we do not need to handle cs-gpios, since that already exists
|
||||
* in the ACPI. The Reset GPIO is also valid, so we can use the Reset defined in _DSD.
|
||||
*/
|
||||
{ "103C89C6", SPI, 2, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, -1, -1, -1, 1000, 4500, 24 },
|
||||
{ "104312AF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431433", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431463", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431473", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "10431483", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "10431493", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104314D3", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104314E3", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431503", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431533", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431573", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431663", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "104316D3", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "104316F3", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "104317F3", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431863", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104318D3", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "10431C9F", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CAF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CCF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CDF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CEF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431D1F", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431DA2", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431E02", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431EE2", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
|
||||
{ "10431F12", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431F1F", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
|
||||
{ "10431F62", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "103C89C6", 2, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, -1, -1, -1, 1000, 4500, 24 },
|
||||
{ "103C8A28", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A29", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A2A", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A2B", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A2C", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A2D", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A2E", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A30", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8A31", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BB3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BB4", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BDF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BE0", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BE1", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BE2", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BE9", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BDD", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BDE", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BE3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BE5", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8BE6", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "103C8B3A", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
|
||||
{ "104312AF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431433", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431463", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431473", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "10431483", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "10431493", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104314D3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104314E3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431503", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431533", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431573", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431663", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
|
||||
{ "104316D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "104316F3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "104317F3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431863", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "104318D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "10431C9F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CAF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CCF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CDF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431CEF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
|
||||
{ "10431D1F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431DA2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431E02", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "10431EE2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
|
||||
{ "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
|
||||
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
|
||||
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
|
||||
{ "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{ "17AA38B7", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -208,7 +234,7 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde
|
||||
"_DSD already exists.\n");
|
||||
}
|
||||
|
||||
if (cfg->bus == SPI) {
|
||||
if (cs35l41->control_bus == SPI) {
|
||||
cs35l41->index = id;
|
||||
|
||||
/*
|
||||
@ -345,7 +371,33 @@ struct cs35l41_prop_model {
|
||||
static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
|
||||
{ "CLSA0100", NULL, lenovo_legion_no_acpi },
|
||||
{ "CLSA0101", NULL, lenovo_legion_no_acpi },
|
||||
{ "CSC3551", "10280B27", generic_dsd_config },
|
||||
{ "CSC3551", "10280B28", generic_dsd_config },
|
||||
{ "CSC3551", "10280BEB", generic_dsd_config },
|
||||
{ "CSC3551", "10280C4D", generic_dsd_config },
|
||||
{ "CSC3551", "103C89C6", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A28", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A29", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A2A", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A2B", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A2C", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A2D", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A2E", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A30", generic_dsd_config },
|
||||
{ "CSC3551", "103C8A31", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BB3", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BB4", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BDF", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BE0", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BE1", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BE2", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BE9", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BDD", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BDE", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BE3", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BE5", generic_dsd_config },
|
||||
{ "CSC3551", "103C8BE6", generic_dsd_config },
|
||||
{ "CSC3551", "103C8B3A", generic_dsd_config },
|
||||
{ "CSC3551", "104312AF", generic_dsd_config },
|
||||
{ "CSC3551", "10431433", generic_dsd_config },
|
||||
{ "CSC3551", "10431463", generic_dsd_config },
|
||||
@ -375,6 +427,10 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
|
||||
{ "CSC3551", "10431F12", generic_dsd_config },
|
||||
{ "CSC3551", "10431F1F", generic_dsd_config },
|
||||
{ "CSC3551", "10431F62", generic_dsd_config },
|
||||
{ "CSC3551", "17AA38B4", generic_dsd_config },
|
||||
{ "CSC3551", "17AA38B5", generic_dsd_config },
|
||||
{ "CSC3551", "17AA38B6", generic_dsd_config },
|
||||
{ "CSC3551", "17AA38B7", generic_dsd_config },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@ static int cs35l41_hda_spi_probe(struct spi_device *spi)
|
||||
return -ENODEV;
|
||||
|
||||
return cs35l41_hda_probe(&spi->dev, device_name, spi_get_chipselect(spi, 0), spi->irq,
|
||||
devm_regmap_init_spi(spi, &cs35l41_regmap_spi));
|
||||
devm_regmap_init_spi(spi, &cs35l41_regmap_spi), SPI);
|
||||
}
|
||||
|
||||
static void cs35l41_hda_spi_remove(struct spi_device *spi)
|
||||
|
@ -3163,6 +3163,7 @@ static int set_pcm_default_values(struct hda_codec *codec,
|
||||
err = snd_hda_query_supported_pcm(codec, info->nid,
|
||||
info->rates ? NULL : &info->rates,
|
||||
info->formats ? NULL : &info->formats,
|
||||
info->subformats ? NULL : &info->subformats,
|
||||
info->maxbps ? NULL : &info->maxbps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@ -3757,6 +3758,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
|
||||
snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
|
||||
&mout->spdif_rates,
|
||||
&mout->spdif_formats,
|
||||
NULL,
|
||||
&mout->spdif_maxbps);
|
||||
}
|
||||
mutex_lock(&codec->spdif_mutex);
|
||||
|
@ -151,7 +151,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
struct azx_dev *azx_dev = get_azx_dev(substream);
|
||||
struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
unsigned int format_val, stream_tag;
|
||||
unsigned int format_val, stream_tag, bits;
|
||||
int err;
|
||||
struct hda_spdif_out *spdif =
|
||||
snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
|
||||
@ -165,11 +165,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
}
|
||||
|
||||
snd_hdac_stream_reset(azx_stream(azx_dev));
|
||||
format_val = snd_hdac_calc_stream_format(runtime->rate,
|
||||
runtime->channels,
|
||||
runtime->format,
|
||||
hinfo->maxbps,
|
||||
ctls);
|
||||
bits = snd_hdac_stream_format_bits(runtime->format, SNDRV_PCM_SUBFORMAT_STD, hinfo->maxbps);
|
||||
|
||||
format_val = snd_hdac_spdif_stream_format(runtime->channels, bits, runtime->rate, ctls);
|
||||
if (!format_val) {
|
||||
dev_err(chip->card->dev,
|
||||
"invalid format_val, rate=%d, ch=%d, format=%d\n",
|
||||
|
@ -2504,6 +2504,8 @@ static const struct pci_device_id azx_ids[] = {
|
||||
{ PCI_DEVICE_DATA(INTEL, HDA_LNL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
|
||||
/* Arrow Lake-S */
|
||||
{ PCI_DEVICE_DATA(INTEL, HDA_ARL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
|
||||
/* Arrow Lake */
|
||||
{ PCI_DEVICE_DATA(INTEL, HDA_ARL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
|
||||
/* Apollolake (Broxton-P) */
|
||||
{ PCI_DEVICE_DATA(INTEL, HDA_APL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
|
||||
/* Gemini-Lake */
|
||||
|
@ -3022,8 +3022,7 @@ static int dma_convert_to_hda_format(struct hda_codec *codec,
|
||||
{
|
||||
unsigned int format_val;
|
||||
|
||||
format_val = snd_hdac_calc_stream_format(sample_rate,
|
||||
channels, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
|
||||
format_val = snd_hdac_stream_format(channels, 32, sample_rate);
|
||||
|
||||
if (hda_format)
|
||||
*hda_format = (unsigned short)format_val;
|
||||
|
@ -21,6 +21,12 @@
|
||||
#include "hda_jack.h"
|
||||
#include "hda_generic.h"
|
||||
|
||||
enum {
|
||||
CX_HEADSET_NOPRESENT = 0,
|
||||
CX_HEADSET_PARTPRESENT,
|
||||
CX_HEADSET_ALLPRESENT,
|
||||
};
|
||||
|
||||
struct conexant_spec {
|
||||
struct hda_gen_spec gen;
|
||||
|
||||
@ -42,7 +48,8 @@ struct conexant_spec {
|
||||
unsigned int gpio_led;
|
||||
unsigned int gpio_mute_led_mask;
|
||||
unsigned int gpio_mic_led_mask;
|
||||
|
||||
unsigned int headset_present_flag;
|
||||
bool is_cx8070_sn6140;
|
||||
};
|
||||
|
||||
|
||||
@ -164,6 +171,27 @@ static void cxt_init_gpio_led(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
static void cx_fixup_headset_recog(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int mic_persent;
|
||||
|
||||
/* fix some headset type recognize fail issue, such as EDIFIER headset */
|
||||
/* set micbiasd output current comparator threshold from 66% to 55%. */
|
||||
snd_hda_codec_write(codec, 0x1c, 0, 0x320, 0x010);
|
||||
/* set OFF voltage for DFET from -1.2V to -0.8V, set headset micbias registor
|
||||
* value adjustment trim from 2.2K ohms to 2.0K ohms.
|
||||
*/
|
||||
snd_hda_codec_write(codec, 0x1c, 0, 0x3b0, 0xe10);
|
||||
/* fix reboot headset type recognize fail issue */
|
||||
mic_persent = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0);
|
||||
if (mic_persent & AC_PINSENSE_PRESENCE)
|
||||
/* enable headset mic VREF */
|
||||
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24);
|
||||
else
|
||||
/* disable headset mic VREF */
|
||||
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20);
|
||||
}
|
||||
|
||||
static int cx_auto_init(struct hda_codec *codec)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
@ -174,6 +202,9 @@ static int cx_auto_init(struct hda_codec *codec)
|
||||
cxt_init_gpio_led(codec);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
|
||||
|
||||
if (spec->is_cx8070_sn6140)
|
||||
cx_fixup_headset_recog(codec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -192,6 +223,77 @@ static void cx_auto_free(struct hda_codec *codec)
|
||||
snd_hda_gen_free(codec);
|
||||
}
|
||||
|
||||
static void cx_process_headset_plugin(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int val;
|
||||
unsigned int count = 0;
|
||||
|
||||
/* Wait headset detect done. */
|
||||
do {
|
||||
val = snd_hda_codec_read(codec, 0x1c, 0, 0xca0, 0x0);
|
||||
if (val & 0x080) {
|
||||
codec_dbg(codec, "headset type detect done!\n");
|
||||
break;
|
||||
}
|
||||
msleep(20);
|
||||
count++;
|
||||
} while (count < 3);
|
||||
val = snd_hda_codec_read(codec, 0x1c, 0, 0xcb0, 0x0);
|
||||
if (val & 0x800) {
|
||||
codec_dbg(codec, "headset plugin, type is CTIA\n");
|
||||
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24);
|
||||
} else if (val & 0x400) {
|
||||
codec_dbg(codec, "headset plugin, type is OMTP\n");
|
||||
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24);
|
||||
} else {
|
||||
codec_dbg(codec, "headphone plugin\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void cx_update_headset_mic_vref(struct hda_codec *codec, unsigned int res)
|
||||
{
|
||||
unsigned int phone_present, mic_persent, phone_tag, mic_tag;
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
|
||||
/* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled,
|
||||
* the node 19 can only be config to microphone or disabled.
|
||||
* Check hp&mic tag to process headset pulgin&plugout.
|
||||
*/
|
||||
phone_tag = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0);
|
||||
mic_tag = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0);
|
||||
if ((phone_tag & (res >> AC_UNSOL_RES_TAG_SHIFT)) ||
|
||||
(mic_tag & (res >> AC_UNSOL_RES_TAG_SHIFT))) {
|
||||
phone_present = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_PIN_SENSE, 0x0);
|
||||
if (!(phone_present & AC_PINSENSE_PRESENCE)) {/* headphone plugout */
|
||||
spec->headset_present_flag = CX_HEADSET_NOPRESENT;
|
||||
snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20);
|
||||
return;
|
||||
}
|
||||
if (spec->headset_present_flag == CX_HEADSET_NOPRESENT) {
|
||||
spec->headset_present_flag = CX_HEADSET_PARTPRESENT;
|
||||
} else if (spec->headset_present_flag == CX_HEADSET_PARTPRESENT) {
|
||||
mic_persent = snd_hda_codec_read(codec, 0x19, 0,
|
||||
AC_VERB_GET_PIN_SENSE, 0x0);
|
||||
/* headset is present */
|
||||
if ((phone_present & AC_PINSENSE_PRESENCE) &&
|
||||
(mic_persent & AC_PINSENSE_PRESENCE)) {
|
||||
cx_process_headset_plugin(codec);
|
||||
spec->headset_present_flag = CX_HEADSET_ALLPRESENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
|
||||
if (spec->is_cx8070_sn6140)
|
||||
cx_update_headset_mic_vref(codec, res);
|
||||
|
||||
snd_hda_jack_unsol_event(codec, res);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int cx_auto_suspend(struct hda_codec *codec)
|
||||
{
|
||||
@ -205,7 +307,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = cx_auto_init,
|
||||
.free = cx_auto_free,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.unsol_event = cx_jack_unsol_event,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = cx_auto_suspend,
|
||||
.check_power_status = snd_hda_gen_check_power_status,
|
||||
@ -1042,6 +1144,15 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
||||
codec->spec = spec;
|
||||
codec->patch_ops = cx_auto_patch_ops;
|
||||
|
||||
/* init cx8070/sn6140 flag and reset headset_present_flag */
|
||||
switch (codec->core.vendor_id) {
|
||||
case 0x14f11f86:
|
||||
case 0x14f11f87:
|
||||
spec->is_cx8070_sn6140 = true;
|
||||
spec->headset_present_flag = CX_HEADSET_NOPRESENT;
|
||||
break;
|
||||
}
|
||||
|
||||
cx_auto_parse_eapd(codec);
|
||||
spec->gen.own_eapd_ctl = 1;
|
||||
|
||||
|
@ -1655,7 +1655,6 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
|
||||
|
||||
#define I915_SILENT_RATE 48000
|
||||
#define I915_SILENT_CHANNELS 2
|
||||
#define I915_SILENT_FORMAT SNDRV_PCM_FORMAT_S16_LE
|
||||
#define I915_SILENT_FORMAT_BITS 16
|
||||
#define I915_SILENT_FMT_MASK 0xf
|
||||
|
||||
@ -1668,8 +1667,8 @@ static void silent_stream_enable_i915(struct hda_codec *codec,
|
||||
per_pin->dev_id, I915_SILENT_RATE);
|
||||
|
||||
/* trigger silent stream generation in hw */
|
||||
format = snd_hdac_calc_stream_format(I915_SILENT_RATE, I915_SILENT_CHANNELS,
|
||||
I915_SILENT_FORMAT, I915_SILENT_FORMAT_BITS, 0);
|
||||
format = snd_hdac_stream_format(I915_SILENT_CHANNELS, I915_SILENT_FORMAT_BITS,
|
||||
I915_SILENT_RATE);
|
||||
snd_hda_codec_setup_stream(codec, per_pin->cvt_nid,
|
||||
I915_SILENT_FMT_MASK, I915_SILENT_FMT_MASK, format);
|
||||
usleep_range(100, 200);
|
||||
@ -1977,6 +1976,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
|
||||
err = snd_hda_query_supported_pcm(codec, cvt_nid,
|
||||
&per_cvt->rates,
|
||||
&per_cvt->formats,
|
||||
NULL,
|
||||
&per_cvt->maxbps);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -6956,6 +6956,11 @@ static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup
|
||||
cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2);
|
||||
}
|
||||
|
||||
static void cs35l41_fixup_i2c_four(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
|
||||
{
|
||||
cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 4);
|
||||
}
|
||||
|
||||
static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
|
||||
{
|
||||
cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 2);
|
||||
@ -6984,6 +6989,12 @@ static void tas2781_fixup_i2c(struct hda_codec *cdc,
|
||||
tas2781_generic_fixup(cdc, action, "i2c", "TIAS2781");
|
||||
}
|
||||
|
||||
static void yoga7_14arb7_fixup_i2c(struct hda_codec *cdc,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
tas2781_generic_fixup(cdc, action, "i2c", "INT8866");
|
||||
}
|
||||
|
||||
/* for alc295_fixup_hp_top_speakers */
|
||||
#include "hp_x360_helper.c"
|
||||
|
||||
@ -7441,6 +7452,7 @@ enum {
|
||||
ALC287_FIXUP_LEGION_16ACHG6,
|
||||
ALC287_FIXUP_CS35L41_I2C_2,
|
||||
ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
|
||||
ALC287_FIXUP_CS35L41_I2C_4,
|
||||
ALC245_FIXUP_CS35L41_SPI_2,
|
||||
ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
|
||||
ALC245_FIXUP_CS35L41_SPI_4,
|
||||
@ -7454,6 +7466,7 @@ enum {
|
||||
ALC236_FIXUP_DELL_DUAL_CODECS,
|
||||
ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
|
||||
ALC287_FIXUP_TAS2781_I2C,
|
||||
ALC287_FIXUP_YOGA7_14ARB7_I2C,
|
||||
ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
|
||||
ALC245_FIXUP_HP_X360_MUTE_LEDS,
|
||||
ALC287_FIXUP_THINKPAD_I2S_SPK,
|
||||
@ -9427,6 +9440,10 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC285_FIXUP_HP_MUTE_LED,
|
||||
},
|
||||
[ALC287_FIXUP_CS35L41_I2C_4] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cs35l41_fixup_i2c_four,
|
||||
},
|
||||
[ALC245_FIXUP_CS35L41_SPI_2] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cs35l41_fixup_spi_two,
|
||||
@ -9568,6 +9585,12 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
|
||||
},
|
||||
[ALC287_FIXUP_YOGA7_14ARB7_I2C] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = yoga7_14arb7_fixup_i2c,
|
||||
.chained = true,
|
||||
.chain_id = ALC285_FIXUP_THINKPAD_HEADSET_JACK,
|
||||
},
|
||||
[ALC245_FIXUP_HP_MUTE_LED_COEFBIT] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc245_fixup_hp_mute_led_coefbit,
|
||||
@ -9703,6 +9726,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0b27, "Dell", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1028, 0x0b28, "Dell", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2),
|
||||
@ -9713,6 +9738,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0c4d, "Dell", ALC287_FIXUP_CS35L41_I2C_4),
|
||||
SND_PCI_QUIRK(0x1028, 0x0cbd, "Dell Oasis 13 CS MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1028, 0x0cbe, "Dell Oasis 13 2-IN-1 MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1028, 0x0cbf, "Dell Oasis 13 Low Weight MTU-L", ALC289_FIXUP_DELL_CS35L41_SPI_2),
|
||||
@ -9816,6 +9842,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8735, "HP ProBook 435 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x876e, "HP ENVY x360 Convertible 13-ay0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS),
|
||||
SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8780, "HP ZBook Fury 17 G7 Mobile Workstation",
|
||||
@ -10221,6 +10248,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C),
|
||||
@ -10229,6 +10257,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38b4, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38b5, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38b6, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38b7, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),
|
||||
|
@ -65,6 +65,24 @@ enum calib_data {
|
||||
CALIB_MAX
|
||||
};
|
||||
|
||||
#define TAS2563_MAX_CHANNELS 4
|
||||
|
||||
#define TAS2563_CAL_POWER TASDEVICE_REG(0, 0x0d, 0x3c)
|
||||
#define TAS2563_CAL_R0 TASDEVICE_REG(0, 0x0f, 0x34)
|
||||
#define TAS2563_CAL_INVR0 TASDEVICE_REG(0, 0x0f, 0x40)
|
||||
#define TAS2563_CAL_R0_LOW TASDEVICE_REG(0, 0x0f, 0x48)
|
||||
#define TAS2563_CAL_TLIM TASDEVICE_REG(0, 0x10, 0x14)
|
||||
#define TAS2563_CAL_N 5
|
||||
#define TAS2563_CAL_DATA_SIZE 4
|
||||
#define TAS2563_CAL_CH_SIZE 20
|
||||
#define TAS2563_CAL_ARRAY_SIZE 80
|
||||
|
||||
static unsigned int cal_regs[TAS2563_CAL_N] = {
|
||||
TAS2563_CAL_POWER, TAS2563_CAL_R0, TAS2563_CAL_INVR0,
|
||||
TAS2563_CAL_R0_LOW, TAS2563_CAL_TLIM,
|
||||
};
|
||||
|
||||
|
||||
struct tas2781_hda {
|
||||
struct device *dev;
|
||||
struct tasdevice_priv *priv;
|
||||
@ -81,7 +99,7 @@ static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
|
||||
|
||||
if (i2c_acpi_get_i2c_resource(ares, &sb)) {
|
||||
if (tas_priv->ndev < TASDEVICE_MAX_CHANNELS &&
|
||||
sb->slave_address != TAS2781_GLOBAL_ADDR) {
|
||||
sb->slave_address != tas_priv->global_addr) {
|
||||
tas_priv->tasdevice[tas_priv->ndev].dev_addr =
|
||||
(unsigned int)sb->slave_address;
|
||||
tas_priv->ndev++;
|
||||
@ -404,6 +422,69 @@ static const struct snd_kcontrol_new tas2781_dsp_conf_ctrl = {
|
||||
.put = tasdevice_config_put,
|
||||
};
|
||||
|
||||
static void tas2563_apply_calib(struct tasdevice_priv *tas_priv)
|
||||
{
|
||||
int offset = 0;
|
||||
__be32 data;
|
||||
int ret;
|
||||
|
||||
for (int i = 0; i < tas_priv->ndev; i++) {
|
||||
for (int j = 0; j < TAS2563_CAL_N; ++j) {
|
||||
data = cpu_to_be32(
|
||||
*(uint32_t *)&tas_priv->cali_data.data[offset]);
|
||||
ret = tasdevice_dev_bulk_write(tas_priv, i, cal_regs[j],
|
||||
(unsigned char *)&data, TAS2563_CAL_DATA_SIZE);
|
||||
if (ret)
|
||||
dev_err(tas_priv->dev,
|
||||
"Error writing calib regs\n");
|
||||
offset += TAS2563_CAL_DATA_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int tas2563_save_calibration(struct tasdevice_priv *tas_priv)
|
||||
{
|
||||
static efi_guid_t efi_guid = EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc,
|
||||
0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92);
|
||||
|
||||
static efi_char16_t *efi_vars[TAS2563_MAX_CHANNELS][TAS2563_CAL_N] = {
|
||||
{ L"Power_1", L"R0_1", L"InvR0_1", L"R0_Low_1", L"TLim_1" },
|
||||
{ L"Power_2", L"R0_2", L"InvR0_2", L"R0_Low_2", L"TLim_2" },
|
||||
{ L"Power_3", L"R0_3", L"InvR0_3", L"R0_Low_3", L"TLim_3" },
|
||||
{ L"Power_4", L"R0_4", L"InvR0_4", L"R0_Low_4", L"TLim_4" },
|
||||
};
|
||||
|
||||
unsigned long max_size = TAS2563_CAL_DATA_SIZE;
|
||||
unsigned int offset = 0;
|
||||
efi_status_t status;
|
||||
unsigned int attr;
|
||||
|
||||
tas_priv->cali_data.data = devm_kzalloc(tas_priv->dev,
|
||||
TAS2563_CAL_ARRAY_SIZE, GFP_KERNEL);
|
||||
if (!tas_priv->cali_data.data)
|
||||
return -ENOMEM;
|
||||
|
||||
for (int i = 0; i < tas_priv->ndev; ++i) {
|
||||
for (int j = 0; j < TAS2563_CAL_N; ++j) {
|
||||
status = efi.get_variable(efi_vars[i][j],
|
||||
&efi_guid, &attr, &max_size,
|
||||
&tas_priv->cali_data.data[offset]);
|
||||
if (status != EFI_SUCCESS ||
|
||||
max_size != TAS2563_CAL_DATA_SIZE) {
|
||||
dev_warn(tas_priv->dev,
|
||||
"Calibration data read failed %ld\n", status);
|
||||
return -EINVAL;
|
||||
}
|
||||
offset += TAS2563_CAL_DATA_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
tas_priv->cali_data.total_sz = offset;
|
||||
tasdevice_apply_calibration(tas_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tas2781_apply_calib(struct tasdevice_priv *tas_priv)
|
||||
{
|
||||
static const unsigned char page_array[CALIB_MAX] = {
|
||||
@ -479,7 +560,7 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv)
|
||||
dev_dbg(tas_priv->dev, "%4ld-%2d-%2d, %2d:%2d:%2d\n",
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
tas2781_apply_calib(tas_priv);
|
||||
tasdevice_apply_calibration(tas_priv);
|
||||
} else
|
||||
tas_priv->cali_data.total_sz = 0;
|
||||
|
||||
@ -582,7 +663,9 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
|
||||
/* If calibrated data occurs error, dsp will still works with default
|
||||
* calibrated data inside algo.
|
||||
*/
|
||||
tas2781_save_calibration(tas_priv);
|
||||
tasdevice_save_calibration(tas_priv);
|
||||
|
||||
tasdevice_tuning_switch(tas_hda->priv, 0);
|
||||
|
||||
out:
|
||||
mutex_unlock(&tas_hda->priv->codec_lock);
|
||||
@ -683,10 +766,6 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
|
||||
const char *device_name;
|
||||
int ret;
|
||||
|
||||
if (strstr(dev_name(&clt->dev), "TIAS2781"))
|
||||
device_name = "TIAS2781";
|
||||
else
|
||||
return -ENODEV;
|
||||
|
||||
tas_hda = devm_kzalloc(&clt->dev, sizeof(*tas_hda), GFP_KERNEL);
|
||||
if (!tas_hda)
|
||||
@ -699,6 +778,19 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
|
||||
if (!tas_hda->priv)
|
||||
return -ENOMEM;
|
||||
|
||||
if (strstr(dev_name(&clt->dev), "TIAS2781")) {
|
||||
device_name = "TIAS2781";
|
||||
tas_hda->priv->save_calibration = tas2781_save_calibration;
|
||||
tas_hda->priv->apply_calibration = tas2781_apply_calib;
|
||||
tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;
|
||||
} else if (strstr(dev_name(&clt->dev), "INT8866")) {
|
||||
device_name = "INT8866";
|
||||
tas_hda->priv->save_calibration = tas2563_save_calibration;
|
||||
tas_hda->priv->apply_calibration = tas2563_apply_calib;
|
||||
tas_hda->priv->global_addr = TAS2563_GLOBAL_ADDR;
|
||||
} else
|
||||
return -ENODEV;
|
||||
|
||||
tas_hda->priv->irq_info.irq = clt->irq;
|
||||
ret = tas2781_read_acpi(tas_hda->priv, device_name);
|
||||
if (ret)
|
||||
@ -765,8 +857,6 @@ static int tas2781_runtime_suspend(struct device *dev)
|
||||
static int tas2781_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
|
||||
unsigned long calib_data_sz =
|
||||
tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
|
||||
|
||||
dev_dbg(tas_hda->dev, "Runtime Resume\n");
|
||||
|
||||
@ -777,8 +867,7 @@ static int tas2781_runtime_resume(struct device *dev)
|
||||
/* If calibrated data occurs error, dsp will still works with default
|
||||
* calibrated data inside algo.
|
||||
*/
|
||||
if (tas_hda->priv->cali_data.total_sz > calib_data_sz)
|
||||
tas2781_apply_calib(tas_hda->priv);
|
||||
tasdevice_apply_calibration(tas_hda->priv);
|
||||
|
||||
mutex_unlock(&tas_hda->priv->codec_lock);
|
||||
|
||||
@ -809,8 +898,6 @@ static int tas2781_system_suspend(struct device *dev)
|
||||
static int tas2781_system_resume(struct device *dev)
|
||||
{
|
||||
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
|
||||
unsigned long calib_data_sz =
|
||||
tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
|
||||
int i, ret;
|
||||
|
||||
dev_info(tas_hda->priv->dev, "System Resume\n");
|
||||
@ -832,8 +919,7 @@ static int tas2781_system_resume(struct device *dev)
|
||||
/* If calibrated data occurs error, dsp will still work with default
|
||||
* calibrated data inside algo.
|
||||
*/
|
||||
if (tas_hda->priv->cali_data.total_sz > calib_data_sz)
|
||||
tas2781_apply_calib(tas_hda->priv);
|
||||
tasdevice_apply_calibration(tas_hda->priv);
|
||||
mutex_unlock(&tas_hda->priv->codec_lock);
|
||||
|
||||
return 0;
|
||||
@ -851,6 +937,7 @@ static const struct i2c_device_id tas2781_hda_i2c_id[] = {
|
||||
|
||||
static const struct acpi_device_id tas2781_acpi_hda_match[] = {
|
||||
{"TIAS2781", 0 },
|
||||
{"INT8866", 0 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, tas2781_acpi_hda_match);
|
||||
|
@ -3,7 +3,7 @@
|
||||
// This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
// redistributing this file, you may do so under either license.
|
||||
//
|
||||
// Copyright(c) 2021 Advanced Micro Devices, Inc.
|
||||
// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
|
||||
//
|
||||
@ -19,6 +19,8 @@
|
||||
#include "../sof/amd/acp.h"
|
||||
#include "mach-config.h"
|
||||
|
||||
#define ACP_7_0_REV 0x70
|
||||
|
||||
static int acp_quirk_data;
|
||||
|
||||
static const struct config_entry config_table[] = {
|
||||
@ -47,6 +49,19 @@ static const struct config_entry config_table[] = {
|
||||
{}
|
||||
},
|
||||
},
|
||||
{
|
||||
.flags = FLAG_AMD_LEGACY,
|
||||
.device = ACP_PCI_DEV_ID,
|
||||
.dmi_table = (const struct dmi_system_id []) {
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
},
|
||||
},
|
||||
{
|
||||
.flags = FLAG_AMD_SOF,
|
||||
.device = ACP_PCI_DEV_ID,
|
||||
@ -55,7 +70,6 @@ static const struct config_entry config_table[] = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "Sephiroth"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
@ -147,15 +161,33 @@ static const struct config_entry config_table[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int snd_amd_acp_acpi_find_config(struct pci_dev *pci)
|
||||
{
|
||||
const union acpi_object *obj;
|
||||
int acp_flag = FLAG_AMD_LEGACY_ONLY_DMIC;
|
||||
|
||||
if (!acpi_dev_get_property(ACPI_COMPANION(&pci->dev), "acp-audio-config-flag",
|
||||
ACPI_TYPE_INTEGER, &obj))
|
||||
acp_flag = obj->integer.value;
|
||||
|
||||
return acp_flag;
|
||||
}
|
||||
|
||||
int snd_amd_acp_find_config(struct pci_dev *pci)
|
||||
{
|
||||
const struct config_entry *table = config_table;
|
||||
u16 device = pci->device;
|
||||
int i;
|
||||
|
||||
/* Do not enable FLAGS on older platforms with Rev id zero */
|
||||
/* Do not enable FLAGS on older platforms with Rev Id zero
|
||||
* For platforms which has ACP 7.0 or higher, read the acp
|
||||
* config flag from BIOS ACPI table and for older platforms
|
||||
* read it from DMI tables.
|
||||
*/
|
||||
if (!pci->revision)
|
||||
return 0;
|
||||
else if (pci->revision >= ACP_7_0_REV)
|
||||
return snd_amd_acp_acpi_find_config(pci);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(config_table); i++, table++) {
|
||||
if (table->device != device)
|
||||
@ -289,4 +321,5 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_machines[] = {
|
||||
};
|
||||
EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sof_machines);
|
||||
|
||||
MODULE_DESCRIPTION("AMD ACP Machine Configuration Module");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
@ -73,6 +73,19 @@ config SND_AMD_ASOC_ACP63
|
||||
Say Y if you want to enable AUDIO on ACP6.3
|
||||
If unsure select "N".
|
||||
|
||||
config SND_AMD_ASOC_ACP70
|
||||
tristate "AMD ACP ASOC Acp7.0 Support"
|
||||
depends on X86 && PCI
|
||||
depends on ACPI
|
||||
select SND_SOC_AMD_ACP_PCM
|
||||
select SND_SOC_AMD_ACP_I2S
|
||||
select SND_SOC_AMD_ACP_PDM
|
||||
select SND_SOC_AMD_ACP_LEGACY_COMMON
|
||||
help
|
||||
This option enables Acp7.0 PDM support on AMD platform.
|
||||
Say Y if you want to enable AUDIO on ACP7.0
|
||||
If unsure select "N".
|
||||
|
||||
config SND_SOC_AMD_MACH_COMMON
|
||||
tristate
|
||||
depends on X86 && PCI && I2C
|
||||
|
@ -15,6 +15,7 @@ snd-acp-pci-objs := acp-pci.o
|
||||
snd-acp-renoir-objs := acp-renoir.o
|
||||
snd-acp-rembrandt-objs := acp-rembrandt.o
|
||||
snd-acp63-objs := acp63.o
|
||||
snd-acp70-objs := acp70.o
|
||||
|
||||
#machine specific driver
|
||||
snd-acp-mach-objs := acp-mach-common.o
|
||||
@ -30,6 +31,7 @@ obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o
|
||||
obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o
|
||||
obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o
|
||||
obj-$(CONFIG_SND_AMD_ASOC_ACP63) += snd-acp63.o
|
||||
obj-$(CONFIG_SND_AMD_ASOC_ACP70) += snd-acp70.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_AMD_MACH_COMMON) += snd-acp-mach.o
|
||||
obj-$(CONFIG_SND_SOC_AMD_LEGACY_MACH) += snd-acp-legacy-mach.o
|
||||
|
@ -3,7 +3,7 @@
|
||||
// This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
// redistributing this file, you may do so under either license.
|
||||
//
|
||||
// Copyright(c) 2021 Advanced Micro Devices, Inc.
|
||||
// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
|
||||
// Vijendar Mukunda <Vijendar.Mukunda@amd.com>
|
||||
@ -282,6 +282,22 @@ static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
|
||||
6144000, 49152000);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,
|
||||
49152000, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set tdm/i2s1 master bclk ratio */
|
||||
ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
|
||||
if (ret < 0) {
|
||||
@ -464,6 +480,22 @@ static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
|
||||
6144000, 49152000);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,
|
||||
49152000, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set tdm/i2s1 master bclk ratio */
|
||||
ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
|
||||
if (ret < 0) {
|
||||
@ -1290,6 +1322,8 @@ SND_SOC_DAILINK_DEF(sof_hs,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));
|
||||
SND_SOC_DAILINK_DEF(sof_hs_virtual,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual")));
|
||||
SND_SOC_DAILINK_DEF(sof_bt,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-bt")));
|
||||
SND_SOC_DAILINK_DEF(sof_dmic,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
|
||||
SND_SOC_DAILINK_DEF(pdm_dmic,
|
||||
@ -1348,6 +1382,8 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
|
||||
|
||||
if (drv_data->hs_cpu_id)
|
||||
num_links++;
|
||||
if (drv_data->bt_cpu_id)
|
||||
num_links++;
|
||||
if (drv_data->amp_cpu_id)
|
||||
num_links++;
|
||||
if (drv_data->dmic_cpu_id)
|
||||
@ -1479,6 +1515,7 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
|
||||
links[i].init = acp_card_maxim_init;
|
||||
}
|
||||
if (drv_data->amp_codec_id == MAX98388) {
|
||||
links[i].dpcm_capture = 1;
|
||||
links[i].codecs = max98388;
|
||||
links[i].num_codecs = ARRAY_SIZE(max98388);
|
||||
links[i].ops = &acp_max98388_ops;
|
||||
@ -1497,6 +1534,25 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
|
||||
i++;
|
||||
}
|
||||
|
||||
if (drv_data->bt_cpu_id == I2S_BT) {
|
||||
links[i].name = "acp-bt-codec";
|
||||
links[i].id = BT_BE_ID;
|
||||
links[i].cpus = sof_bt;
|
||||
links[i].num_cpus = ARRAY_SIZE(sof_bt);
|
||||
links[i].platforms = sof_component;
|
||||
links[i].num_platforms = ARRAY_SIZE(sof_component);
|
||||
links[i].dpcm_playback = 1;
|
||||
links[i].dpcm_capture = 1;
|
||||
links[i].nonatomic = true;
|
||||
links[i].no_pcm = 1;
|
||||
if (!drv_data->bt_codec_id) {
|
||||
/* Use dummy codec if codec id not specified */
|
||||
links[i].codecs = &snd_soc_dummy_dlc;
|
||||
links[i].num_codecs = 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (drv_data->dmic_cpu_id == DMIC) {
|
||||
links[i].name = "acp-dmic-codec";
|
||||
links[i].id = DMIC_BE_ID;
|
||||
@ -1717,4 +1773,5 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, SND_SOC_AMD_MACH);
|
||||
|
||||
MODULE_DESCRIPTION("AMD ACP Common Machine driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -28,6 +28,7 @@ enum be_id {
|
||||
HEADSET_BE_ID = 0,
|
||||
AMP_BE_ID,
|
||||
DMIC_BE_ID,
|
||||
BT_BE_ID,
|
||||
};
|
||||
|
||||
enum cpu_endpoints {
|
||||
@ -68,9 +69,11 @@ struct acp_mach_ops {
|
||||
struct acp_card_drvdata {
|
||||
unsigned int hs_cpu_id;
|
||||
unsigned int amp_cpu_id;
|
||||
unsigned int bt_cpu_id;
|
||||
unsigned int dmic_cpu_id;
|
||||
unsigned int hs_codec_id;
|
||||
unsigned int amp_codec_id;
|
||||
unsigned int bt_codec_id;
|
||||
unsigned int dmic_codec_id;
|
||||
unsigned int dai_fmt;
|
||||
unsigned int platform;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dai.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "amd.h"
|
||||
#include "acp-mach.h"
|
||||
@ -196,6 +197,11 @@ static int renoir_audio_probe(struct platform_device *pdev)
|
||||
acp_enable_interrupts(adata);
|
||||
acp_platform_register(dev);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -208,11 +214,42 @@ static void renoir_audio_remove(struct platform_device *pdev)
|
||||
acp_platform_unregister(dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused rn_pcm_resume(struct device *dev)
|
||||
{
|
||||
struct acp_dev_data *adata = dev_get_drvdata(dev);
|
||||
struct acp_stream *stream;
|
||||
struct snd_pcm_substream *substream;
|
||||
snd_pcm_uframes_t buf_in_frames;
|
||||
u64 buf_size;
|
||||
|
||||
spin_lock(&adata->acp_lock);
|
||||
list_for_each_entry(stream, &adata->stream_list, list) {
|
||||
substream = stream->substream;
|
||||
if (substream && substream->runtime) {
|
||||
buf_in_frames = (substream->runtime->buffer_size);
|
||||
buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
|
||||
config_pte_for_stream(adata, stream);
|
||||
config_acp_dma(adata, stream, buf_size);
|
||||
if (stream->dai_id)
|
||||
restore_acp_i2s_params(substream, adata, stream);
|
||||
else
|
||||
restore_acp_pdm_params(substream, adata);
|
||||
}
|
||||
}
|
||||
spin_unlock(&adata->acp_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rn_dma_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(NULL, rn_pcm_resume)
|
||||
};
|
||||
|
||||
static struct platform_driver renoir_driver = {
|
||||
.probe = renoir_audio_probe,
|
||||
.remove_new = renoir_audio_remove,
|
||||
.driver = {
|
||||
.name = "acp_asoc_renoir",
|
||||
.pm = &rn_dma_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
// redistributing this file, you may do so under either license.
|
||||
//
|
||||
// Copyright(c) 2021 Advanced Micro Devices, Inc.
|
||||
// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
|
||||
//
|
||||
@ -86,9 +86,11 @@ static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = {
|
||||
static struct acp_card_drvdata sof_nau8821_max98388_data = {
|
||||
.hs_cpu_id = I2S_SP,
|
||||
.amp_cpu_id = I2S_HS,
|
||||
.bt_cpu_id = I2S_BT,
|
||||
.dmic_cpu_id = NONE,
|
||||
.hs_codec_id = NAU8821,
|
||||
.amp_codec_id = MAX98388,
|
||||
.bt_codec_id = NONE,
|
||||
.dmic_codec_id = NONE,
|
||||
.soc_mclk = true,
|
||||
.tdm_mode = false,
|
||||
|
@ -222,7 +222,6 @@ static int acp3x_es83xx_resume_post(struct snd_soc_card *card)
|
||||
|
||||
static int acp3x_es83xx_configure_gpios(struct acp3x_es83xx_private *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
priv->enable_spk_gpio.crs_entry_index = 0;
|
||||
priv->enable_hp_gpio.crs_entry_index = 1;
|
||||
@ -245,7 +244,7 @@ static int acp3x_es83xx_configure_gpios(struct acp3x_es83xx_private *priv)
|
||||
priv->enable_spk_gpio.active_low ? "low" : "high",
|
||||
priv->enable_hp_gpio.crs_entry_index,
|
||||
priv->enable_hp_gpio.active_low ? "low" : "high");
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acp3x_es83xx_configure_mics(struct acp3x_es83xx_private *priv)
|
||||
|
@ -283,18 +283,16 @@ static int __maybe_unused acp63_pcm_resume(struct device *dev)
|
||||
|
||||
spin_lock(&adata->acp_lock);
|
||||
list_for_each_entry(stream, &adata->stream_list, list) {
|
||||
if (stream) {
|
||||
substream = stream->substream;
|
||||
if (substream && substream->runtime) {
|
||||
buf_in_frames = (substream->runtime->buffer_size);
|
||||
buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
|
||||
config_pte_for_stream(adata, stream);
|
||||
config_acp_dma(adata, stream, buf_size);
|
||||
if (stream->dai_id)
|
||||
restore_acp_i2s_params(substream, adata, stream);
|
||||
else
|
||||
restore_acp_pdm_params(substream, adata);
|
||||
}
|
||||
substream = stream->substream;
|
||||
if (substream && substream->runtime) {
|
||||
buf_in_frames = (substream->runtime->buffer_size);
|
||||
buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
|
||||
config_pte_for_stream(adata, stream);
|
||||
config_acp_dma(adata, stream, buf_size);
|
||||
if (stream->dai_id)
|
||||
restore_acp_i2s_params(substream, adata, stream);
|
||||
else
|
||||
restore_acp_pdm_params(substream, adata);
|
||||
}
|
||||
}
|
||||
spin_unlock(&adata->acp_lock);
|
||||
|
@ -52,8 +52,8 @@ static struct snd_soc_dai_driver acp70_dai[] = {
|
||||
.playback = {
|
||||
.stream_name = "I2S SP Playback",
|
||||
.rates = SNDRV_PCM_RATE_8000_96000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rate_min = 8000,
|
||||
@ -62,8 +62,8 @@ static struct snd_soc_dai_driver acp70_dai[] = {
|
||||
.capture = {
|
||||
.stream_name = "I2S SP Capture",
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rate_min = 8000,
|
||||
@ -77,8 +77,8 @@ static struct snd_soc_dai_driver acp70_dai[] = {
|
||||
.playback = {
|
||||
.stream_name = "I2S BT Playback",
|
||||
.rates = SNDRV_PCM_RATE_8000_96000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rate_min = 8000,
|
||||
@ -87,8 +87,8 @@ static struct snd_soc_dai_driver acp70_dai[] = {
|
||||
.capture = {
|
||||
.stream_name = "I2S BT Capture",
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rate_min = 8000,
|
||||
@ -102,8 +102,8 @@ static struct snd_soc_dai_driver acp70_dai[] = {
|
||||
.playback = {
|
||||
.stream_name = "I2S HS Playback",
|
||||
.rates = SNDRV_PCM_RATE_8000_96000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rate_min = 8000,
|
||||
@ -112,8 +112,8 @@ static struct snd_soc_dai_driver acp70_dai[] = {
|
||||
.capture = {
|
||||
.stream_name = "I2S HS Capture",
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rate_min = 8000,
|
||||
@ -229,8 +229,8 @@ static int __maybe_unused acp70_pcm_resume(struct device *dev)
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&adata->acp_lock);
|
||||
return 0;
|
||||
spin_unlock(&adata->acp_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops acp70_dma_pm_ops = {
|
||||
|
@ -439,7 +439,15 @@ static const struct dmi_system_id acp5x_vg_quirk_table[] = {
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Valve"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
|
||||
}
|
||||
},
|
||||
.driver_data = (void *)&acp5x_8821_35l41_card,
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Valve"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"),
|
||||
},
|
||||
.driver_data = (void *)&acp5x_8821_98388_card,
|
||||
},
|
||||
{}
|
||||
};
|
||||
@ -452,25 +460,15 @@ static int acp5x_probe(struct platform_device *pdev)
|
||||
struct snd_soc_card *card;
|
||||
int ret;
|
||||
|
||||
card = (struct snd_soc_card *)device_get_match_data(dev);
|
||||
if (!card) {
|
||||
/*
|
||||
* This is normally the result of directly probing the driver
|
||||
* in pci-acp5x through platform_device_register_full(), which
|
||||
* is necessary for the CS35L41 variant, as it doesn't support
|
||||
* ACPI probing and relies on DMI quirks.
|
||||
*/
|
||||
dmi_id = dmi_first_match(acp5x_vg_quirk_table);
|
||||
if (!dmi_id)
|
||||
return -ENODEV;
|
||||
|
||||
card = &acp5x_8821_35l41_card;
|
||||
}
|
||||
dmi_id = dmi_first_match(acp5x_vg_quirk_table);
|
||||
if (!dmi_id || !dmi_id->driver_data)
|
||||
return -ENODEV;
|
||||
|
||||
machine = devm_kzalloc(dev, sizeof(*machine), GFP_KERNEL);
|
||||
if (!machine)
|
||||
return -ENOMEM;
|
||||
|
||||
card = dmi_id->driver_data;
|
||||
card->dev = dev;
|
||||
platform_set_drvdata(pdev, card);
|
||||
snd_soc_card_set_drvdata(card, machine);
|
||||
@ -482,17 +480,10 @@ static int acp5x_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id acp5x_acpi_match[] = {
|
||||
{ "AMDI8821", (kernel_ulong_t)&acp5x_8821_98388_card },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, acp5x_acpi_match);
|
||||
|
||||
static struct platform_driver acp5x_mach_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.pm = &snd_soc_pm_ops,
|
||||
.acpi_match_table = acp5x_acpi_match,
|
||||
},
|
||||
.probe = acp5x_probe,
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// AMD Vangogh ACP PCI Driver
|
||||
//
|
||||
// Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Copyright (C) 2021, 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/module.h>
|
||||
@ -13,6 +13,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "acp5x.h"
|
||||
#include "../mach-config.h"
|
||||
|
||||
struct acp5x_dev_data {
|
||||
void __iomem *acp5x_base;
|
||||
@ -129,9 +130,13 @@ static int snd_acp5x_probe(struct pci_dev *pci,
|
||||
int ret, i;
|
||||
u32 addr, val;
|
||||
|
||||
/* Return if acp config flag is defined */
|
||||
/*
|
||||
* Return if ACP config flag is defined, except when board
|
||||
* supports SOF while it is not being enabled in kernel config.
|
||||
*/
|
||||
flag = snd_amd_acp_find_config(pci);
|
||||
if (flag)
|
||||
if (flag != FLAG_AMD_LEGACY &&
|
||||
(flag != FLAG_AMD_SOF || IS_ENABLED(CONFIG_SND_SOC_SOF_AMD_VANGOGH)))
|
||||
return -ENODEV;
|
||||
|
||||
irqflags = IRQF_SHARED;
|
||||
@ -259,7 +264,7 @@ disable_pci:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused snd_acp5x_suspend(struct device *dev)
|
||||
static int snd_acp5x_suspend(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct acp5x_dev_data *adata;
|
||||
@ -274,7 +279,7 @@ static int __maybe_unused snd_acp5x_suspend(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused snd_acp5x_resume(struct device *dev)
|
||||
static int snd_acp5x_resume(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct acp5x_dev_data *adata;
|
||||
@ -289,9 +294,8 @@ static int __maybe_unused snd_acp5x_resume(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops acp5x_pm = {
|
||||
SET_RUNTIME_PM_OPS(snd_acp5x_suspend,
|
||||
snd_acp5x_resume, NULL)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(snd_acp5x_suspend, snd_acp5x_resume)
|
||||
RUNTIME_PM_OPS(snd_acp5x_suspend, snd_acp5x_resume, NULL)
|
||||
SYSTEM_SLEEP_PM_OPS(snd_acp5x_suspend, snd_acp5x_resume)
|
||||
};
|
||||
|
||||
static void snd_acp5x_remove(struct pci_dev *pci)
|
||||
@ -327,7 +331,7 @@ static struct pci_driver acp5x_driver = {
|
||||
.probe = snd_acp5x_probe,
|
||||
.remove = snd_acp5x_remove,
|
||||
.driver = {
|
||||
.pm = &acp5x_pm,
|
||||
.pm = pm_ptr(&acp5x_pm),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/soc/cirrus/ep93xx.h>
|
||||
#include <sound/core.h>
|
||||
|
@ -1076,6 +1076,10 @@ config SND_SOC_ES7134
|
||||
config SND_SOC_ES7241
|
||||
tristate "Everest Semi ES7241 CODEC"
|
||||
|
||||
config SND_SOC_ES83XX_DSM_COMMON
|
||||
depends on ACPI
|
||||
tristate
|
||||
|
||||
config SND_SOC_ES8316
|
||||
tristate "Everest Semi ES8316 CODEC"
|
||||
depends on I2C
|
||||
|
@ -116,6 +116,7 @@ snd-soc-da9055-objs := da9055.o
|
||||
snd-soc-dmic-objs := dmic.o
|
||||
snd-soc-es7134-objs := es7134.o
|
||||
snd-soc-es7241-objs := es7241.o
|
||||
snd-soc-es83xx-dsm-common-objs := es83xx-dsm-common.o
|
||||
snd-soc-es8316-objs := es8316.o
|
||||
snd-soc-es8326-objs := es8326.o
|
||||
snd-soc-es8328-objs := es8328.o
|
||||
@ -505,6 +506,7 @@ obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
|
||||
obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
|
||||
obj-$(CONFIG_SND_SOC_ES7134) += snd-soc-es7134.o
|
||||
obj-$(CONFIG_SND_SOC_ES7241) += snd-soc-es7241.o
|
||||
obj-$(CONFIG_SND_SOC_ES83XX_DSM_COMMON) += snd-soc-es83xx-dsm-common.o
|
||||
obj-$(CONFIG_SND_SOC_ES8316) += snd-soc-es8316.o
|
||||
obj-$(CONFIG_SND_SOC_ES8326) += snd-soc-es8326.o
|
||||
obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
|
||||
|
@ -146,6 +146,7 @@ struct aw_device {
|
||||
|
||||
unsigned int channel;
|
||||
unsigned int fade_step;
|
||||
unsigned int prof_data_type;
|
||||
|
||||
struct i2c_client *i2c;
|
||||
struct device *dev;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <linux/i2c.h>
|
||||
#include "aw88395_lib.h"
|
||||
#include "aw88395_device.h"
|
||||
#include "aw88395_reg.h"
|
||||
|
||||
#define AW88395_CRC8_POLYNOMIAL 0x8C
|
||||
DECLARE_CRC8_TABLE(aw_crc8_table);
|
||||
@ -456,14 +455,6 @@ static int aw_dev_parse_reg_bin_with_hdr(struct aw_device *aw_dev,
|
||||
goto parse_bin_failed;
|
||||
}
|
||||
|
||||
if (aw_dev->chip_id == AW88261_CHIP_ID) {
|
||||
if (aw_bin->header_info[0].valid_data_len % 4) {
|
||||
dev_err(aw_dev->dev, "bin data len get error!");
|
||||
ret = -EINVAL;
|
||||
goto parse_bin_failed;
|
||||
}
|
||||
}
|
||||
|
||||
prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data =
|
||||
data + aw_bin->header_info[0].valid_data_addr;
|
||||
prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len =
|
||||
@ -528,7 +519,7 @@ static int aw_dev_parse_dev_type(struct aw_device *aw_dev,
|
||||
cfg_dde[i].dev_profile);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
aw_dev->prof_data_type = cfg_dde[i].data_type;
|
||||
ret = aw_dev_parse_data_by_sec_type(aw_dev, prof_hdr, &cfg_dde[i],
|
||||
&all_prof_info->prof_desc[cfg_dde[i].dev_profile]);
|
||||
if (ret < 0) {
|
||||
@ -564,6 +555,7 @@ static int aw_dev_parse_dev_default_type(struct aw_device *aw_dev,
|
||||
cfg_dde[i].dev_profile);
|
||||
return -EINVAL;
|
||||
}
|
||||
aw_dev->prof_data_type = cfg_dde[i].data_type;
|
||||
ret = aw_dev_parse_data_by_sec_type(aw_dev, prof_hdr, &cfg_dde[i],
|
||||
&all_prof_info->prof_desc[cfg_dde[i].dev_profile]);
|
||||
if (ret < 0) {
|
||||
@ -582,7 +574,7 @@ static int aw_dev_parse_dev_default_type(struct aw_device *aw_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88261_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
|
||||
static int aw_dev_cfg_get_reg_valid_prof(struct aw_device *aw_dev,
|
||||
struct aw_all_prof_info *all_prof_info)
|
||||
{
|
||||
struct aw_prof_desc *prof_desc = all_prof_info->prof_desc;
|
||||
@ -624,7 +616,7 @@ static int aw88261_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
|
||||
static int aw_dev_cfg_get_multiple_valid_prof(struct aw_device *aw_dev,
|
||||
struct aw_all_prof_info *all_prof_info)
|
||||
{
|
||||
struct aw_prof_desc *prof_desc = all_prof_info->prof_desc;
|
||||
@ -703,26 +695,20 @@ static int aw_dev_load_cfg_by_hdr(struct aw_device *aw_dev,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (aw_dev->chip_id) {
|
||||
case AW88395_CHIP_ID:
|
||||
case AW88399_CHIP_ID:
|
||||
ret = aw88395_dev_cfg_get_valid_prof(aw_dev, all_prof_info);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
switch (aw_dev->prof_data_type) {
|
||||
case ACF_SEC_TYPE_MULTIPLE_BIN:
|
||||
ret = aw_dev_cfg_get_multiple_valid_prof(aw_dev, all_prof_info);
|
||||
break;
|
||||
case AW88261_CHIP_ID:
|
||||
case AW87390_CHIP_ID:
|
||||
ret = aw88261_dev_cfg_get_valid_prof(aw_dev, all_prof_info);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
case ACF_SEC_TYPE_HDR_REG:
|
||||
ret = aw_dev_cfg_get_reg_valid_prof(aw_dev, all_prof_info);
|
||||
break;
|
||||
default:
|
||||
dev_err(aw_dev->dev, "valid prof unsupported");
|
||||
dev_err(aw_dev->dev, "unsupport data type\n");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
aw_dev->prof_info.prof_name_list = profile_name;
|
||||
if (!ret)
|
||||
aw_dev->prof_info.prof_name_list = profile_name;
|
||||
|
||||
exit:
|
||||
devm_kfree(aw_dev->dev, all_prof_info);
|
||||
@ -791,39 +777,23 @@ static int aw_get_dev_scene_count_v1(struct aw_device *aw_dev, struct aw_contain
|
||||
struct aw_cfg_dde_v1 *cfg_dde =
|
||||
(struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
switch (aw_dev->chip_id) {
|
||||
case AW88395_CHIP_ID:
|
||||
case AW88399_CHIP_ID:
|
||||
for (i = 0; i < cfg_hdr->ddt_num; ++i) {
|
||||
if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&
|
||||
(aw_dev->chip_id == cfg_dde[i].chip_id) &&
|
||||
(aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
|
||||
(aw_dev->i2c->addr == cfg_dde[i].dev_addr))
|
||||
(*scene_num)++;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case AW88261_CHIP_ID:
|
||||
case AW87390_CHIP_ID:
|
||||
for (i = 0; i < cfg_hdr->ddt_num; ++i) {
|
||||
if (((cfg_dde[i].data_type == ACF_SEC_TYPE_REG) ||
|
||||
(cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG)) &&
|
||||
(aw_dev->chip_id == cfg_dde[i].chip_id) &&
|
||||
(aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
|
||||
(aw_dev->i2c->addr == cfg_dde[i].dev_addr))
|
||||
(*scene_num)++;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
dev_err(aw_dev->dev, "unsupported device");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
for (i = 0; i < cfg_hdr->ddt_num; ++i) {
|
||||
if (((cfg_dde[i].data_type == ACF_SEC_TYPE_REG) ||
|
||||
(cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG) ||
|
||||
(cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN)) &&
|
||||
(aw_dev->chip_id == cfg_dde[i].chip_id) &&
|
||||
(aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
|
||||
(aw_dev->i2c->addr == cfg_dde[i].dev_addr))
|
||||
(*scene_num)++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
if ((*scene_num) == 0) {
|
||||
dev_err(aw_dev->dev, "failed to obtain scene, scenu_num = %d\n", (*scene_num));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_get_default_scene_count_v1(struct aw_device *aw_dev,
|
||||
@ -834,37 +804,23 @@ static int aw_get_default_scene_count_v1(struct aw_device *aw_dev,
|
||||
struct aw_cfg_dde_v1 *cfg_dde =
|
||||
(struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
switch (aw_dev->chip_id) {
|
||||
case AW88395_CHIP_ID:
|
||||
case AW88399_CHIP_ID:
|
||||
for (i = 0; i < cfg_hdr->ddt_num; ++i) {
|
||||
if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&
|
||||
(aw_dev->chip_id == cfg_dde[i].chip_id) &&
|
||||
(aw_dev->channel == cfg_dde[i].dev_index))
|
||||
(*scene_num)++;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case AW88261_CHIP_ID:
|
||||
case AW87390_CHIP_ID:
|
||||
for (i = 0; i < cfg_hdr->ddt_num; ++i) {
|
||||
if (((cfg_dde[i].data_type == ACF_SEC_TYPE_REG) ||
|
||||
(cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG)) &&
|
||||
(aw_dev->chip_id == cfg_dde[i].chip_id) &&
|
||||
(aw_dev->channel == cfg_dde[i].dev_index))
|
||||
(*scene_num)++;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
dev_err(aw_dev->dev, "unsupported device");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
||||
for (i = 0; i < cfg_hdr->ddt_num; ++i) {
|
||||
if (((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) ||
|
||||
(cfg_dde[i].data_type == ACF_SEC_TYPE_REG) ||
|
||||
(cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG)) &&
|
||||
(aw_dev->chip_id == cfg_dde[i].chip_id) &&
|
||||
(aw_dev->channel == cfg_dde[i].dev_index))
|
||||
(*scene_num)++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
if ((*scene_num) == 0) {
|
||||
dev_err(aw_dev->dev, "failed to obtain scene, scenu_num = %d\n", (*scene_num));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_dev_parse_scene_count_v1(struct aw_device *aw_dev,
|
||||
|
@ -95,10 +95,7 @@
|
||||
#define AW88395_TM_REG (0x7C)
|
||||
|
||||
enum aw88395_id {
|
||||
AW88399_CHIP_ID = 0x2183,
|
||||
AW88395_CHIP_ID = 0x2049,
|
||||
AW88261_CHIP_ID = 0x2113,
|
||||
AW87390_CHIP_ID = 0x76,
|
||||
};
|
||||
|
||||
#define AW88395_REG_MAX (0x7D)
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <sound/soc.h>
|
||||
#include "aw88399.h"
|
||||
#include "aw88395/aw88395_device.h"
|
||||
#include "aw88395/aw88395_reg.h"
|
||||
|
||||
static const struct regmap_config aw88399_remap_config = {
|
||||
.val_bits = 16,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user