1

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:
Linus Torvalds 2024-01-12 11:55:28 -08:00
commit 7912a6391f
287 changed files with 10603 additions and 3989 deletions

View File

@ -39,7 +39,7 @@ unevaluatedProperties: false
examples:
- |
soundwire-controller@3250000 {
soundwire@3250000 {
#address-cells = <2>;
#size-cells = <0>;
reg = <0x3250000 0x2000>;

View File

@ -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:

View File

@ -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 = <&reg_3p3v>;
AVDD-supply = <&reg_3p3v>;
PVDD-supply = <&reg_3p3v>;
HPVDD-supply = <&reg_3p3v>;
clocks = <&clks 169>;
reg = <0x11>;
};

View 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 = <&reg_3p3v>;
DVDD-supply = <&reg_3p3v>;
HPVDD-supply = <&reg_3p3v>;
PVDD-supply = <&reg_3p3v>;
clocks = <&clks 169>;
};
};

View File

@ -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";
};

View 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>;
};

View File

@ -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:

View File

@ -15,6 +15,7 @@ allOf:
properties:
compatible:
enum:
- mediatek,mt8188-es8326
- mediatek,mt8188-mt6359-evb
- mediatek,mt8188-nau8825
- mediatek,mt8188-rt5682s

View File

@ -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>;
};
};

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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>;

View File

@ -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>;
};
};

View File

@ -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>;
};
};

View File

@ -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>;

View File

@ -48,7 +48,7 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
soundwire-controller {
soundwire {
#address-cells = <2>;
#size-cells = <0>;

View File

@ -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>;
};
};
};

View File

@ -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

View File

@ -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

View File

@ -90,7 +90,7 @@ examples:
ldoin-supply = <&reg_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 */

View File

@ -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.

View File

@ -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>

View File

@ -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>;
};

View File

@ -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,

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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 */
/*

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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)
{

View File

@ -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];

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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,

View File

@ -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;
};

View File

@ -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

View File

@ -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];

View File

@ -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];

View File

@ -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;

View File

@ -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 */

View 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 */

View File

@ -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

View File

@ -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,

View File

@ -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",
};

View File

@ -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[] = {

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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(&params, 0, sizeof(params));
params_set_format(&params, snd_hdac_format_normalize(format));
snd_mask_set(hw_param_mask(&params, SNDRV_PCM_HW_PARAM_SUBFORMAT),
(__force unsigned int)subformat);
bits = snd_pcm_hw_params_bits(&params);
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;
}

View File

@ -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) {

View File

@ -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 */

View File

@ -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;

View File

@ -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 :-)
*/

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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 },
{}
};

View File

@ -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)

View File

@ -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);

View File

@ -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",

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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),

View File

@ -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);

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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;

View File

@ -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,
},
};

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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 = {

View File

@ -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,
};

View File

@ -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),
}
};

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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)

View File

@ -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