mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
sound updates for 5.19-rc1
Not much dramatic changes at this time, but we've received quite a lot of changes for ASoC, while there are still a few fixes and quirks for usual HD- and USB-auido. Here are some highlights. * ASoC: - Overhaul of endianness specification for data formats, avoiding needless restrictions due to CODECs - Initial stages of Intel AVS driver merge - Introduction of v4 IPC mechanism for SOF - TDM mode support for AK4613 - Support for Analog Devices ADAU1361, Cirrus Logic CS35L45, Maxim MAX98396, MediaTek MT8186, NXP i.MX8 micfil and SAI interfaces, nVidia Tegra186 ASRC, and Texas Instruments TAS2764 and TAS2780 * Others - A few regression fixes after the USB-audio endpoint management refactoring - More enhancements for Cirrus HD-audio codec support (still ongoing) - Addition of generic serial MIDI driver -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmKOEiAOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE96FxAAnoVCecFK955fWInCULe15xYpi9kqngDSLAQk k6TkbP8AFyX+3PbIb9YVK9u+fLBaZzdK/ZIRqZNfb5T4q8tVTHphg2P+SNB36qaD nTTaEQ6dr6VUJO3fwwVBa3NJ+rGPr8KMKLlQGCg/I8HKdFeW2t/mV1YZI/ZxM7Or MXu3F5dt3yVXXMgUb33if+atYCXOwJ9YIqe1WHE4oPTtfOhbwiIdFeHgg88Kq7vJ ep7PCbyJ0rqfA9BIAnBfQuD9ZoaS7mKlo9xgyauNBzWnbRVd7dYyUnaxH++XLPPS GS0MEgftJfmUay6o++I7qrhoTyMKMHN/CU+6RlR1GD6WBpBhQ6T+poLkFDvKqbL8 kvFEBFrEf0soeAKkUinzl1wCJnzWvpq2PF0EewQp03A3vOL5MOzGdId1wLKLmbCw Z0e0HAKTP4/AQeBluLo/SjiNoeSEU76xYYv8tFGv531ybIhvsF0nm/Suv4VZcy0V 9tr2gLSORDLTBqSJqCf1JgN8oJht0QLirzgSekk8HUvx1JnIwwAaH1Dvy1DMrjyu TQ6oRyDS2giHKh7FItv3+U+HE1CkA89dzDvGrIbKrT6xkodHGzLNr0DxaDGuR11w H9f9oFEnGBpBxWmfLkGTa8+oBenTz8YRm4Ti8xhZkJkD1ys/4fjasAYoIKJqdnxH iG1DWic= =5qBk -----END PGP SIGNATURE----- Merge tag 'sound-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "Not much dramatic changes at this time, but we've received quite a lot of changes for ASoC, while there are still a few fixes and quirks for usual HD- and USB-auido. Here are some highlights. ASoC: - Overhaul of endianness specification for data formats, avoiding needless restrictions due to CODECs - Initial stages of Intel AVS driver merge - Introduction of v4 IPC mechanism for SOF - TDM mode support for AK4613 - Support for Analog Devices ADAU1361, Cirrus Logic CS35L45, Maxim MAX98396, MediaTek MT8186, NXP i.MX8 micfil and SAI interfaces, nVidia Tegra186 ASRC, and Texas Instruments TAS2764 and TAS2780 Others: - A few regression fixes after the USB-audio endpoint management refactoring - More enhancements for Cirrus HD-audio codec support (still ongoing) - Addition of generic serial MIDI driver" * tag 'sound-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (504 commits) ALSA: hda/realtek - Add new type for ALC245 ALSA: usb-audio: Configure sync endpoints before data ALSA: ctxfi: fix typo in comment ALSA: cs5535audio: fix typo in comment ALSA: ctxfi: Add SB046x PCI ID ALSA: usb-audio: Add missing ep_idx in fixed EP quirks ALSA: usb-audio: Workaround for clock setup on TEAC devices ALSA: lola: Bounds check loop iterator against streams array size ASoC: max98090: Move check for invalid values before casting in max98090_put_enab_tlv() ASoC: rt1308-sdw: add the default value of register 0xc320 ASoC: rt9120: Use pm_runtime and regcache to optimize 'pwdnn' logic ASoC: rt9120: Fix 3byte read, valule offset typo ASoC: amd: acp: Set Speaker enable/disable pin through rt1019 codec driver. ASoC: amd: acp: Set Speaker enable/disable pin through rt1019 codec driver ASoC: wm2000: fix missing clk_disable_unprepare() on error in wm2000_anc_transition() ASoC: codecs: lpass: Fix passing zero to 'PTR_ERR' ASoC: SOF: sof-client-ipc-flood-test: use pm_runtime_resume_and_get() ASoC: SOF: mediatek: remove duplicate include in mt8195.c ASoC: SOF: mediatek: Add mt8195 debug dump ASoC: SOF: mediatek: Add mediatek common debug dump ...
This commit is contained in:
commit
d7227785e3
105
Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
Normal file
105
Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
Normal file
@ -0,0 +1,105 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/dsp/mediatek,mt8195-dsp.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek mt8195 DSP core
|
||||
|
||||
maintainers:
|
||||
- YC Hung <yc.hung@mediatek.com>
|
||||
|
||||
description: |
|
||||
Some boards from mt8195 contain a DSP core used for
|
||||
advanced pre- and post- audio processing.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8195-dsp
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address and size of the DSP Cfg registers
|
||||
- description: Address and size of the DSP SRAM
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: cfg
|
||||
- const: sram
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: mux for audio dsp clock
|
||||
- description: 26M clock
|
||||
- description: mux for audio dsp local bus
|
||||
- description: default audio dsp local bus clock source
|
||||
- description: clock gate for audio dsp clock
|
||||
- description: mux for audio dsp access external bus
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: adsp_sel
|
||||
- const: clk26m_ck
|
||||
- const: audio_local_bus
|
||||
- const: mainpll_d7_d2
|
||||
- const: scp_adsp_audiodsp
|
||||
- const: audio_h
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
mboxes:
|
||||
items:
|
||||
- description: ipc reply between host and audio DSP.
|
||||
- description: ipc request between host and audio DSP.
|
||||
|
||||
mbox-names:
|
||||
items:
|
||||
- const: mbox0
|
||||
- const: mbox1
|
||||
|
||||
memory-region:
|
||||
items:
|
||||
- description: dma buffer between host and DSP.
|
||||
- description: DSP system memory.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- memory-region
|
||||
- power-domains
|
||||
- mbox-names
|
||||
- mboxes
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
dsp@10803000 {
|
||||
compatible = "mediatek,mt8195-dsp";
|
||||
reg = <0x10803000 0x1000>,
|
||||
<0x10840000 0x40000>;
|
||||
reg-names = "cfg", "sram";
|
||||
clocks = <&topckgen 10>, //CLK_TOP_ADSP
|
||||
<&clk26m>,
|
||||
<&topckgen 107>, //CLK_TOP_AUDIO_LOCAL_BUS
|
||||
<&topckgen 136>, //CLK_TOP_MAINPLL_D7_D2
|
||||
<&scp_adsp 0>, //CLK_SCP_ADSP_AUDIODSP
|
||||
<&topckgen 34>; //CLK_TOP_AUDIO_H
|
||||
clock-names = "adsp_sel",
|
||||
"clk26m_ck",
|
||||
"audio_local_bus",
|
||||
"mainpll_d7_d2",
|
||||
"scp_adsp_audiodsp",
|
||||
"audio_h";
|
||||
memory-region = <&adsp_dma_mem_reserved>,
|
||||
<&adsp_mem_reserved>;
|
||||
power-domains = <&spm 6>; //MT8195_POWER_DOMAIN_ADSP
|
||||
mbox-names = "mbox0", "mbox1";
|
||||
mboxes = <&adsp_mailbox0>, <&adsp_mailbox1>;
|
||||
};
|
79
Documentation/devicetree/bindings/sound/adi,max98396.yaml
Normal file
79
Documentation/devicetree/bindings/sound/adi,max98396.yaml
Normal file
@ -0,0 +1,79 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/adi,max98396.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices MAX98396 Speaker Amplifier Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Ryan Lee <ryans.lee@analog.com>
|
||||
|
||||
description:
|
||||
The MAX98396 is a mono Class-DG speaker amplifier with I/V sense.
|
||||
The device provides a PCM interface for audio data and a standard
|
||||
I2C interface for control data communication.
|
||||
The MAX98397 is a variant of MAX98396 with wide input supply range.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,max98396
|
||||
- adi,max98397
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: I2C address of the device.
|
||||
|
||||
adi,vmon-slot-no:
|
||||
description: slot number of the voltage sense monitor
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
default: 0
|
||||
|
||||
adi,imon-slot-no:
|
||||
description: slot number of the current sense monitor
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
default: 0
|
||||
|
||||
adi,spkfb-slot-no:
|
||||
description: slot number of speaker DSP monitor
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
default: 0
|
||||
|
||||
adi,interleave-mode:
|
||||
description:
|
||||
For cases where a single combined channel for the I/V sense data
|
||||
is not sufficient, the device can also be configured to share
|
||||
a single data output channel on alternating frames.
|
||||
In this configuration, the current and voltage data will be frame
|
||||
interleaved on a single output channel.
|
||||
type: boolean
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
max98396: amplifier@39 {
|
||||
compatible = "adi,max98396";
|
||||
reg = <0x39>;
|
||||
adi,vmon-slot-no = <0>;
|
||||
adi,imon-slot-no = <1>;
|
||||
reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
@ -75,6 +75,19 @@ properties:
|
||||
maximum: 3
|
||||
default: 2
|
||||
|
||||
cirrus,boost-type:
|
||||
description:
|
||||
Configures the type of Boost being used.
|
||||
Internal boost requires boost-peak-milliamp, boost-ind-nanohenry and
|
||||
boost-cap-microfarad.
|
||||
External Boost must have GPIO1 as GPIO output. GPIO1 will be set high to
|
||||
enable boost voltage.
|
||||
0 = Internal Boost
|
||||
1 = External Boost
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
||||
cirrus,gpio1-polarity-invert:
|
||||
description:
|
||||
Boolean which specifies whether the GPIO1
|
||||
@ -131,9 +144,32 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- cirrus,boost-peak-milliamp
|
||||
- cirrus,boost-ind-nanohenry
|
||||
- cirrus,boost-cap-microfarad
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
cirrus,boost-type:
|
||||
const: 0
|
||||
then:
|
||||
required:
|
||||
- cirrus,boost-peak-milliamp
|
||||
- cirrus,boost-ind-nanohenry
|
||||
- cirrus,boost-cap-microfarad
|
||||
else:
|
||||
if:
|
||||
properties:
|
||||
cirrus,boost-type:
|
||||
const: 1
|
||||
then:
|
||||
required:
|
||||
- cirrus,gpio1-output-enable
|
||||
- cirrus,gpio1-src-select
|
||||
properties:
|
||||
cirrus,boost-peak-milliamp: false
|
||||
cirrus,boost-ind-nanohenry: false
|
||||
cirrus,boost-cap-microfarad: false
|
||||
cirrus,gpio1-src-select:
|
||||
enum: [1]
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@ -150,6 +186,8 @@ examples:
|
||||
VA-supply = <&dummy_vreg>;
|
||||
VP-supply = <&dummy_vreg>;
|
||||
reset-gpios = <&gpio 110 0>;
|
||||
|
||||
cirrus,boost-type = <0>;
|
||||
cirrus,boost-peak-milliamp = <4500>;
|
||||
cirrus,boost-ind-nanohenry = <1000>;
|
||||
cirrus,boost-cap-microfarad = <15>;
|
||||
|
75
Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
Normal file
75
Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml
Normal file
@ -0,0 +1,75 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/cirrus,cs35l45.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Cirrus Logic CS35L45 Speaker Amplifier
|
||||
|
||||
maintainers:
|
||||
- Ricardo Rivera-Matos <rriveram@opensource.cirrus.com>
|
||||
- Richard Fitzgerald <rf@opensource.cirrus.com>
|
||||
|
||||
description: |
|
||||
CS35L45 is a Boosted Mono Class D Amplifier with DSP
|
||||
Speaker Protection and Adaptive Battery Management.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- cirrus,cs35l45
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
vdd-a-supply:
|
||||
description: voltage regulator phandle for the VDD_A supply
|
||||
|
||||
vdd-batt-supply:
|
||||
description: voltage regulator phandle for the VDD_BATT supply
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 5000000
|
||||
|
||||
cirrus,asp-sdout-hiz-ctrl:
|
||||
description:
|
||||
Audio serial port SDOUT Hi-Z control. Sets the Hi-Z
|
||||
configuration for SDOUT pin of amplifier. Logical OR of
|
||||
CS35L45_ASP_TX_HIZ_xxx values.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/sound/cs35l45.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cs35l45: cs35l45@2 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "cirrus,cs35l45";
|
||||
reg = <2>;
|
||||
spi-max-frequency = <5000000>;
|
||||
vdd-a-supply = <&dummy_vreg>;
|
||||
vdd-batt-supply = <&dummy_vreg>;
|
||||
reset-gpios = <&gpio 110 0>;
|
||||
cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
|
||||
CS35L45_ASP_TX_HIZ_DISABLED)>;
|
||||
};
|
||||
};
|
@ -6,6 +6,7 @@ microphone bitstream in a configurable output sampling rate.
|
||||
Required properties:
|
||||
|
||||
- compatible : Compatible list, contains "fsl,imx8mm-micfil"
|
||||
or "fsl,imx8mp-micfil"
|
||||
|
||||
- reg : Offset and length of the register set for the device.
|
||||
|
||||
|
@ -29,6 +29,9 @@ properties:
|
||||
minimum: 1
|
||||
maximum: 8388607
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -37,6 +40,7 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@ -45,5 +49,6 @@ examples:
|
||||
reg = <0x38>;
|
||||
maxim,temperature_calib = <1024>;
|
||||
maxim,r0_calib = <100232>;
|
||||
reset-gpios = <&gpio 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
@ -18,6 +18,7 @@ properties:
|
||||
enum:
|
||||
- mediatek,mt8192_mt6359_rt1015_rt5682
|
||||
- mediatek,mt8192_mt6359_rt1015p_rt5682
|
||||
- mediatek,mt8192_mt6359_rt1015p_rt5682s
|
||||
|
||||
mediatek,platform:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
@ -27,11 +28,33 @@ properties:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of HDMI codec.
|
||||
|
||||
headset-codec:
|
||||
type: object
|
||||
properties:
|
||||
sound-dai:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
speaker-codecs:
|
||||
type: object
|
||||
properties:
|
||||
sound-dai:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
maxItems: 1
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- mediatek,platform
|
||||
- headset-codec
|
||||
- speaker-codecs
|
||||
|
||||
examples:
|
||||
- |
|
||||
@ -44,6 +67,15 @@ examples:
|
||||
"aud_clk_mosi_on";
|
||||
pinctrl-0 = <&aud_clk_mosi_off>;
|
||||
pinctrl-1 = <&aud_clk_mosi_on>;
|
||||
|
||||
headset-codec {
|
||||
sound-dai = <&rt5682>;
|
||||
};
|
||||
|
||||
speaker-codecs {
|
||||
sound-dai = <&rt1015_l>,
|
||||
<&rt1015_r>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
@ -1,51 +0,0 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1011-rt5682.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek MT8195 with MT6359, RT1011 and RT5682 ASoC sound card driver
|
||||
|
||||
maintainers:
|
||||
- Trevor Wu <trevor.wu@mediatek.com>
|
||||
|
||||
description:
|
||||
This binding describes the MT8195 sound card with RT1011 and RT5682.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8195_mt6359_rt1011_rt5682
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: User specified audio sound card name
|
||||
|
||||
mediatek,platform:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8195 ASoC platform.
|
||||
|
||||
mediatek,dptx-codec:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8195 Display Port Tx codec node.
|
||||
|
||||
mediatek,hdmi-codec:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8195 HDMI codec node.
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- mediatek,platform
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
sound: mt8195-sound {
|
||||
compatible = "mediatek,mt8195_mt6359_rt1011_rt5682";
|
||||
mediatek,platform = <&afe>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&aud_pins_default>;
|
||||
};
|
||||
|
||||
...
|
@ -1,10 +1,10 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1019-rt5682.yaml#
|
||||
$id: http://devicetree.org/schemas/sound/mt8195-mt6359.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek MT8195 with MT6359, RT1019 and RT5682 ASoC sound card driver
|
||||
title: MediaTek MT8195 ASoC sound card driver
|
||||
|
||||
maintainers:
|
||||
- Trevor Wu <trevor.wu@mediatek.com>
|
||||
@ -14,7 +14,10 @@ description:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8195_mt6359_rt1019_rt5682
|
||||
enum:
|
||||
- mediatek,mt8195_mt6359_rt1019_rt5682
|
||||
- mediatek,mt8195_mt6359_rt1011_rt5682
|
||||
- mediatek,mt8195_mt6359_max98390_rt5682
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra186-asrc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tegra186 ASRC Device Tree Bindings
|
||||
|
||||
description: |
|
||||
Asynchronous Sample Rate Converter (ASRC) converts the sampling frequency
|
||||
of the input signal from one frequency to another. It can handle over a
|
||||
wide range of sample rate ratios (freq_in/freq_out) from 1:24 to 24:1.
|
||||
ASRC has two modes of operation. One where ratio can be programmed in SW
|
||||
and the other where it gets the information from ratio estimator module.
|
||||
|
||||
It supports sample rate conversions in the range of 8 to 192 kHz and
|
||||
supports 6 streams upto 12 total channels. The input data size can be
|
||||
16, 24 and 32 bits.
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Mohan Kumar <mkumard@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^asrc@[0-9a-f]*$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra186-asrc
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-asrc
|
||||
- nvidia,tegra194-asrc
|
||||
- const: nvidia,tegra186-asrc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^ASRC[1-9]$"
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
ASRC has seven input ports and six output ports. Accordingly ACIF
|
||||
(Audio Client Interfaces) port nodes are defined to represent the
|
||||
ASRC inputs (port 0 to 6) and outputs (port 7 to 12). These are
|
||||
connected to corresponding ports on AHUB (Audio Hub). Additional
|
||||
input (port 6) is for receiving ratio information from estimator.
|
||||
|
||||
patternProperties:
|
||||
'^port@[0-6]':
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: ASRC ACIF input ports
|
||||
'^port@[7-9]|1[1-2]':
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: ASRC ACIF output ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
asrc@2910000 {
|
||||
compatible = "nvidia,tegra186-asrc";
|
||||
reg = <0x2910000 0x2000>;
|
||||
sound-name-prefix = "ASRC1";
|
||||
};
|
||||
|
||||
...
|
@ -106,6 +106,10 @@ patternProperties:
|
||||
type: object
|
||||
$ref: nvidia,tegra210-mixer.yaml#
|
||||
|
||||
'^asrc@[0-9a-f]+$':
|
||||
type: object
|
||||
$ref: nvidia,tegra186-asrc.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -38,8 +38,8 @@ properties:
|
||||
maxItems: 7
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
maxItems: 7
|
||||
minItems: 1
|
||||
maxItems: 10
|
||||
|
||||
interrupts:
|
||||
minItems: 2
|
||||
@ -62,6 +62,9 @@ properties:
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
power-domain-names:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
@ -192,15 +195,19 @@ allOf:
|
||||
oneOf:
|
||||
- items: #for I2S
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: audio_cc_ext_mclk0
|
||||
- const: core_cc_sysnoc_mport_core
|
||||
- const: core_cc_ext_if0_ibit
|
||||
- const: core_cc_ext_if1_ibit
|
||||
- items: #for Soundwire
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: audio_cc_codec_mem
|
||||
- const: audio_cc_codec_mem0
|
||||
- const: audio_cc_codec_mem1
|
||||
- const: audio_cc_codec_mem2
|
||||
- const: aon_cc_va_mem0
|
||||
- items: #for HDMI
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: core_cc_sysnoc_mport_core
|
||||
|
||||
reg-names:
|
||||
anyOf:
|
||||
@ -228,6 +235,10 @@ allOf:
|
||||
- const: lpass-irq-hdmi
|
||||
- const: lpass-irq-vaif
|
||||
- const: lpass-irq-rxtxif
|
||||
power-domain-names:
|
||||
allOf:
|
||||
- items:
|
||||
- const: lcx
|
||||
|
||||
required:
|
||||
- iommus
|
||||
|
@ -28,12 +28,17 @@ properties:
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
oneOf:
|
||||
- items: #for ADSP based platforms
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
- items: #for ADSP bypass based platforms
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: fsgen
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
|
@ -28,12 +28,17 @@ properties:
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
oneOf:
|
||||
- items: #for ADSP based platforms
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
- items: #for ADSP bypass based platforms
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: fsgen
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
|
@ -28,10 +28,13 @@ properties:
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: core
|
||||
- const: dcodec
|
||||
oneOf:
|
||||
- items: #for ADSP based platforms
|
||||
- const: mclk
|
||||
- const: core
|
||||
- const: dcodec
|
||||
- items: #for ADSP bypass based platforms
|
||||
- const: mclk
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
|
@ -36,6 +36,9 @@ properties:
|
||||
vdd-io-supply:
|
||||
description: A reference to the 1.8V I/O supply
|
||||
|
||||
vdd-mic-bias-supply:
|
||||
description: A reference to the 3.8V mic bias supply
|
||||
|
||||
qcom,tx-device:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: A reference to Soundwire tx device phandle
|
||||
|
@ -25,6 +25,9 @@ properties:
|
||||
0 means shut down; 1 means power on.
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
@ -46,6 +46,8 @@ Optional properties:
|
||||
|
||||
- realtek,dmic-clk-driving-high : Set the high driving of the DMIC clock out.
|
||||
|
||||
- #sound-dai-cells: Should be set to '<0>'.
|
||||
|
||||
Pins on the device (for linking into audio routes) for RT5682:
|
||||
|
||||
* DMIC L1
|
||||
|
51
Documentation/devicetree/bindings/sound/serial-midi.yaml
Normal file
51
Documentation/devicetree/bindings/sound/serial-midi.yaml
Normal file
@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/serial-midi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Generic Serial MIDI Interface
|
||||
|
||||
maintainers:
|
||||
- Daniel Kaehn <kaehndan@gmail.com>
|
||||
|
||||
description:
|
||||
Generic MIDI interface using a serial device. This denotes that a serial device is
|
||||
dedicated to MIDI communication, either to an external MIDI device through a DIN5
|
||||
or other connector, or to a known hardwired MIDI controller. This device must be a
|
||||
child node of a serial node.
|
||||
|
||||
Can only be set to use standard baud rates corresponding to supported rates of the
|
||||
parent serial device. If the standard MIDI baud of 31.25 kBaud is needed
|
||||
(as would be the case if interfacing with arbitrary external MIDI devices),
|
||||
configure the clocks of the parent serial device so that a requested baud of 38.4 kBaud
|
||||
resuts in the standard MIDI baud rate, and set the 'current-speed' property to 38400 (default)
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: serial-midi
|
||||
|
||||
current-speed:
|
||||
description: Baudrate to set the serial port to when this MIDI device is opened.
|
||||
default: 38400
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial {
|
||||
midi {
|
||||
compatible = "serial-midi";
|
||||
};
|
||||
};
|
||||
- |
|
||||
serial {
|
||||
midi {
|
||||
compatible = "serial-midi";
|
||||
current-speed = <115200>;
|
||||
};
|
||||
};
|
@ -1,25 +1,26 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2020 Texas Instruments Incorporated
|
||||
# Copyright (C) 2020-2022 Texas Instruments Incorporated
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/sound/tas2764.yaml#"
|
||||
$id: "http://devicetree.org/schemas/sound/tas27xx.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Texas Instruments TAS2764 Smart PA
|
||||
title: Texas Instruments TAS2764/TAS2780 Smart PA
|
||||
|
||||
maintainers:
|
||||
- Dan Murphy <dmurphy@ti.com>
|
||||
- Shenghao Ding <shenghao-ding@ti.com>
|
||||
|
||||
description: |
|
||||
The TAS2764 is a mono, digital input Class-D audio amplifier optimized for
|
||||
efficiently driving high peak power into small loudspeakers.
|
||||
Integrated speaker voltage and current sense provides for
|
||||
real time monitoring of loudspeaker behavior.
|
||||
The TAS2764/TAS2780 is a mono, digital input Class-D audio amplifier
|
||||
optimized for efficiently driving high peak power into small
|
||||
loudspeakers. Integrated speaker voltage and current sense provides
|
||||
for real time monitoring of loudspeaker behavior.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tas2764
|
||||
- ti,tas2780
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
97
Documentation/devicetree/bindings/sound/wlf,wm8731.yaml
Normal file
97
Documentation/devicetree/bindings/sound/wlf,wm8731.yaml
Normal file
@ -0,0 +1,97 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/wlf,wm8731.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Wolfson Microelectromics WM8731 audio CODEC
|
||||
|
||||
maintainers:
|
||||
- patches@opensource.cirrus.com
|
||||
|
||||
description: |
|
||||
Wolfson Microelectronics WM8731 audio CODEC
|
||||
|
||||
Pins on the device (for linking into audio routes):
|
||||
* LOUT: Left Channel Line Output
|
||||
* ROUT: Right Channel Line Output
|
||||
* LHPOUT: Left Channel Headphone Output
|
||||
* RHPOUT: Right Channel Headphone Output
|
||||
* LLINEIN: Left Channel Line Input
|
||||
* RLINEIN: Right Channel Line Input
|
||||
* MICIN: Microphone Input
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- wlf,wm8731
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
description: Clock provider for MCLK pin.
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
AVDD-supply:
|
||||
description: Analog power supply regulator on the AVDD pin.
|
||||
|
||||
HPVDD-supply:
|
||||
description: Headphone power supply regulator on the HPVDD pin.
|
||||
|
||||
DBVDD-supply:
|
||||
description: Digital buffer supply regulator for the DBVDD pin.
|
||||
|
||||
DCVDD-supply:
|
||||
description: Digital core supply regulator for the DCVDD pin.
|
||||
|
||||
spi-max-frequency: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
- compatible
|
||||
- AVDD-supply
|
||||
- HPVDD-supply
|
||||
- DBVDD-supply
|
||||
- DCVDD-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
wm8731_i2c: codec@0 {
|
||||
compatible = "wlf,wm8731";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <12500000>;
|
||||
|
||||
AVDD-supply = <&avdd_reg>;
|
||||
HPVDD-supply = <&hpvdd_reg>;
|
||||
DCVDD-supply = <&dcvdd_reg>;
|
||||
DBVDD-supply = <&dbvdd_reg>;
|
||||
};
|
||||
};
|
||||
- |
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
wm8731_spi: codec@1b {
|
||||
compatible = "wlf,wm8731";
|
||||
reg = <0x1b>;
|
||||
|
||||
AVDD-supply = <&avdd_reg>;
|
||||
HPVDD-supply = <&hpvdd_reg>;
|
||||
DCVDD-supply = <&dcvdd_reg>;
|
||||
DBVDD-supply = <&dbvdd_reg>;
|
||||
};
|
||||
};
|
57
Documentation/devicetree/bindings/sound/wlf,wm8940.yaml
Normal file
57
Documentation/devicetree/bindings/sound/wlf,wm8940.yaml
Normal file
@ -0,0 +1,57 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/wlf,wm8940.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Wolfson WM8940 Codec Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- patches@opensource.cirrus.com
|
||||
|
||||
properties:
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
const: wlf,wm8940
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 526000
|
||||
|
||||
required:
|
||||
- '#sound-dai-cells'
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@0 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "wlf,wm8940";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <500000>;
|
||||
};
|
||||
};
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@1a {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "wlf,wm8940";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -1,27 +0,0 @@
|
||||
WM8731 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8731"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
wm8731: codec@1a {
|
||||
compatible = "wlf,wm8731";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
||||
Available audio endpoints for an audio-routing table:
|
||||
* LOUT: Left Channel Line Output
|
||||
* ROUT: Right Channel Line Output
|
||||
* LHPOUT: Left Channel Headphone Output
|
||||
* RHPOUT: Right Channel Headphone Output
|
||||
* LLINEIN: Left Channel Line Input
|
||||
* RLINEIN: Right Channel Line Input
|
||||
* MICIN: Microphone Input
|
@ -2246,7 +2246,7 @@ implicit_fb
|
||||
Apply the generic implicit feedback sync mode. When this is set
|
||||
and the playback stream sync mode is ASYNC, the driver tries to
|
||||
tie an adjacent ASYNC capture stream as the implicit feedback
|
||||
source.
|
||||
source. This is equivalent with quirk_flags bit 17.
|
||||
use_vmalloc
|
||||
Use vmalloc() for allocations of the PCM buffers (default: yes).
|
||||
For architectures with non-coherent memory like ARM or MIPS, the
|
||||
@ -2288,6 +2288,8 @@ quirk_flags
|
||||
* bit 14: Ignore errors for mixer access
|
||||
* bit 15: Support generic DSD raw U32_BE format
|
||||
* bit 16: Set up the interface at first like UAC1
|
||||
* bit 17: Apply the generic implicit feedback sync mode
|
||||
* bit 18: Don't apply implicit feedback sync mode
|
||||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
|
@ -4705,10 +4705,12 @@ CIRRUS LOGIC AUDIO CODEC DRIVERS
|
||||
M: James Schulman <james.schulman@cirrus.com>
|
||||
M: David Rhodes <david.rhodes@cirrus.com>
|
||||
M: Lucas Tanure <tanureal@opensource.cirrus.com>
|
||||
M: Richard Fitzgerald <rf@opensource.cirrus.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: patches@opensource.cirrus.com
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/cirrus,cs*
|
||||
F: include/dt-bindings/sound/cs*
|
||||
F: sound/pci/hda/cs*
|
||||
F: sound/soc/codecs/cs*
|
||||
|
||||
|
@ -211,7 +211,8 @@ CONFIG_SND_ATMEL_SOC_WM8904=m
|
||||
CONFIG_SND_AT91_SOC_SAM9X5_WM8731=m
|
||||
CONFIG_SND_KIRKWOOD_SOC=y
|
||||
CONFIG_SND_SOC_ALC5623=y
|
||||
CONFIG_SND_SOC_WM8731=y
|
||||
CONFIG_SND_SOC_WM8731_I2C=y
|
||||
CONFIG_SND_SOC_WM8731_SPI=y
|
||||
CONFIG_SND_SIMPLE_CARD=y
|
||||
CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_HID_GYRATION=y
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <linux/of_dma.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <linux/dma/imx-dma.h>
|
||||
|
||||
#include "dmaengine.h"
|
||||
#define IMXDMA_MAX_CHAN_DESCRIPTORS 16
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -35,7 +36,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <linux/dma/imx-dma.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
|
||||
@ -73,6 +74,7 @@
|
||||
#define SDMA_CHNENBL0_IMX35 0x200
|
||||
#define SDMA_CHNENBL0_IMX31 0x080
|
||||
#define SDMA_CHNPRI_0 0x100
|
||||
#define SDMA_DONE0_CONFIG 0x1000
|
||||
|
||||
/*
|
||||
* Buffer descriptor status values.
|
||||
@ -180,6 +182,12 @@
|
||||
BIT(DMA_MEM_TO_DEV) | \
|
||||
BIT(DMA_DEV_TO_DEV))
|
||||
|
||||
#define SDMA_WATERMARK_LEVEL_N_FIFOS GENMASK(15, 12)
|
||||
#define SDMA_WATERMARK_LEVEL_SW_DONE BIT(23)
|
||||
|
||||
#define SDMA_DONE0_CONFIG_DONE_SEL BIT(7)
|
||||
#define SDMA_DONE0_CONFIG_DONE_DIS BIT(6)
|
||||
|
||||
/**
|
||||
* struct sdma_script_start_addrs - SDMA script start pointers
|
||||
*
|
||||
@ -441,6 +449,9 @@ struct sdma_channel {
|
||||
struct work_struct terminate_worker;
|
||||
struct list_head terminated;
|
||||
bool is_ram_script;
|
||||
unsigned int n_fifos_src;
|
||||
unsigned int n_fifos_dst;
|
||||
bool sw_done;
|
||||
};
|
||||
|
||||
#define IMX_DMA_SG_LOOP BIT(0)
|
||||
@ -778,6 +789,14 @@ static void sdma_event_enable(struct sdma_channel *sdmac, unsigned int event)
|
||||
val = readl_relaxed(sdma->regs + chnenbl);
|
||||
__set_bit(channel, &val);
|
||||
writel_relaxed(val, sdma->regs + chnenbl);
|
||||
|
||||
/* Set SDMA_DONEx_CONFIG is sw_done enabled */
|
||||
if (sdmac->sw_done) {
|
||||
val = readl_relaxed(sdma->regs + SDMA_DONE0_CONFIG);
|
||||
val |= SDMA_DONE0_CONFIG_DONE_SEL;
|
||||
val &= ~SDMA_DONE0_CONFIG_DONE_DIS;
|
||||
writel_relaxed(val, sdma->regs + SDMA_DONE0_CONFIG);
|
||||
}
|
||||
}
|
||||
|
||||
static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
|
||||
@ -940,7 +959,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
|
||||
/*
|
||||
* sets the pc of SDMA script according to the peripheral type
|
||||
*/
|
||||
static void sdma_get_pc(struct sdma_channel *sdmac,
|
||||
static int sdma_get_pc(struct sdma_channel *sdmac,
|
||||
enum sdma_peripheral_type peripheral_type)
|
||||
{
|
||||
struct sdma_engine *sdma = sdmac->sdma;
|
||||
@ -1038,14 +1057,22 @@ static void sdma_get_pc(struct sdma_channel *sdmac,
|
||||
case IMX_DMATYPE_IPU_MEMORY:
|
||||
emi_2_per = sdma->script_addrs->ext_mem_2_ipu_addr;
|
||||
break;
|
||||
default:
|
||||
case IMX_DMATYPE_MULTI_SAI:
|
||||
per_2_emi = sdma->script_addrs->sai_2_mcu_addr;
|
||||
emi_2_per = sdma->script_addrs->mcu_2_sai_addr;
|
||||
break;
|
||||
default:
|
||||
dev_err(sdma->dev, "Unsupported transfer type %d\n",
|
||||
peripheral_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sdmac->pc_from_device = per_2_emi;
|
||||
sdmac->pc_to_device = emi_2_per;
|
||||
sdmac->device_to_device = per_2_per;
|
||||
sdmac->pc_to_pc = emi_2_emi;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdma_load_context(struct sdma_channel *sdmac)
|
||||
@ -1210,9 +1237,26 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
|
||||
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_CONT;
|
||||
}
|
||||
|
||||
static void sdma_set_watermarklevel_for_sais(struct sdma_channel *sdmac)
|
||||
{
|
||||
unsigned int n_fifos;
|
||||
|
||||
if (sdmac->sw_done)
|
||||
sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SW_DONE;
|
||||
|
||||
if (sdmac->direction == DMA_DEV_TO_MEM)
|
||||
n_fifos = sdmac->n_fifos_src;
|
||||
else
|
||||
n_fifos = sdmac->n_fifos_dst;
|
||||
|
||||
sdmac->watermark_level |=
|
||||
FIELD_PREP(SDMA_WATERMARK_LEVEL_N_FIFOS, n_fifos);
|
||||
}
|
||||
|
||||
static int sdma_config_channel(struct dma_chan *chan)
|
||||
{
|
||||
struct sdma_channel *sdmac = to_sdma_chan(chan);
|
||||
int ret;
|
||||
|
||||
sdma_disable_channel(chan);
|
||||
|
||||
@ -1233,7 +1277,9 @@ static int sdma_config_channel(struct dma_chan *chan)
|
||||
break;
|
||||
}
|
||||
|
||||
sdma_get_pc(sdmac, sdmac->peripheral_type);
|
||||
ret = sdma_get_pc(sdmac, sdmac->peripheral_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((sdmac->peripheral_type != IMX_DMATYPE_MEMORY) &&
|
||||
(sdmac->peripheral_type != IMX_DMATYPE_DSP)) {
|
||||
@ -1243,6 +1289,10 @@ static int sdma_config_channel(struct dma_chan *chan)
|
||||
sdmac->peripheral_type == IMX_DMATYPE_ASRC)
|
||||
sdma_set_watermarklevel_for_p2p(sdmac);
|
||||
} else {
|
||||
if (sdmac->peripheral_type ==
|
||||
IMX_DMATYPE_MULTI_SAI)
|
||||
sdma_set_watermarklevel_for_sais(sdmac);
|
||||
|
||||
__set_bit(sdmac->event_id0, sdmac->event_mask);
|
||||
}
|
||||
|
||||
@ -1349,7 +1399,9 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
|
||||
mem_data.dma_request2 = 0;
|
||||
data = &mem_data;
|
||||
|
||||
sdma_get_pc(sdmac, IMX_DMATYPE_MEMORY);
|
||||
ret = sdma_get_pc(sdmac, IMX_DMATYPE_MEMORY);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (data->priority) {
|
||||
@ -1698,9 +1750,23 @@ static int sdma_config(struct dma_chan *chan,
|
||||
struct dma_slave_config *dmaengine_cfg)
|
||||
{
|
||||
struct sdma_channel *sdmac = to_sdma_chan(chan);
|
||||
struct sdma_engine *sdma = sdmac->sdma;
|
||||
|
||||
memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
|
||||
|
||||
if (dmaengine_cfg->peripheral_config) {
|
||||
struct sdma_peripheral_config *sdmacfg = dmaengine_cfg->peripheral_config;
|
||||
if (dmaengine_cfg->peripheral_size != sizeof(struct sdma_peripheral_config)) {
|
||||
dev_err(sdma->dev, "Invalid peripheral size %zu, expected %zu\n",
|
||||
dmaengine_cfg->peripheral_size,
|
||||
sizeof(struct sdma_peripheral_config));
|
||||
return -EINVAL;
|
||||
}
|
||||
sdmac->n_fifos_src = sdmacfg->n_fifos_src;
|
||||
sdmac->n_fifos_dst = sdmacfg->n_fifos_dst;
|
||||
sdmac->sw_done = sdmacfg->sw_done;
|
||||
}
|
||||
|
||||
/* Set ENBLn earlier to make sure dma request triggered after that */
|
||||
if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
|
||||
return -EINVAL;
|
||||
|
@ -616,6 +616,15 @@ static struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card,
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static u32 dummy_read_csr(struct fw_card *card, int csr_offset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dummy_write_csr(struct fw_card *card, int csr_offset, u32 value)
|
||||
{
|
||||
}
|
||||
|
||||
static int dummy_start_iso(struct fw_iso_context *ctx,
|
||||
s32 cycle, u32 sync, u32 tags)
|
||||
{
|
||||
@ -649,6 +658,8 @@ static const struct fw_card_driver dummy_driver_template = {
|
||||
.send_response = dummy_send_response,
|
||||
.cancel_packet = dummy_cancel_packet,
|
||||
.enable_phys_dma = dummy_enable_phys_dma,
|
||||
.read_csr = dummy_read_csr,
|
||||
.write_csr = dummy_write_csr,
|
||||
.allocate_iso_context = dummy_allocate_iso_context,
|
||||
.start_iso = dummy_start_iso,
|
||||
.set_iso_channels = dummy_set_iso_channels,
|
||||
@ -694,3 +705,31 @@ void fw_core_remove_card(struct fw_card *card)
|
||||
WARN_ON(!list_empty(&card->transaction_list));
|
||||
}
|
||||
EXPORT_SYMBOL(fw_core_remove_card);
|
||||
|
||||
/**
|
||||
* fw_card_read_cycle_time: read from Isochronous Cycle Timer Register of 1394 OHCI in MMIO region
|
||||
* for controller card.
|
||||
* @card: The instance of card for 1394 OHCI controller.
|
||||
* @cycle_time: The mutual reference to value of cycle time for the read operation.
|
||||
*
|
||||
* Read value from Isochronous Cycle Timer Register of 1394 OHCI in MMIO region for the given
|
||||
* controller card. This function accesses the region without any lock primitives or IRQ mask.
|
||||
* When returning successfully, the content of @value argument has value aligned to host endianness,
|
||||
* formetted by CYCLE_TIME CSR Register of IEEE 1394 std.
|
||||
*
|
||||
* Context: Any context.
|
||||
* Return:
|
||||
* * 0 - Read successfully.
|
||||
* * -ENODEV - The controller is unavailable due to being removed or unbound.
|
||||
*/
|
||||
int fw_card_read_cycle_time(struct fw_card *card, u32 *cycle_time)
|
||||
{
|
||||
if (card->driver->read_csr == dummy_read_csr)
|
||||
return -ENODEV;
|
||||
|
||||
// It's possible to switch to dummy driver between the above and the below. This is the best
|
||||
// effort to return -ENODEV.
|
||||
*cycle_time = card->driver->read_csr(card, CSR_CYCLE_TIME);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fw_card_read_cycle_time);
|
||||
|
@ -1216,7 +1216,9 @@ static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
cycle_time = card->driver->read_csr(card, CSR_CYCLE_TIME);
|
||||
ret = fw_card_read_cycle_time(card, &cycle_time);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
switch (a->clk_id) {
|
||||
case CLOCK_REALTIME: ktime_get_real_ts64(&ts); break;
|
||||
@ -1225,7 +1227,7 @@ static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
end:
|
||||
local_irq_enable();
|
||||
|
||||
a->tv_sec = ts.tv_sec;
|
||||
|
@ -620,6 +620,7 @@ struct fw_request {
|
||||
struct fw_packet response;
|
||||
u32 request_header[4];
|
||||
int ack;
|
||||
u32 timestamp;
|
||||
u32 length;
|
||||
u32 data[];
|
||||
};
|
||||
@ -789,6 +790,7 @@ static struct fw_request *allocate_request(struct fw_card *card,
|
||||
request->response.ack = 0;
|
||||
request->response.callback = free_response_callback;
|
||||
request->ack = p->ack;
|
||||
request->timestamp = p->timestamp;
|
||||
request->length = length;
|
||||
if (data)
|
||||
memcpy(request->data, data, length);
|
||||
@ -833,6 +835,22 @@ int fw_get_request_speed(struct fw_request *request)
|
||||
}
|
||||
EXPORT_SYMBOL(fw_get_request_speed);
|
||||
|
||||
/**
|
||||
* fw_request_get_timestamp: Get timestamp of the request.
|
||||
* @request: The opaque pointer to request structure.
|
||||
*
|
||||
* Get timestamp when 1394 OHCI controller receives the asynchronous request subaction. The
|
||||
* timestamp consists of the low order 3 bits of second field and the full 13 bits of count
|
||||
* field of isochronous cycle time register.
|
||||
*
|
||||
* Returns: timestamp of the request.
|
||||
*/
|
||||
u32 fw_request_get_timestamp(const struct fw_request *request)
|
||||
{
|
||||
return request->timestamp;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fw_request_get_timestamp);
|
||||
|
||||
static void handle_exclusive_region_request(struct fw_card *card,
|
||||
struct fw_packet *p,
|
||||
struct fw_request *request,
|
||||
|
@ -203,6 +203,15 @@ config INTEL_STRATIX10_RSU
|
||||
|
||||
Say Y here if you want Intel RSU support.
|
||||
|
||||
config MTK_ADSP_IPC
|
||||
tristate "MTK ADSP IPC Protocol driver"
|
||||
depends on MTK_ADSP_MBOX
|
||||
help
|
||||
Say yes here to add support for the MediaTek ADSP IPC
|
||||
between host AP (Linux) and the firmware running on ADSP.
|
||||
ADSP exists on some mtk processors.
|
||||
Client might use shared memory to exchange information with ADSP.
|
||||
|
||||
config QCOM_SCM
|
||||
tristate
|
||||
|
||||
|
@ -15,6 +15,7 @@ obj-$(CONFIG_INTEL_STRATIX10_RSU) += stratix10-rsu.o
|
||||
obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
|
||||
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
|
||||
obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
|
||||
obj-$(CONFIG_MTK_ADSP_IPC) += mtk-adsp-ipc.o
|
||||
obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
|
||||
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
|
||||
obj-$(CONFIG_QCOM_SCM) += qcom-scm.o
|
||||
|
157
drivers/firmware/mtk-adsp-ipc.c
Normal file
157
drivers/firmware/mtk-adsp-ipc.c
Normal file
@ -0,0 +1,157 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022 MediaTek Corporation. All rights reserved.
|
||||
* Author: Allen-KH Cheng <allen-kh.cheng@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/*
|
||||
* mtk_adsp_ipc_send - send ipc cmd to MTK ADSP
|
||||
*
|
||||
* @ipc: ADSP IPC handle
|
||||
* @idx: index of the mailbox channel
|
||||
* @msg: IPC cmd (reply or request)
|
||||
*
|
||||
* Returns zero for success from mbox_send_message
|
||||
* negative value for error
|
||||
*/
|
||||
int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
|
||||
{
|
||||
struct mtk_adsp_chan *adsp_chan;
|
||||
int ret;
|
||||
|
||||
if (idx >= MTK_ADSP_MBOX_NUM)
|
||||
return -EINVAL;
|
||||
|
||||
adsp_chan = &ipc->chans[idx];
|
||||
ret = mbox_send_message(adsp_chan->ch, &msg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mtk_adsp_ipc_send);
|
||||
|
||||
/*
|
||||
* mtk_adsp_ipc_recv - recv callback used by MTK ADSP mailbox
|
||||
*
|
||||
* @c: mbox client
|
||||
* @msg: message received
|
||||
*
|
||||
* Users of ADSP IPC will need to privde handle_reply and handle_request
|
||||
* callbacks.
|
||||
*/
|
||||
static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
|
||||
{
|
||||
struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
|
||||
struct device *dev = c->dev;
|
||||
|
||||
switch (chan->idx) {
|
||||
case MTK_ADSP_MBOX_REPLY:
|
||||
chan->ipc->ops->handle_reply(chan->ipc);
|
||||
break;
|
||||
case MTK_ADSP_MBOX_REQUEST:
|
||||
chan->ipc->ops->handle_request(chan->ipc);
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "wrong mbox chan %d\n", chan->idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int mtk_adsp_ipc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mtk_adsp_ipc *adsp_ipc;
|
||||
struct mtk_adsp_chan *adsp_chan;
|
||||
struct mbox_client *cl;
|
||||
char *chan_name;
|
||||
int ret;
|
||||
int i, j;
|
||||
|
||||
device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
|
||||
|
||||
adsp_ipc = devm_kzalloc(dev, sizeof(*adsp_ipc), GFP_KERNEL);
|
||||
if (!adsp_ipc)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
|
||||
chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
|
||||
if (!chan_name) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
adsp_chan = &adsp_ipc->chans[i];
|
||||
cl = &adsp_chan->cl;
|
||||
cl->dev = dev->parent;
|
||||
cl->tx_block = false;
|
||||
cl->knows_txdone = false;
|
||||
cl->tx_prepare = NULL;
|
||||
cl->rx_callback = mtk_adsp_ipc_recv;
|
||||
|
||||
adsp_chan->ipc = adsp_ipc;
|
||||
adsp_chan->idx = i;
|
||||
adsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
|
||||
if (IS_ERR(adsp_chan->ch)) {
|
||||
ret = PTR_ERR(adsp_chan->ch);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "Failed to request mbox chan %d ret %d\n",
|
||||
i, ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "request mbox chan %s\n", chan_name);
|
||||
kfree(chan_name);
|
||||
}
|
||||
|
||||
adsp_ipc->dev = dev;
|
||||
dev_set_drvdata(dev, adsp_ipc);
|
||||
dev_dbg(dev, "MTK ADSP IPC initialized\n");
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
kfree(chan_name);
|
||||
out:
|
||||
for (j = 0; j < i; j++) {
|
||||
adsp_chan = &adsp_ipc->chans[j];
|
||||
mbox_free_channel(adsp_chan->ch);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mtk_adsp_ipc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mtk_adsp_ipc *adsp_ipc = dev_get_drvdata(&pdev->dev);
|
||||
struct mtk_adsp_chan *adsp_chan;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
|
||||
adsp_chan = &adsp_ipc->chans[i];
|
||||
mbox_free_channel(adsp_chan->ch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mtk_adsp_ipc_driver = {
|
||||
.driver = {
|
||||
.name = "mtk-adsp-ipc",
|
||||
},
|
||||
.probe = mtk_adsp_ipc_probe,
|
||||
.remove = mtk_adsp_ipc_remove,
|
||||
};
|
||||
builtin_platform_driver(mtk_adsp_ipc_driver);
|
||||
|
||||
MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng@mediatek.com>");
|
||||
MODULE_DESCRIPTION("MTK ADSP IPC Driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -39,7 +39,7 @@
|
||||
#include <asm/irq.h>
|
||||
#include <linux/platform_data/mmc-mxcmmc.h>
|
||||
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <linux/dma/imx-dma.h>
|
||||
|
||||
#define DRIVER_NAME "mxc-mmc"
|
||||
#define MXCMCI_TIMEOUT_MS 10000
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <linux/dma/imx-dma.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <linux/dma/imx-dma.h>
|
||||
|
||||
#define DRIVER_NAME "spi_imx"
|
||||
|
||||
|
@ -702,8 +702,9 @@ static int gbaudio_init_jack(struct gbaudio_module_info *module,
|
||||
|
||||
headset->pin = module->jack_name;
|
||||
headset->mask = module->jack_mask;
|
||||
ret = snd_soc_card_jack_new(card, module->jack_name, module->jack_mask,
|
||||
&module->headset.jack, headset, 1);
|
||||
ret = snd_soc_card_jack_new_pins(card, module->jack_name,
|
||||
module->jack_mask,
|
||||
&module->headset.jack, headset, 1);
|
||||
if (ret) {
|
||||
dev_err(module->dev, "Failed to create new jack\n");
|
||||
return ret;
|
||||
@ -725,9 +726,10 @@ static int gbaudio_init_jack(struct gbaudio_module_info *module,
|
||||
|
||||
button->pin = module->button_name;
|
||||
button->mask = module->button_mask;
|
||||
ret = snd_soc_card_jack_new(card, module->button_name,
|
||||
module->button_mask, &module->button.jack,
|
||||
button, 1);
|
||||
ret = snd_soc_card_jack_new_pins(card, module->button_name,
|
||||
module->button_mask,
|
||||
&module->button.jack,
|
||||
button, 1);
|
||||
if (ret) {
|
||||
dev_err(module->dev, "Failed to create button jack\n");
|
||||
goto free_jacks;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <linux/dma/imx-dma.h>
|
||||
|
||||
#include "serial_mctrl_gpio.h"
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <linux/dma/ipu-dma.h>
|
||||
#include <linux/backlight.h>
|
||||
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <linux/dma/imx-dma.h>
|
||||
#include <linux/platform_data/video-mx3fb.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
20
include/dt-bindings/sound/cs35l45.h
Normal file
20
include/dt-bindings/sound/cs35l45.h
Normal file
@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* cs35l45.h -- CS35L45 ALSA SoC audio driver DT bindings header
|
||||
*
|
||||
* Copyright 2022 Cirrus Logic, Inc.
|
||||
*/
|
||||
|
||||
#ifndef DT_CS35L45_H
|
||||
#define DT_CS35L45_H
|
||||
|
||||
/*
|
||||
* cirrus,asp-sdout-hiz-ctrl
|
||||
*
|
||||
* TX_HIZ_UNUSED: TX pin high-impedance during unused slots.
|
||||
* TX_HIZ_DISABLED: TX pin high-impedance when all channels disabled.
|
||||
*/
|
||||
#define CS35L45_ASP_TX_HIZ_UNUSED 0x1
|
||||
#define CS35L45_ASP_TX_HIZ_DISABLED 0x2
|
||||
|
||||
#endif /* DT_CS35L45_H */
|
@ -3,8 +3,8 @@
|
||||
* Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_MXC_DMA_H__
|
||||
#define __ASM_ARCH_MXC_DMA_H__
|
||||
#ifndef __LINUX_DMA_IMX_H
|
||||
#define __LINUX_DMA_IMX_H
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/device.h>
|
||||
@ -39,6 +39,7 @@ enum sdma_peripheral_type {
|
||||
IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
|
||||
IMX_DMATYPE_ASRC_SP, /* Shared ASRC */
|
||||
IMX_DMATYPE_SAI, /* SAI */
|
||||
IMX_DMATYPE_MULTI_SAI, /* MULTI FIFOs For Audio */
|
||||
};
|
||||
|
||||
enum imx_dma_prio {
|
||||
@ -65,4 +66,23 @@ static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
|
||||
!strcmp(chan->device->dev->driver->name, "imx-dma");
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* struct sdma_peripheral_config - SDMA config for audio
|
||||
* @n_fifos_src: Number of FIFOs for recording
|
||||
* @n_fifos_dst: Number of FIFOs for playback
|
||||
* @sw_done: Use software done. Needed for PDM (micfil)
|
||||
*
|
||||
* Some i.MX Audio devices (SAI, micfil) have multiple successive FIFO
|
||||
* registers. For multichannel recording/playback the SAI/micfil have
|
||||
* one FIFO register per channel and the SDMA engine has to read/write
|
||||
* the next channel from/to the next register and wrap around to the
|
||||
* first register when all channels are handled. The number of active
|
||||
* channels must be communicated to the SDMA engine using this struct.
|
||||
*/
|
||||
struct sdma_peripheral_config {
|
||||
int n_fifos_src;
|
||||
int n_fifos_dst;
|
||||
bool sw_done;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_DMA_IMX_H */
|
@ -150,6 +150,8 @@ static inline void fw_card_put(struct fw_card *card)
|
||||
kref_put(&card->kref, fw_card_release);
|
||||
}
|
||||
|
||||
int fw_card_read_cycle_time(struct fw_card *card, u32 *cycle_time);
|
||||
|
||||
struct fw_attribute_group {
|
||||
struct attribute_group *groups[2];
|
||||
struct attribute_group group;
|
||||
@ -352,6 +354,7 @@ void fw_core_remove_address_handler(struct fw_address_handler *handler);
|
||||
void fw_send_response(struct fw_card *card,
|
||||
struct fw_request *request, int rcode);
|
||||
int fw_get_request_speed(struct fw_request *request);
|
||||
u32 fw_request_get_timestamp(const struct fw_request *request);
|
||||
void fw_send_request(struct fw_card *card, struct fw_transaction *t,
|
||||
int tcode, int destination_id, int generation, int speed,
|
||||
unsigned long long offset, void *payload, size_t length,
|
||||
|
@ -68,36 +68,36 @@ struct cs_dsp_alg_region {
|
||||
|
||||
/**
|
||||
* struct cs_dsp_coeff_ctl - Describes a coefficient control
|
||||
* @list: List node for internal use
|
||||
* @dsp: DSP instance associated with this control
|
||||
* @cache: Cached value of the control
|
||||
* @fw_name: Name of the firmware
|
||||
* @subname: Name of the control parsed from the WMFW
|
||||
* @subname_len: Length of subname
|
||||
* @alg_region: Logical region associated with this control
|
||||
* @dsp: DSP instance associated with this control
|
||||
* @enabled: Flag indicating whether control is enabled
|
||||
* @list: List node for internal use
|
||||
* @cache: Cached value of the control
|
||||
* @offset: Offset of control within alg_region in words
|
||||
* @len: Length of the cached value in bytes
|
||||
* @set: Flag indicating the value has been written by the user
|
||||
* @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h
|
||||
* @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h
|
||||
* @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h
|
||||
* @set: Flag indicating the value has been written by the user
|
||||
* @enabled: Flag indicating whether control is enabled
|
||||
* @alg_region: Logical region associated with this control
|
||||
* @priv: For use by the client
|
||||
*/
|
||||
struct cs_dsp_coeff_ctl {
|
||||
struct list_head list;
|
||||
struct cs_dsp *dsp;
|
||||
void *cache;
|
||||
const char *fw_name;
|
||||
/* Subname is needed to match with firmware */
|
||||
const char *subname;
|
||||
unsigned int subname_len;
|
||||
struct cs_dsp_alg_region alg_region;
|
||||
struct cs_dsp *dsp;
|
||||
unsigned int enabled:1;
|
||||
struct list_head list;
|
||||
void *cache;
|
||||
unsigned int offset;
|
||||
size_t len;
|
||||
unsigned int set:1;
|
||||
unsigned int flags;
|
||||
unsigned int type;
|
||||
unsigned int flags;
|
||||
unsigned int set:1;
|
||||
unsigned int enabled:1;
|
||||
struct cs_dsp_alg_region alg_region;
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
65
include/linux/firmware/mediatek/mtk-adsp-ipc.h
Normal file
65
include/linux/firmware/mediatek/mtk-adsp-ipc.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2022 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef MTK_ADSP_IPC_H
|
||||
#define MTK_ADSP_IPC_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mailbox_controller.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
|
||||
#define MTK_ADSP_IPC_REQ 0
|
||||
#define MTK_ADSP_IPC_RSP 1
|
||||
#define MTK_ADSP_IPC_OP_REQ 0x1
|
||||
#define MTK_ADSP_IPC_OP_RSP 0x2
|
||||
|
||||
enum {
|
||||
MTK_ADSP_MBOX_REPLY,
|
||||
MTK_ADSP_MBOX_REQUEST,
|
||||
MTK_ADSP_MBOX_NUM,
|
||||
};
|
||||
|
||||
struct mtk_adsp_ipc;
|
||||
|
||||
struct mtk_adsp_ipc_ops {
|
||||
void (*handle_reply)(struct mtk_adsp_ipc *ipc);
|
||||
void (*handle_request)(struct mtk_adsp_ipc *ipc);
|
||||
};
|
||||
|
||||
struct mtk_adsp_chan {
|
||||
struct mtk_adsp_ipc *ipc;
|
||||
struct mbox_client cl;
|
||||
struct mbox_chan *ch;
|
||||
char *name;
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct mtk_adsp_ipc {
|
||||
struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
|
||||
struct device *dev;
|
||||
struct mtk_adsp_ipc_ops *ops;
|
||||
void *private_data;
|
||||
};
|
||||
|
||||
static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
|
||||
{
|
||||
if (!ipc)
|
||||
return;
|
||||
|
||||
ipc->private_data = data;
|
||||
}
|
||||
|
||||
static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
|
||||
{
|
||||
if (!ipc)
|
||||
return NULL;
|
||||
|
||||
return ipc->private_data;
|
||||
}
|
||||
|
||||
int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
|
||||
|
||||
#endif /* MTK_ADSP_IPC_H */
|
@ -11,6 +11,7 @@
|
||||
#define __CS35L41_H
|
||||
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/firmware/cirrus/cs_dsp.h>
|
||||
|
||||
#define CS35L41_FIRSTREG 0x00000000
|
||||
#define CS35L41_LASTREG 0x03804FE8
|
||||
@ -536,9 +537,7 @@
|
||||
|
||||
#define CS35L41_MAX_CACHE_REG 36
|
||||
#define CS35L41_OTP_SIZE_WORDS 32
|
||||
#define CS35L41_NUM_OTP_ELEM 100
|
||||
|
||||
#define CS35L41_VALID_PDATA 0x80000000
|
||||
#define CS35L41_NUM_SUPPLIES 2
|
||||
|
||||
#define CS35L41_SCLK_MSTR_MASK 0x10
|
||||
@ -662,6 +661,7 @@
|
||||
#define CS35L41_GLOBAL_EN_SHIFT 0
|
||||
#define CS35L41_BST_EN_MASK 0x0030
|
||||
#define CS35L41_BST_EN_SHIFT 4
|
||||
#define CS35L41_BST_DIS_FET_OFF 0x00
|
||||
#define CS35L41_BST_EN_DEFAULT 0x2
|
||||
#define CS35L41_AMP_EN_SHIFT 0
|
||||
#define CS35L41_AMP_EN_MASK 1
|
||||
@ -691,6 +691,13 @@
|
||||
#define CS35L41_TEMP_WARN_ERR_RLS 0x20
|
||||
#define CS35L41_TEMP_ERR_RLS 0x40
|
||||
|
||||
#define CS35L41_AMP_SHORT_ERR_RLS_SHIFT 1
|
||||
#define CS35L41_BST_SHORT_ERR_RLS_SHIFT 2
|
||||
#define CS35L41_BST_OVP_ERR_RLS_SHIFT 3
|
||||
#define CS35L41_BST_UVP_ERR_RLS_SHIFT 4
|
||||
#define CS35L41_TEMP_WARN_ERR_RLS_SHIFT 5
|
||||
#define CS35L41_TEMP_ERR_RLS_SHIFT 6
|
||||
|
||||
#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F
|
||||
#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF
|
||||
#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF
|
||||
@ -701,9 +708,8 @@
|
||||
#define CS35L41_GPIO1_CTRL_SHIFT 16
|
||||
#define CS35L41_GPIO2_CTRL_MASK 0x07000000
|
||||
#define CS35L41_GPIO2_CTRL_SHIFT 24
|
||||
#define CS35L41_GPIO_CTRL_OPEN_INT 2
|
||||
#define CS35L41_GPIO_CTRL_ACTV_LO 4
|
||||
#define CS35L41_GPIO_CTRL_ACTV_HI 5
|
||||
#define CS35L41_GPIO_LVL_SHIFT 15
|
||||
#define CS35L41_GPIO_LVL_MASK BIT(CS35L41_GPIO_LVL_SHIFT)
|
||||
#define CS35L41_GPIO_POL_MASK 0x1000
|
||||
#define CS35L41_GPIO_POL_SHIFT 12
|
||||
|
||||
@ -729,25 +735,56 @@
|
||||
#define CS35L41_SPI_MAX_FREQ 4000000
|
||||
#define CS35L41_REGSTRIDE 4
|
||||
|
||||
enum cs35l41_boost_type {
|
||||
CS35L41_INT_BOOST,
|
||||
CS35L41_EXT_BOOST,
|
||||
CS35L41_EXT_BOOST_NO_VSPK_SWITCH,
|
||||
};
|
||||
|
||||
enum cs35l41_clk_ids {
|
||||
CS35L41_CLKID_SCLK = 0,
|
||||
CS35L41_CLKID_LRCLK = 1,
|
||||
CS35L41_CLKID_MCLK = 4,
|
||||
};
|
||||
|
||||
struct cs35l41_irq_cfg {
|
||||
bool irq_pol_inv;
|
||||
bool irq_out_en;
|
||||
int irq_src_sel;
|
||||
enum cs35l41_gpio1_func {
|
||||
CS35L41_GPIO1_HIZ,
|
||||
CS35L41_GPIO1_GPIO,
|
||||
CS35L41_GPIO1_MDSYNC,
|
||||
CS35L41_GPIO1_MCLK,
|
||||
CS35L41_GPIO1_PDM_CLK,
|
||||
CS35L41_GPIO1_PDM_DATA,
|
||||
};
|
||||
|
||||
struct cs35l41_platform_data {
|
||||
enum cs35l41_gpio2_func {
|
||||
CS35L41_GPIO2_HIZ,
|
||||
CS35L41_GPIO2_GPIO,
|
||||
CS35L41_GPIO2_INT_OPEN_DRAIN,
|
||||
CS35L41_GPIO2_MCLK,
|
||||
CS35L41_GPIO2_INT_PUSH_PULL_LOW,
|
||||
CS35L41_GPIO2_INT_PUSH_PULL_HIGH,
|
||||
CS35L41_GPIO2_PDM_CLK,
|
||||
CS35L41_GPIO2_PDM_DATA,
|
||||
};
|
||||
|
||||
struct cs35l41_gpio_cfg {
|
||||
bool valid;
|
||||
bool pol_inv;
|
||||
bool out_en;
|
||||
unsigned int func;
|
||||
};
|
||||
|
||||
struct cs35l41_hw_cfg {
|
||||
bool valid;
|
||||
int bst_ind;
|
||||
int bst_ipk;
|
||||
int bst_cap;
|
||||
int dout_hiz;
|
||||
struct cs35l41_irq_cfg irq_config1;
|
||||
struct cs35l41_irq_cfg irq_config2;
|
||||
struct cs35l41_gpio_cfg gpio1;
|
||||
struct cs35l41_gpio_cfg gpio2;
|
||||
unsigned int spk_pos;
|
||||
|
||||
enum cs35l41_boost_type bst_type;
|
||||
};
|
||||
|
||||
struct cs35l41_otp_packed_element_t {
|
||||
@ -764,6 +801,71 @@ struct cs35l41_otp_map_element_t {
|
||||
u32 word_offset;
|
||||
};
|
||||
|
||||
enum cs35l41_cspl_mbox_status {
|
||||
CSPL_MBOX_STS_RUNNING = 0,
|
||||
CSPL_MBOX_STS_PAUSED = 1,
|
||||
CSPL_MBOX_STS_RDY_FOR_REINIT = 2,
|
||||
};
|
||||
|
||||
enum cs35l41_cspl_mbox_cmd {
|
||||
CSPL_MBOX_CMD_NONE = 0,
|
||||
CSPL_MBOX_CMD_PAUSE = 1,
|
||||
CSPL_MBOX_CMD_RESUME = 2,
|
||||
CSPL_MBOX_CMD_REINIT = 3,
|
||||
CSPL_MBOX_CMD_STOP_PRE_REINIT = 4,
|
||||
CSPL_MBOX_CMD_HIBERNATE = 5,
|
||||
CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6,
|
||||
CSPL_MBOX_CMD_UNKNOWN_CMD = -1,
|
||||
CSPL_MBOX_CMD_INVALID_SEQUENCE = -2,
|
||||
};
|
||||
|
||||
/*
|
||||
* IRQs
|
||||
*/
|
||||
#define CS35L41_IRQ(_irq, _name, _hand) \
|
||||
{ \
|
||||
.irq = CS35L41_ ## _irq ## _IRQ,\
|
||||
.name = _name, \
|
||||
.handler = _hand, \
|
||||
}
|
||||
|
||||
struct cs35l41_irq {
|
||||
int irq;
|
||||
const char *name;
|
||||
irqreturn_t (*handler)(int irq, void *data);
|
||||
};
|
||||
|
||||
#define CS35L41_REG_IRQ(_reg, _irq) \
|
||||
[CS35L41_ ## _irq ## _IRQ] = { \
|
||||
.reg_offset = (CS35L41_ ## _reg) - CS35L41_IRQ1_STATUS1,\
|
||||
.mask = CS35L41_ ## _irq ## _MASK \
|
||||
}
|
||||
|
||||
/* (0x0000E010) CS35L41_IRQ1_STATUS1 */
|
||||
#define CS35L41_BST_OVP_ERR_SHIFT 6
|
||||
#define CS35L41_BST_OVP_ERR_MASK BIT(CS35L41_BST_OVP_ERR_SHIFT)
|
||||
#define CS35L41_BST_DCM_UVP_ERR_SHIFT 7
|
||||
#define CS35L41_BST_DCM_UVP_ERR_MASK BIT(CS35L41_BST_DCM_UVP_ERR_SHIFT)
|
||||
#define CS35L41_BST_SHORT_ERR_SHIFT 8
|
||||
#define CS35L41_BST_SHORT_ERR_MASK BIT(CS35L41_BST_SHORT_ERR_SHIFT)
|
||||
#define CS35L41_TEMP_WARN_SHIFT 15
|
||||
#define CS35L41_TEMP_WARN_MASK BIT(CS35L41_TEMP_WARN_SHIFT)
|
||||
#define CS35L41_TEMP_ERR_SHIFT 17
|
||||
#define CS35L41_TEMP_ERR_MASK BIT(CS35L41_TEMP_ERR_SHIFT)
|
||||
#define CS35L41_AMP_SHORT_ERR_SHIFT 31
|
||||
#define CS35L41_AMP_SHORT_ERR_MASK BIT(CS35L41_AMP_SHORT_ERR_SHIFT)
|
||||
|
||||
enum cs35l41_irq_list {
|
||||
CS35L41_BST_OVP_ERR_IRQ,
|
||||
CS35L41_BST_DCM_UVP_ERR_IRQ,
|
||||
CS35L41_BST_SHORT_ERR_IRQ,
|
||||
CS35L41_TEMP_WARN_IRQ,
|
||||
CS35L41_TEMP_ERR_IRQ,
|
||||
CS35L41_AMP_SHORT_ERR_IRQ,
|
||||
|
||||
CS35L41_NUM_IRQ
|
||||
};
|
||||
|
||||
extern struct regmap_config cs35l41_regmap_i2c;
|
||||
extern struct regmap_config cs35l41_regmap_spi;
|
||||
|
||||
@ -774,7 +876,14 @@ int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsign
|
||||
int cs35l41_set_channels(struct device *dev, struct regmap *reg,
|
||||
unsigned int tx_num, unsigned int *tx_slot,
|
||||
unsigned int rx_num, unsigned int *rx_slot);
|
||||
int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap,
|
||||
int boost_ipk);
|
||||
int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg);
|
||||
void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_dsp *dsp);
|
||||
int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap,
|
||||
enum cs35l41_cspl_mbox_cmd cmd);
|
||||
int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap);
|
||||
int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
|
||||
struct cs35l41_hw_cfg *hw_cfg);
|
||||
bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);
|
||||
int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable);
|
||||
|
||||
#endif /* __CS35L41_H */
|
||||
|
810
include/sound/cs42l42.h
Normal file
810
include/sound/cs42l42.h
Normal file
@ -0,0 +1,810 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* linux/sound/cs42l42.h -- Platform data for CS42L42 ALSA SoC audio driver header
|
||||
*
|
||||
* Copyright 2016-2022 Cirrus Logic, Inc.
|
||||
*
|
||||
* Author: James Schulman <james.schulman@cirrus.com>
|
||||
* Author: Brian Austin <brian.austin@cirrus.com>
|
||||
* Author: Michael White <michael.white@cirrus.com>
|
||||
*/
|
||||
|
||||
#ifndef __CS42L42_H
|
||||
#define __CS42L42_H
|
||||
|
||||
#define CS42L42_PAGE_REGISTER 0x00 /* Page Select Register */
|
||||
#define CS42L42_WIN_START 0x00
|
||||
#define CS42L42_WIN_LEN 0x100
|
||||
#define CS42L42_RANGE_MIN 0x00
|
||||
#define CS42L42_RANGE_MAX 0x7F
|
||||
|
||||
#define CS42L42_PAGE_10 0x1000
|
||||
#define CS42L42_PAGE_11 0x1100
|
||||
#define CS42L42_PAGE_12 0x1200
|
||||
#define CS42L42_PAGE_13 0x1300
|
||||
#define CS42L42_PAGE_15 0x1500
|
||||
#define CS42L42_PAGE_19 0x1900
|
||||
#define CS42L42_PAGE_1B 0x1B00
|
||||
#define CS42L42_PAGE_1C 0x1C00
|
||||
#define CS42L42_PAGE_1D 0x1D00
|
||||
#define CS42L42_PAGE_1F 0x1F00
|
||||
#define CS42L42_PAGE_20 0x2000
|
||||
#define CS42L42_PAGE_21 0x2100
|
||||
#define CS42L42_PAGE_23 0x2300
|
||||
#define CS42L42_PAGE_24 0x2400
|
||||
#define CS42L42_PAGE_25 0x2500
|
||||
#define CS42L42_PAGE_26 0x2600
|
||||
#define CS42L42_PAGE_28 0x2800
|
||||
#define CS42L42_PAGE_29 0x2900
|
||||
#define CS42L42_PAGE_2A 0x2A00
|
||||
#define CS42L42_PAGE_30 0x3000
|
||||
|
||||
#define CS42L42_CHIP_ID 0x42A42
|
||||
|
||||
/* Page 0x10 Global Registers */
|
||||
#define CS42L42_DEVID_AB (CS42L42_PAGE_10 + 0x01)
|
||||
#define CS42L42_DEVID_CD (CS42L42_PAGE_10 + 0x02)
|
||||
#define CS42L42_DEVID_E (CS42L42_PAGE_10 + 0x03)
|
||||
#define CS42L42_FABID (CS42L42_PAGE_10 + 0x04)
|
||||
#define CS42L42_REVID (CS42L42_PAGE_10 + 0x05)
|
||||
#define CS42L42_FRZ_CTL (CS42L42_PAGE_10 + 0x06)
|
||||
|
||||
#define CS42L42_SRC_CTL (CS42L42_PAGE_10 + 0x07)
|
||||
#define CS42L42_SRC_BYPASS_DAC_SHIFT 1
|
||||
#define CS42L42_SRC_BYPASS_DAC_MASK (1 << CS42L42_SRC_BYPASS_DAC_SHIFT)
|
||||
|
||||
#define CS42L42_MCLK_STATUS (CS42L42_PAGE_10 + 0x08)
|
||||
|
||||
#define CS42L42_MCLK_CTL (CS42L42_PAGE_10 + 0x09)
|
||||
#define CS42L42_INTERNAL_FS_SHIFT 1
|
||||
#define CS42L42_INTERNAL_FS_MASK (1 << CS42L42_INTERNAL_FS_SHIFT)
|
||||
|
||||
#define CS42L42_SFTRAMP_RATE (CS42L42_PAGE_10 + 0x0A)
|
||||
#define CS42L42_SLOW_START_ENABLE (CS42L42_PAGE_10 + 0x0B)
|
||||
#define CS42L42_SLOW_START_EN_MASK GENMASK(6, 4)
|
||||
#define CS42L42_SLOW_START_EN_SHIFT 4
|
||||
#define CS42L42_I2C_DEBOUNCE (CS42L42_PAGE_10 + 0x0E)
|
||||
#define CS42L42_I2C_STRETCH (CS42L42_PAGE_10 + 0x0F)
|
||||
#define CS42L42_I2C_TIMEOUT (CS42L42_PAGE_10 + 0x10)
|
||||
|
||||
/* Page 0x11 Power and Headset Detect Registers */
|
||||
#define CS42L42_PWR_CTL1 (CS42L42_PAGE_11 + 0x01)
|
||||
#define CS42L42_ASP_DAO_PDN_SHIFT 7
|
||||
#define CS42L42_ASP_DAO_PDN_MASK (1 << CS42L42_ASP_DAO_PDN_SHIFT)
|
||||
#define CS42L42_ASP_DAI_PDN_SHIFT 6
|
||||
#define CS42L42_ASP_DAI_PDN_MASK (1 << CS42L42_ASP_DAI_PDN_SHIFT)
|
||||
#define CS42L42_MIXER_PDN_SHIFT 5
|
||||
#define CS42L42_MIXER_PDN_MASK (1 << CS42L42_MIXER_PDN_SHIFT)
|
||||
#define CS42L42_EQ_PDN_SHIFT 4
|
||||
#define CS42L42_EQ_PDN_MASK (1 << CS42L42_EQ_PDN_SHIFT)
|
||||
#define CS42L42_HP_PDN_SHIFT 3
|
||||
#define CS42L42_HP_PDN_MASK (1 << CS42L42_HP_PDN_SHIFT)
|
||||
#define CS42L42_ADC_PDN_SHIFT 2
|
||||
#define CS42L42_ADC_PDN_MASK (1 << CS42L42_ADC_PDN_SHIFT)
|
||||
#define CS42L42_PDN_ALL_SHIFT 0
|
||||
#define CS42L42_PDN_ALL_MASK (1 << CS42L42_PDN_ALL_SHIFT)
|
||||
|
||||
#define CS42L42_PWR_CTL2 (CS42L42_PAGE_11 + 0x02)
|
||||
#define CS42L42_ADC_SRC_PDNB_SHIFT 0
|
||||
#define CS42L42_ADC_SRC_PDNB_MASK (1 << CS42L42_ADC_SRC_PDNB_SHIFT)
|
||||
#define CS42L42_DAC_SRC_PDNB_SHIFT 1
|
||||
#define CS42L42_DAC_SRC_PDNB_MASK (1 << CS42L42_DAC_SRC_PDNB_SHIFT)
|
||||
#define CS42L42_ASP_DAI1_PDN_SHIFT 2
|
||||
#define CS42L42_ASP_DAI1_PDN_MASK (1 << CS42L42_ASP_DAI1_PDN_SHIFT)
|
||||
#define CS42L42_SRC_PDN_OVERRIDE_SHIFT 3
|
||||
#define CS42L42_SRC_PDN_OVERRIDE_MASK (1 << CS42L42_SRC_PDN_OVERRIDE_SHIFT)
|
||||
#define CS42L42_DISCHARGE_FILT_SHIFT 4
|
||||
#define CS42L42_DISCHARGE_FILT_MASK (1 << CS42L42_DISCHARGE_FILT_SHIFT)
|
||||
|
||||
#define CS42L42_PWR_CTL3 (CS42L42_PAGE_11 + 0x03)
|
||||
#define CS42L42_RING_SENSE_PDNB_SHIFT 1
|
||||
#define CS42L42_RING_SENSE_PDNB_MASK (1 << CS42L42_RING_SENSE_PDNB_SHIFT)
|
||||
#define CS42L42_VPMON_PDNB_SHIFT 2
|
||||
#define CS42L42_VPMON_PDNB_MASK (1 << CS42L42_VPMON_PDNB_SHIFT)
|
||||
#define CS42L42_SW_CLK_STP_STAT_SEL_SHIFT 5
|
||||
#define CS42L42_SW_CLK_STP_STAT_SEL_MASK (3 << CS42L42_SW_CLK_STP_STAT_SEL_SHIFT)
|
||||
|
||||
#define CS42L42_RSENSE_CTL1 (CS42L42_PAGE_11 + 0x04)
|
||||
#define CS42L42_RS_TRIM_R_SHIFT 0
|
||||
#define CS42L42_RS_TRIM_R_MASK (1 << CS42L42_RS_TRIM_R_SHIFT)
|
||||
#define CS42L42_RS_TRIM_T_SHIFT 1
|
||||
#define CS42L42_RS_TRIM_T_MASK (1 << CS42L42_RS_TRIM_T_SHIFT)
|
||||
#define CS42L42_HPREF_RS_SHIFT 2
|
||||
#define CS42L42_HPREF_RS_MASK (1 << CS42L42_HPREF_RS_SHIFT)
|
||||
#define CS42L42_HSBIAS_FILT_REF_RS_SHIFT 3
|
||||
#define CS42L42_HSBIAS_FILT_REF_RS_MASK (1 << CS42L42_HSBIAS_FILT_REF_RS_SHIFT)
|
||||
#define CS42L42_RING_SENSE_PU_HIZ_SHIFT 6
|
||||
#define CS42L42_RING_SENSE_PU_HIZ_MASK (1 << CS42L42_RING_SENSE_PU_HIZ_SHIFT)
|
||||
|
||||
#define CS42L42_RSENSE_CTL2 (CS42L42_PAGE_11 + 0x05)
|
||||
#define CS42L42_TS_RS_GATE_SHIFT 7
|
||||
#define CS42L42_TS_RS_GATE_MAS (1 << CS42L42_TS_RS_GATE_SHIFT)
|
||||
|
||||
#define CS42L42_OSC_SWITCH (CS42L42_PAGE_11 + 0x07)
|
||||
#define CS42L42_SCLK_PRESENT_SHIFT 0
|
||||
#define CS42L42_SCLK_PRESENT_MASK (1 << CS42L42_SCLK_PRESENT_SHIFT)
|
||||
|
||||
#define CS42L42_OSC_SWITCH_STATUS (CS42L42_PAGE_11 + 0x09)
|
||||
#define CS42L42_OSC_SW_SEL_STAT_SHIFT 0
|
||||
#define CS42L42_OSC_SW_SEL_STAT_MASK (3 << CS42L42_OSC_SW_SEL_STAT_SHIFT)
|
||||
#define CS42L42_OSC_PDNB_STAT_SHIFT 2
|
||||
#define CS42L42_OSC_PDNB_STAT_MASK (1 << CS42L42_OSC_SW_SEL_STAT_SHIFT)
|
||||
|
||||
#define CS42L42_RSENSE_CTL3 (CS42L42_PAGE_11 + 0x12)
|
||||
#define CS42L42_RS_RISE_DBNCE_TIME_SHIFT 0
|
||||
#define CS42L42_RS_RISE_DBNCE_TIME_MASK (7 << CS42L42_RS_RISE_DBNCE_TIME_SHIFT)
|
||||
#define CS42L42_RS_FALL_DBNCE_TIME_SHIFT 3
|
||||
#define CS42L42_RS_FALL_DBNCE_TIME_MASK (7 << CS42L42_RS_FALL_DBNCE_TIME_SHIFT)
|
||||
#define CS42L42_RS_PU_EN_SHIFT 6
|
||||
#define CS42L42_RS_PU_EN_MASK (1 << CS42L42_RS_PU_EN_SHIFT)
|
||||
#define CS42L42_RS_INV_SHIFT 7
|
||||
#define CS42L42_RS_INV_MASK (1 << CS42L42_RS_INV_SHIFT)
|
||||
|
||||
#define CS42L42_TSENSE_CTL (CS42L42_PAGE_11 + 0x13)
|
||||
#define CS42L42_TS_RISE_DBNCE_TIME_SHIFT 0
|
||||
#define CS42L42_TS_RISE_DBNCE_TIME_MASK (7 << CS42L42_TS_RISE_DBNCE_TIME_SHIFT)
|
||||
#define CS42L42_TS_FALL_DBNCE_TIME_SHIFT 3
|
||||
#define CS42L42_TS_FALL_DBNCE_TIME_MASK (7 << CS42L42_TS_FALL_DBNCE_TIME_SHIFT)
|
||||
#define CS42L42_TS_INV_SHIFT 7
|
||||
#define CS42L42_TS_INV_MASK (1 << CS42L42_TS_INV_SHIFT)
|
||||
|
||||
#define CS42L42_TSRS_INT_DISABLE (CS42L42_PAGE_11 + 0x14)
|
||||
#define CS42L42_D_RS_PLUG_DBNC_SHIFT 0
|
||||
#define CS42L42_D_RS_PLUG_DBNC_MASK (1 << CS42L42_D_RS_PLUG_DBNC_SHIFT)
|
||||
#define CS42L42_D_RS_UNPLUG_DBNC_SHIFT 1
|
||||
#define CS42L42_D_RS_UNPLUG_DBNC_MASK (1 << CS42L42_D_RS_UNPLUG_DBNC_SHIFT)
|
||||
#define CS42L42_D_TS_PLUG_DBNC_SHIFT 2
|
||||
#define CS42L42_D_TS_PLUG_DBNC_MASK (1 << CS42L42_D_TS_PLUG_DBNC_SHIFT)
|
||||
#define CS42L42_D_TS_UNPLUG_DBNC_SHIFT 3
|
||||
#define CS42L42_D_TS_UNPLUG_DBNC_MASK (1 << CS42L42_D_TS_UNPLUG_DBNC_SHIFT)
|
||||
|
||||
#define CS42L42_TRSENSE_STATUS (CS42L42_PAGE_11 + 0x15)
|
||||
#define CS42L42_RS_PLUG_DBNC_SHIFT 0
|
||||
#define CS42L42_RS_PLUG_DBNC_MASK (1 << CS42L42_RS_PLUG_DBNC_SHIFT)
|
||||
#define CS42L42_RS_UNPLUG_DBNC_SHIFT 1
|
||||
#define CS42L42_RS_UNPLUG_DBNC_MASK (1 << CS42L42_RS_UNPLUG_DBNC_SHIFT)
|
||||
#define CS42L42_TS_PLUG_DBNC_SHIFT 2
|
||||
#define CS42L42_TS_PLUG_DBNC_MASK (1 << CS42L42_TS_PLUG_DBNC_SHIFT)
|
||||
#define CS42L42_TS_UNPLUG_DBNC_SHIFT 3
|
||||
#define CS42L42_TS_UNPLUG_DBNC_MASK (1 << CS42L42_TS_UNPLUG_DBNC_SHIFT)
|
||||
|
||||
#define CS42L42_HSDET_CTL1 (CS42L42_PAGE_11 + 0x1F)
|
||||
#define CS42L42_HSDET_COMP1_LVL_SHIFT 0
|
||||
#define CS42L42_HSDET_COMP1_LVL_MASK (15 << CS42L42_HSDET_COMP1_LVL_SHIFT)
|
||||
#define CS42L42_HSDET_COMP2_LVL_SHIFT 4
|
||||
#define CS42L42_HSDET_COMP2_LVL_MASK (15 << CS42L42_HSDET_COMP2_LVL_SHIFT)
|
||||
|
||||
#define CS42L42_HSDET_COMP1_LVL_VAL 12 /* 1.25V Comparator */
|
||||
#define CS42L42_HSDET_COMP2_LVL_VAL 2 /* 1.75V Comparator */
|
||||
#define CS42L42_HSDET_COMP1_LVL_DEFAULT 7 /* 1V Comparator */
|
||||
#define CS42L42_HSDET_COMP2_LVL_DEFAULT 7 /* 2V Comparator */
|
||||
|
||||
#define CS42L42_HSDET_CTL2 (CS42L42_PAGE_11 + 0x20)
|
||||
#define CS42L42_HSDET_AUTO_TIME_SHIFT 0
|
||||
#define CS42L42_HSDET_AUTO_TIME_MASK (3 << CS42L42_HSDET_AUTO_TIME_SHIFT)
|
||||
#define CS42L42_HSBIAS_REF_SHIFT 3
|
||||
#define CS42L42_HSBIAS_REF_MASK (1 << CS42L42_HSBIAS_REF_SHIFT)
|
||||
#define CS42L42_HSDET_SET_SHIFT 4
|
||||
#define CS42L42_HSDET_SET_MASK (3 << CS42L42_HSDET_SET_SHIFT)
|
||||
#define CS42L42_HSDET_CTRL_SHIFT 6
|
||||
#define CS42L42_HSDET_CTRL_MASK (3 << CS42L42_HSDET_CTRL_SHIFT)
|
||||
|
||||
#define CS42L42_HS_SWITCH_CTL (CS42L42_PAGE_11 + 0x21)
|
||||
#define CS42L42_SW_GNDHS_HS4_SHIFT 0
|
||||
#define CS42L42_SW_GNDHS_HS4_MASK (1 << CS42L42_SW_GNDHS_HS4_SHIFT)
|
||||
#define CS42L42_SW_GNDHS_HS3_SHIFT 1
|
||||
#define CS42L42_SW_GNDHS_HS3_MASK (1 << CS42L42_SW_GNDHS_HS3_SHIFT)
|
||||
#define CS42L42_SW_HSB_HS4_SHIFT 2
|
||||
#define CS42L42_SW_HSB_HS4_MASK (1 << CS42L42_SW_HSB_HS4_SHIFT)
|
||||
#define CS42L42_SW_HSB_HS3_SHIFT 3
|
||||
#define CS42L42_SW_HSB_HS3_MASK (1 << CS42L42_SW_HSB_HS3_SHIFT)
|
||||
#define CS42L42_SW_HSB_FILT_HS4_SHIFT 4
|
||||
#define CS42L42_SW_HSB_FILT_HS4_MASK (1 << CS42L42_SW_HSB_FILT_HS4_SHIFT)
|
||||
#define CS42L42_SW_HSB_FILT_HS3_SHIFT 5
|
||||
#define CS42L42_SW_HSB_FILT_HS3_MASK (1 << CS42L42_SW_HSB_FILT_HS3_SHIFT)
|
||||
#define CS42L42_SW_REF_HS4_SHIFT 6
|
||||
#define CS42L42_SW_REF_HS4_MASK (1 << CS42L42_SW_REF_HS4_SHIFT)
|
||||
#define CS42L42_SW_REF_HS3_SHIFT 7
|
||||
#define CS42L42_SW_REF_HS3_MASK (1 << CS42L42_SW_REF_HS3_SHIFT)
|
||||
|
||||
#define CS42L42_HS_DET_STATUS (CS42L42_PAGE_11 + 0x24)
|
||||
#define CS42L42_HSDET_TYPE_SHIFT 0
|
||||
#define CS42L42_HSDET_TYPE_MASK (3 << CS42L42_HSDET_TYPE_SHIFT)
|
||||
#define CS42L42_HSDET_COMP1_OUT_SHIFT 6
|
||||
#define CS42L42_HSDET_COMP1_OUT_MASK (1 << CS42L42_HSDET_COMP1_OUT_SHIFT)
|
||||
#define CS42L42_HSDET_COMP2_OUT_SHIFT 7
|
||||
#define CS42L42_HSDET_COMP2_OUT_MASK (1 << CS42L42_HSDET_COMP2_OUT_SHIFT)
|
||||
#define CS42L42_PLUG_CTIA 0
|
||||
#define CS42L42_PLUG_OMTP 1
|
||||
#define CS42L42_PLUG_HEADPHONE 2
|
||||
#define CS42L42_PLUG_INVALID 3
|
||||
|
||||
#define CS42L42_HSDET_SW_COMP1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_REF_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_REF_HS3_SHIFT))
|
||||
#define CS42L42_HSDET_SW_COMP2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_REF_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_REF_HS3_SHIFT))
|
||||
#define CS42L42_HSDET_SW_TYPE1 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_REF_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_REF_HS3_SHIFT))
|
||||
#define CS42L42_HSDET_SW_TYPE2 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_GNDHS_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_REF_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_REF_HS3_SHIFT))
|
||||
#define CS42L42_HSDET_SW_TYPE3 ((1 << CS42L42_SW_GNDHS_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_REF_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_REF_HS3_SHIFT))
|
||||
#define CS42L42_HSDET_SW_TYPE4 ((0 << CS42L42_SW_GNDHS_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_GNDHS_HS3_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_HS4_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_HSB_FILT_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_HSB_FILT_HS3_SHIFT) | \
|
||||
(0 << CS42L42_SW_REF_HS4_SHIFT) | \
|
||||
(1 << CS42L42_SW_REF_HS3_SHIFT))
|
||||
|
||||
#define CS42L42_HSDET_COMP_TYPE1 1
|
||||
#define CS42L42_HSDET_COMP_TYPE2 2
|
||||
#define CS42L42_HSDET_COMP_TYPE3 0
|
||||
#define CS42L42_HSDET_COMP_TYPE4 3
|
||||
|
||||
#define CS42L42_HS_CLAMP_DISABLE (CS42L42_PAGE_11 + 0x29)
|
||||
#define CS42L42_HS_CLAMP_DISABLE_SHIFT 0
|
||||
#define CS42L42_HS_CLAMP_DISABLE_MASK (1 << CS42L42_HS_CLAMP_DISABLE_SHIFT)
|
||||
|
||||
/* Page 0x12 Clocking Registers */
|
||||
#define CS42L42_MCLK_SRC_SEL (CS42L42_PAGE_12 + 0x01)
|
||||
#define CS42L42_MCLKDIV_SHIFT 1
|
||||
#define CS42L42_MCLKDIV_MASK (1 << CS42L42_MCLKDIV_SHIFT)
|
||||
#define CS42L42_MCLK_SRC_SEL_SHIFT 0
|
||||
#define CS42L42_MCLK_SRC_SEL_MASK (1 << CS42L42_MCLK_SRC_SEL_SHIFT)
|
||||
|
||||
#define CS42L42_SPDIF_CLK_CFG (CS42L42_PAGE_12 + 0x02)
|
||||
#define CS42L42_FSYNC_PW_LOWER (CS42L42_PAGE_12 + 0x03)
|
||||
|
||||
#define CS42L42_FSYNC_PW_UPPER (CS42L42_PAGE_12 + 0x04)
|
||||
#define CS42L42_FSYNC_PULSE_WIDTH_SHIFT 0
|
||||
#define CS42L42_FSYNC_PULSE_WIDTH_MASK (0xff << \
|
||||
CS42L42_FSYNC_PULSE_WIDTH_SHIFT)
|
||||
|
||||
#define CS42L42_FSYNC_P_LOWER (CS42L42_PAGE_12 + 0x05)
|
||||
|
||||
#define CS42L42_FSYNC_P_UPPER (CS42L42_PAGE_12 + 0x06)
|
||||
#define CS42L42_FSYNC_PERIOD_SHIFT 0
|
||||
#define CS42L42_FSYNC_PERIOD_MASK (0xff << CS42L42_FSYNC_PERIOD_SHIFT)
|
||||
|
||||
#define CS42L42_ASP_CLK_CFG (CS42L42_PAGE_12 + 0x07)
|
||||
#define CS42L42_ASP_SCLK_EN_SHIFT 5
|
||||
#define CS42L42_ASP_SCLK_EN_MASK (1 << CS42L42_ASP_SCLK_EN_SHIFT)
|
||||
#define CS42L42_ASP_MASTER_MODE 0x01
|
||||
#define CS42L42_ASP_SLAVE_MODE 0x00
|
||||
#define CS42L42_ASP_MODE_SHIFT 4
|
||||
#define CS42L42_ASP_MODE_MASK (1 << CS42L42_ASP_MODE_SHIFT)
|
||||
#define CS42L42_ASP_SCPOL_SHIFT 2
|
||||
#define CS42L42_ASP_SCPOL_MASK (3 << CS42L42_ASP_SCPOL_SHIFT)
|
||||
#define CS42L42_ASP_SCPOL_NOR 3
|
||||
#define CS42L42_ASP_LCPOL_SHIFT 0
|
||||
#define CS42L42_ASP_LCPOL_MASK (3 << CS42L42_ASP_LCPOL_SHIFT)
|
||||
#define CS42L42_ASP_LCPOL_INV 3
|
||||
|
||||
#define CS42L42_ASP_FRM_CFG (CS42L42_PAGE_12 + 0x08)
|
||||
#define CS42L42_ASP_STP_SHIFT 4
|
||||
#define CS42L42_ASP_STP_MASK (1 << CS42L42_ASP_STP_SHIFT)
|
||||
#define CS42L42_ASP_5050_SHIFT 3
|
||||
#define CS42L42_ASP_5050_MASK (1 << CS42L42_ASP_5050_SHIFT)
|
||||
#define CS42L42_ASP_FSD_SHIFT 0
|
||||
#define CS42L42_ASP_FSD_MASK (7 << CS42L42_ASP_FSD_SHIFT)
|
||||
#define CS42L42_ASP_FSD_0_5 1
|
||||
#define CS42L42_ASP_FSD_1_0 2
|
||||
#define CS42L42_ASP_FSD_1_5 3
|
||||
#define CS42L42_ASP_FSD_2_0 4
|
||||
|
||||
#define CS42L42_FS_RATE_EN (CS42L42_PAGE_12 + 0x09)
|
||||
#define CS42L42_FS_EN_SHIFT 0
|
||||
#define CS42L42_FS_EN_MASK (0xf << CS42L42_FS_EN_SHIFT)
|
||||
#define CS42L42_FS_EN_IASRC_96K 0x1
|
||||
#define CS42L42_FS_EN_OASRC_96K 0x2
|
||||
|
||||
#define CS42L42_IN_ASRC_CLK (CS42L42_PAGE_12 + 0x0A)
|
||||
#define CS42L42_CLK_IASRC_SEL_SHIFT 0
|
||||
#define CS42L42_CLK_IASRC_SEL_MASK (1 << CS42L42_CLK_IASRC_SEL_SHIFT)
|
||||
#define CS42L42_CLK_IASRC_SEL_6 0
|
||||
#define CS42L42_CLK_IASRC_SEL_12 1
|
||||
|
||||
#define CS42L42_OUT_ASRC_CLK (CS42L42_PAGE_12 + 0x0B)
|
||||
#define CS42L42_CLK_OASRC_SEL_SHIFT 0
|
||||
#define CS42L42_CLK_OASRC_SEL_MASK (1 << CS42L42_CLK_OASRC_SEL_SHIFT)
|
||||
#define CS42L42_CLK_OASRC_SEL_12 1
|
||||
|
||||
#define CS42L42_PLL_DIV_CFG1 (CS42L42_PAGE_12 + 0x0C)
|
||||
#define CS42L42_SCLK_PREDIV_SHIFT 0
|
||||
#define CS42L42_SCLK_PREDIV_MASK (3 << CS42L42_SCLK_PREDIV_SHIFT)
|
||||
|
||||
/* Page 0x13 Interrupt Registers */
|
||||
/* Interrupts */
|
||||
#define CS42L42_ADC_OVFL_STATUS (CS42L42_PAGE_13 + 0x01)
|
||||
#define CS42L42_MIXER_STATUS (CS42L42_PAGE_13 + 0x02)
|
||||
#define CS42L42_SRC_STATUS (CS42L42_PAGE_13 + 0x03)
|
||||
#define CS42L42_ASP_RX_STATUS (CS42L42_PAGE_13 + 0x04)
|
||||
#define CS42L42_ASP_TX_STATUS (CS42L42_PAGE_13 + 0x05)
|
||||
#define CS42L42_CODEC_STATUS (CS42L42_PAGE_13 + 0x08)
|
||||
#define CS42L42_DET_INT_STATUS1 (CS42L42_PAGE_13 + 0x09)
|
||||
#define CS42L42_DET_INT_STATUS2 (CS42L42_PAGE_13 + 0x0A)
|
||||
#define CS42L42_SRCPL_INT_STATUS (CS42L42_PAGE_13 + 0x0B)
|
||||
#define CS42L42_VPMON_STATUS (CS42L42_PAGE_13 + 0x0D)
|
||||
#define CS42L42_PLL_LOCK_STATUS (CS42L42_PAGE_13 + 0x0E)
|
||||
#define CS42L42_TSRS_PLUG_STATUS (CS42L42_PAGE_13 + 0x0F)
|
||||
/* Masks */
|
||||
#define CS42L42_ADC_OVFL_INT_MASK (CS42L42_PAGE_13 + 0x16)
|
||||
#define CS42L42_ADC_OVFL_SHIFT 0
|
||||
#define CS42L42_ADC_OVFL_MASK (1 << CS42L42_ADC_OVFL_SHIFT)
|
||||
#define CS42L42_ADC_OVFL_VAL_MASK CS42L42_ADC_OVFL_MASK
|
||||
|
||||
#define CS42L42_MIXER_INT_MASK (CS42L42_PAGE_13 + 0x17)
|
||||
#define CS42L42_MIX_CHB_OVFL_SHIFT 0
|
||||
#define CS42L42_MIX_CHB_OVFL_MASK (1 << CS42L42_MIX_CHB_OVFL_SHIFT)
|
||||
#define CS42L42_MIX_CHA_OVFL_SHIFT 1
|
||||
#define CS42L42_MIX_CHA_OVFL_MASK (1 << CS42L42_MIX_CHA_OVFL_SHIFT)
|
||||
#define CS42L42_EQ_OVFL_SHIFT 2
|
||||
#define CS42L42_EQ_OVFL_MASK (1 << CS42L42_EQ_OVFL_SHIFT)
|
||||
#define CS42L42_EQ_BIQUAD_OVFL_SHIFT 3
|
||||
#define CS42L42_EQ_BIQUAD_OVFL_MASK (1 << CS42L42_EQ_BIQUAD_OVFL_SHIFT)
|
||||
#define CS42L42_MIXER_VAL_MASK (CS42L42_MIX_CHB_OVFL_MASK | \
|
||||
CS42L42_MIX_CHA_OVFL_MASK | \
|
||||
CS42L42_EQ_OVFL_MASK | \
|
||||
CS42L42_EQ_BIQUAD_OVFL_MASK)
|
||||
|
||||
#define CS42L42_SRC_INT_MASK (CS42L42_PAGE_13 + 0x18)
|
||||
#define CS42L42_SRC_ILK_SHIFT 0
|
||||
#define CS42L42_SRC_ILK_MASK (1 << CS42L42_SRC_ILK_SHIFT)
|
||||
#define CS42L42_SRC_OLK_SHIFT 1
|
||||
#define CS42L42_SRC_OLK_MASK (1 << CS42L42_SRC_OLK_SHIFT)
|
||||
#define CS42L42_SRC_IUNLK_SHIFT 2
|
||||
#define CS42L42_SRC_IUNLK_MASK (1 << CS42L42_SRC_IUNLK_SHIFT)
|
||||
#define CS42L42_SRC_OUNLK_SHIFT 3
|
||||
#define CS42L42_SRC_OUNLK_MASK (1 << CS42L42_SRC_OUNLK_SHIFT)
|
||||
#define CS42L42_SRC_VAL_MASK (CS42L42_SRC_ILK_MASK | \
|
||||
CS42L42_SRC_OLK_MASK | \
|
||||
CS42L42_SRC_IUNLK_MASK | \
|
||||
CS42L42_SRC_OUNLK_MASK)
|
||||
|
||||
#define CS42L42_ASP_RX_INT_MASK (CS42L42_PAGE_13 + 0x19)
|
||||
#define CS42L42_ASPRX_NOLRCK_SHIFT 0
|
||||
#define CS42L42_ASPRX_NOLRCK_MASK (1 << CS42L42_ASPRX_NOLRCK_SHIFT)
|
||||
#define CS42L42_ASPRX_EARLY_SHIFT 1
|
||||
#define CS42L42_ASPRX_EARLY_MASK (1 << CS42L42_ASPRX_EARLY_SHIFT)
|
||||
#define CS42L42_ASPRX_LATE_SHIFT 2
|
||||
#define CS42L42_ASPRX_LATE_MASK (1 << CS42L42_ASPRX_LATE_SHIFT)
|
||||
#define CS42L42_ASPRX_ERROR_SHIFT 3
|
||||
#define CS42L42_ASPRX_ERROR_MASK (1 << CS42L42_ASPRX_ERROR_SHIFT)
|
||||
#define CS42L42_ASPRX_OVLD_SHIFT 4
|
||||
#define CS42L42_ASPRX_OVLD_MASK (1 << CS42L42_ASPRX_OVLD_SHIFT)
|
||||
#define CS42L42_ASP_RX_VAL_MASK (CS42L42_ASPRX_NOLRCK_MASK | \
|
||||
CS42L42_ASPRX_EARLY_MASK | \
|
||||
CS42L42_ASPRX_LATE_MASK | \
|
||||
CS42L42_ASPRX_ERROR_MASK | \
|
||||
CS42L42_ASPRX_OVLD_MASK)
|
||||
|
||||
#define CS42L42_ASP_TX_INT_MASK (CS42L42_PAGE_13 + 0x1A)
|
||||
#define CS42L42_ASPTX_NOLRCK_SHIFT 0
|
||||
#define CS42L42_ASPTX_NOLRCK_MASK (1 << CS42L42_ASPTX_NOLRCK_SHIFT)
|
||||
#define CS42L42_ASPTX_EARLY_SHIFT 1
|
||||
#define CS42L42_ASPTX_EARLY_MASK (1 << CS42L42_ASPTX_EARLY_SHIFT)
|
||||
#define CS42L42_ASPTX_LATE_SHIFT 2
|
||||
#define CS42L42_ASPTX_LATE_MASK (1 << CS42L42_ASPTX_LATE_SHIFT)
|
||||
#define CS42L42_ASPTX_SMERROR_SHIFT 3
|
||||
#define CS42L42_ASPTX_SMERROR_MASK (1 << CS42L42_ASPTX_SMERROR_SHIFT)
|
||||
#define CS42L42_ASP_TX_VAL_MASK (CS42L42_ASPTX_NOLRCK_MASK | \
|
||||
CS42L42_ASPTX_EARLY_MASK | \
|
||||
CS42L42_ASPTX_LATE_MASK | \
|
||||
CS42L42_ASPTX_SMERROR_MASK)
|
||||
|
||||
#define CS42L42_CODEC_INT_MASK (CS42L42_PAGE_13 + 0x1B)
|
||||
#define CS42L42_PDN_DONE_SHIFT 0
|
||||
#define CS42L42_PDN_DONE_MASK (1 << CS42L42_PDN_DONE_SHIFT)
|
||||
#define CS42L42_HSDET_AUTO_DONE_SHIFT 1
|
||||
#define CS42L42_HSDET_AUTO_DONE_MASK (1 << CS42L42_HSDET_AUTO_DONE_SHIFT)
|
||||
#define CS42L42_CODEC_VAL_MASK (CS42L42_PDN_DONE_MASK | \
|
||||
CS42L42_HSDET_AUTO_DONE_MASK)
|
||||
|
||||
#define CS42L42_SRCPL_INT_MASK (CS42L42_PAGE_13 + 0x1C)
|
||||
#define CS42L42_SRCPL_ADC_LK_SHIFT 0
|
||||
#define CS42L42_SRCPL_ADC_LK_MASK (1 << CS42L42_SRCPL_ADC_LK_SHIFT)
|
||||
#define CS42L42_SRCPL_DAC_LK_SHIFT 2
|
||||
#define CS42L42_SRCPL_DAC_LK_MASK (1 << CS42L42_SRCPL_DAC_LK_SHIFT)
|
||||
#define CS42L42_SRCPL_ADC_UNLK_SHIFT 5
|
||||
#define CS42L42_SRCPL_ADC_UNLK_MASK (1 << CS42L42_SRCPL_ADC_UNLK_SHIFT)
|
||||
#define CS42L42_SRCPL_DAC_UNLK_SHIFT 6
|
||||
#define CS42L42_SRCPL_DAC_UNLK_MASK (1 << CS42L42_SRCPL_DAC_UNLK_SHIFT)
|
||||
#define CS42L42_SRCPL_VAL_MASK (CS42L42_SRCPL_ADC_LK_MASK | \
|
||||
CS42L42_SRCPL_DAC_LK_MASK | \
|
||||
CS42L42_SRCPL_ADC_UNLK_MASK | \
|
||||
CS42L42_SRCPL_DAC_UNLK_MASK)
|
||||
|
||||
#define CS42L42_VPMON_INT_MASK (CS42L42_PAGE_13 + 0x1E)
|
||||
#define CS42L42_VPMON_SHIFT 0
|
||||
#define CS42L42_VPMON_MASK (1 << CS42L42_VPMON_SHIFT)
|
||||
#define CS42L42_VPMON_VAL_MASK CS42L42_VPMON_MASK
|
||||
|
||||
#define CS42L42_PLL_LOCK_INT_MASK (CS42L42_PAGE_13 + 0x1F)
|
||||
#define CS42L42_PLL_LOCK_SHIFT 0
|
||||
#define CS42L42_PLL_LOCK_MASK (1 << CS42L42_PLL_LOCK_SHIFT)
|
||||
#define CS42L42_PLL_LOCK_VAL_MASK CS42L42_PLL_LOCK_MASK
|
||||
|
||||
#define CS42L42_TSRS_PLUG_INT_MASK (CS42L42_PAGE_13 + 0x20)
|
||||
#define CS42L42_RS_PLUG_SHIFT 0
|
||||
#define CS42L42_RS_PLUG_MASK (1 << CS42L42_RS_PLUG_SHIFT)
|
||||
#define CS42L42_RS_UNPLUG_SHIFT 1
|
||||
#define CS42L42_RS_UNPLUG_MASK (1 << CS42L42_RS_UNPLUG_SHIFT)
|
||||
#define CS42L42_TS_PLUG_SHIFT 2
|
||||
#define CS42L42_TS_PLUG_MASK (1 << CS42L42_TS_PLUG_SHIFT)
|
||||
#define CS42L42_TS_UNPLUG_SHIFT 3
|
||||
#define CS42L42_TS_UNPLUG_MASK (1 << CS42L42_TS_UNPLUG_SHIFT)
|
||||
#define CS42L42_TSRS_PLUG_VAL_MASK (CS42L42_RS_PLUG_MASK | \
|
||||
CS42L42_RS_UNPLUG_MASK | \
|
||||
CS42L42_TS_PLUG_MASK | \
|
||||
CS42L42_TS_UNPLUG_MASK)
|
||||
#define CS42L42_TS_PLUG 3
|
||||
#define CS42L42_TS_UNPLUG 0
|
||||
#define CS42L42_TS_TRANS 1
|
||||
|
||||
/*
|
||||
* NOTE: PLL_START must be 0 while both ADC_PDN=1 and HP_PDN=1.
|
||||
* Otherwise it will prevent FILT+ from charging properly.
|
||||
*/
|
||||
#define CS42L42_PLL_CTL1 (CS42L42_PAGE_15 + 0x01)
|
||||
#define CS42L42_PLL_START_SHIFT 0
|
||||
#define CS42L42_PLL_START_MASK (1 << CS42L42_PLL_START_SHIFT)
|
||||
|
||||
#define CS42L42_PLL_DIV_FRAC0 (CS42L42_PAGE_15 + 0x02)
|
||||
#define CS42L42_PLL_DIV_FRAC_SHIFT 0
|
||||
#define CS42L42_PLL_DIV_FRAC_MASK (0xff << CS42L42_PLL_DIV_FRAC_SHIFT)
|
||||
|
||||
#define CS42L42_PLL_DIV_FRAC1 (CS42L42_PAGE_15 + 0x03)
|
||||
#define CS42L42_PLL_DIV_FRAC2 (CS42L42_PAGE_15 + 0x04)
|
||||
|
||||
#define CS42L42_PLL_DIV_INT (CS42L42_PAGE_15 + 0x05)
|
||||
#define CS42L42_PLL_DIV_INT_SHIFT 0
|
||||
#define CS42L42_PLL_DIV_INT_MASK (0xff << CS42L42_PLL_DIV_INT_SHIFT)
|
||||
|
||||
#define CS42L42_PLL_CTL3 (CS42L42_PAGE_15 + 0x08)
|
||||
#define CS42L42_PLL_DIVOUT_SHIFT 0
|
||||
#define CS42L42_PLL_DIVOUT_MASK (0xff << CS42L42_PLL_DIVOUT_SHIFT)
|
||||
|
||||
#define CS42L42_PLL_CAL_RATIO (CS42L42_PAGE_15 + 0x0A)
|
||||
#define CS42L42_PLL_CAL_RATIO_SHIFT 0
|
||||
#define CS42L42_PLL_CAL_RATIO_MASK (0xff << CS42L42_PLL_CAL_RATIO_SHIFT)
|
||||
|
||||
#define CS42L42_PLL_CTL4 (CS42L42_PAGE_15 + 0x1B)
|
||||
#define CS42L42_PLL_MODE_SHIFT 0
|
||||
#define CS42L42_PLL_MODE_MASK (3 << CS42L42_PLL_MODE_SHIFT)
|
||||
|
||||
/* Page 0x19 HP Load Detect Registers */
|
||||
#define CS42L42_LOAD_DET_RCSTAT (CS42L42_PAGE_19 + 0x25)
|
||||
#define CS42L42_RLA_STAT_SHIFT 0
|
||||
#define CS42L42_RLA_STAT_MASK (3 << CS42L42_RLA_STAT_SHIFT)
|
||||
#define CS42L42_RLA_STAT_15_OHM 0
|
||||
|
||||
#define CS42L42_LOAD_DET_DONE (CS42L42_PAGE_19 + 0x26)
|
||||
#define CS42L42_HPLOAD_DET_DONE_SHIFT 0
|
||||
#define CS42L42_HPLOAD_DET_DONE_MASK (1 << CS42L42_HPLOAD_DET_DONE_SHIFT)
|
||||
|
||||
#define CS42L42_LOAD_DET_EN (CS42L42_PAGE_19 + 0x27)
|
||||
#define CS42L42_HP_LD_EN_SHIFT 0
|
||||
#define CS42L42_HP_LD_EN_MASK (1 << CS42L42_HP_LD_EN_SHIFT)
|
||||
|
||||
/* Page 0x1B Headset Interface Registers */
|
||||
#define CS42L42_HSBIAS_SC_AUTOCTL (CS42L42_PAGE_1B + 0x70)
|
||||
#define CS42L42_HSBIAS_SENSE_TRIP_SHIFT 0
|
||||
#define CS42L42_HSBIAS_SENSE_TRIP_MASK (7 << CS42L42_HSBIAS_SENSE_TRIP_SHIFT)
|
||||
#define CS42L42_TIP_SENSE_EN_SHIFT 5
|
||||
#define CS42L42_TIP_SENSE_EN_MASK (1 << CS42L42_TIP_SENSE_EN_SHIFT)
|
||||
#define CS42L42_AUTO_HSBIAS_HIZ_SHIFT 6
|
||||
#define CS42L42_AUTO_HSBIAS_HIZ_MASK (1 << CS42L42_AUTO_HSBIAS_HIZ_SHIFT)
|
||||
#define CS42L42_HSBIAS_SENSE_EN_SHIFT 7
|
||||
#define CS42L42_HSBIAS_SENSE_EN_MASK (1 << CS42L42_HSBIAS_SENSE_EN_SHIFT)
|
||||
|
||||
#define CS42L42_WAKE_CTL (CS42L42_PAGE_1B + 0x71)
|
||||
#define CS42L42_WAKEB_CLEAR_SHIFT 0
|
||||
#define CS42L42_WAKEB_CLEAR_MASK (1 << CS42L42_WAKEB_CLEAR_SHIFT)
|
||||
#define CS42L42_WAKEB_MODE_SHIFT 5
|
||||
#define CS42L42_WAKEB_MODE_MASK (1 << CS42L42_WAKEB_MODE_SHIFT)
|
||||
#define CS42L42_M_HP_WAKE_SHIFT 6
|
||||
#define CS42L42_M_HP_WAKE_MASK (1 << CS42L42_M_HP_WAKE_SHIFT)
|
||||
#define CS42L42_M_MIC_WAKE_SHIFT 7
|
||||
#define CS42L42_M_MIC_WAKE_MASK (1 << CS42L42_M_MIC_WAKE_SHIFT)
|
||||
|
||||
#define CS42L42_ADC_DISABLE_MUTE (CS42L42_PAGE_1B + 0x72)
|
||||
#define CS42L42_ADC_DISABLE_S0_MUTE_SHIFT 7
|
||||
#define CS42L42_ADC_DISABLE_S0_MUTE_MASK (1 << CS42L42_ADC_DISABLE_S0_MUTE_SHIFT)
|
||||
|
||||
#define CS42L42_TIPSENSE_CTL (CS42L42_PAGE_1B + 0x73)
|
||||
#define CS42L42_TIP_SENSE_DEBOUNCE_SHIFT 0
|
||||
#define CS42L42_TIP_SENSE_DEBOUNCE_MASK (3 << CS42L42_TIP_SENSE_DEBOUNCE_SHIFT)
|
||||
#define CS42L42_TIP_SENSE_INV_SHIFT 5
|
||||
#define CS42L42_TIP_SENSE_INV_MASK (1 << CS42L42_TIP_SENSE_INV_SHIFT)
|
||||
#define CS42L42_TIP_SENSE_CTRL_SHIFT 6
|
||||
#define CS42L42_TIP_SENSE_CTRL_MASK (3 << CS42L42_TIP_SENSE_CTRL_SHIFT)
|
||||
|
||||
/*
|
||||
* NOTE: DETECT_MODE must be 0 while both ADC_PDN=1 and HP_PDN=1.
|
||||
* Otherwise it will prevent FILT+ from charging properly.
|
||||
*/
|
||||
#define CS42L42_MISC_DET_CTL (CS42L42_PAGE_1B + 0x74)
|
||||
#define CS42L42_PDN_MIC_LVL_DET_SHIFT 0
|
||||
#define CS42L42_PDN_MIC_LVL_DET_MASK (1 << CS42L42_PDN_MIC_LVL_DET_SHIFT)
|
||||
#define CS42L42_HSBIAS_CTL_SHIFT 1
|
||||
#define CS42L42_HSBIAS_CTL_MASK (3 << CS42L42_HSBIAS_CTL_SHIFT)
|
||||
#define CS42L42_DETECT_MODE_SHIFT 3
|
||||
#define CS42L42_DETECT_MODE_MASK (3 << CS42L42_DETECT_MODE_SHIFT)
|
||||
|
||||
#define CS42L42_MIC_DET_CTL1 (CS42L42_PAGE_1B + 0x75)
|
||||
#define CS42L42_HS_DET_LEVEL_SHIFT 0
|
||||
#define CS42L42_HS_DET_LEVEL_MASK (0x3F << CS42L42_HS_DET_LEVEL_SHIFT)
|
||||
#define CS42L42_EVENT_STAT_SEL_SHIFT 6
|
||||
#define CS42L42_EVENT_STAT_SEL_MASK (1 << CS42L42_EVENT_STAT_SEL_SHIFT)
|
||||
#define CS42L42_LATCH_TO_VP_SHIFT 7
|
||||
#define CS42L42_LATCH_TO_VP_MASK (1 << CS42L42_LATCH_TO_VP_SHIFT)
|
||||
|
||||
#define CS42L42_MIC_DET_CTL2 (CS42L42_PAGE_1B + 0x76)
|
||||
#define CS42L42_DEBOUNCE_TIME_SHIFT 5
|
||||
#define CS42L42_DEBOUNCE_TIME_MASK (0x07 << CS42L42_DEBOUNCE_TIME_SHIFT)
|
||||
|
||||
#define CS42L42_DET_STATUS1 (CS42L42_PAGE_1B + 0x77)
|
||||
#define CS42L42_HSBIAS_HIZ_MODE_SHIFT 6
|
||||
#define CS42L42_HSBIAS_HIZ_MODE_MASK (1 << CS42L42_HSBIAS_HIZ_MODE_SHIFT)
|
||||
#define CS42L42_TIP_SENSE_SHIFT 7
|
||||
#define CS42L42_TIP_SENSE_MASK (1 << CS42L42_TIP_SENSE_SHIFT)
|
||||
|
||||
#define CS42L42_DET_STATUS2 (CS42L42_PAGE_1B + 0x78)
|
||||
#define CS42L42_SHORT_TRUE_SHIFT 0
|
||||
#define CS42L42_SHORT_TRUE_MASK (1 << CS42L42_SHORT_TRUE_SHIFT)
|
||||
#define CS42L42_HS_TRUE_SHIFT 1
|
||||
#define CS42L42_HS_TRUE_MASK (1 << CS42L42_HS_TRUE_SHIFT)
|
||||
|
||||
#define CS42L42_DET_INT1_MASK (CS42L42_PAGE_1B + 0x79)
|
||||
#define CS42L42_TIP_SENSE_UNPLUG_SHIFT 5
|
||||
#define CS42L42_TIP_SENSE_UNPLUG_MASK (1 << CS42L42_TIP_SENSE_UNPLUG_SHIFT)
|
||||
#define CS42L42_TIP_SENSE_PLUG_SHIFT 6
|
||||
#define CS42L42_TIP_SENSE_PLUG_MASK (1 << CS42L42_TIP_SENSE_PLUG_SHIFT)
|
||||
#define CS42L42_HSBIAS_SENSE_SHIFT 7
|
||||
#define CS42L42_HSBIAS_SENSE_MASK (1 << CS42L42_HSBIAS_SENSE_SHIFT)
|
||||
#define CS42L42_DET_INT_VAL1_MASK (CS42L42_TIP_SENSE_UNPLUG_MASK | \
|
||||
CS42L42_TIP_SENSE_PLUG_MASK | \
|
||||
CS42L42_HSBIAS_SENSE_MASK)
|
||||
|
||||
#define CS42L42_DET_INT2_MASK (CS42L42_PAGE_1B + 0x7A)
|
||||
#define CS42L42_M_SHORT_DET_SHIFT 0
|
||||
#define CS42L42_M_SHORT_DET_MASK (1 << CS42L42_M_SHORT_DET_SHIFT)
|
||||
#define CS42L42_M_SHORT_RLS_SHIFT 1
|
||||
#define CS42L42_M_SHORT_RLS_MASK (1 << CS42L42_M_SHORT_RLS_SHIFT)
|
||||
#define CS42L42_M_HSBIAS_HIZ_SHIFT 2
|
||||
#define CS42L42_M_HSBIAS_HIZ_MASK (1 << CS42L42_M_HSBIAS_HIZ_SHIFT)
|
||||
#define CS42L42_M_DETECT_FT_SHIFT 6
|
||||
#define CS42L42_M_DETECT_FT_MASK (1 << CS42L42_M_DETECT_FT_SHIFT)
|
||||
#define CS42L42_M_DETECT_TF_SHIFT 7
|
||||
#define CS42L42_M_DETECT_TF_MASK (1 << CS42L42_M_DETECT_TF_SHIFT)
|
||||
#define CS42L42_DET_INT_VAL2_MASK (CS42L42_M_SHORT_DET_MASK | \
|
||||
CS42L42_M_SHORT_RLS_MASK | \
|
||||
CS42L42_M_HSBIAS_HIZ_MASK | \
|
||||
CS42L42_M_DETECT_FT_MASK | \
|
||||
CS42L42_M_DETECT_TF_MASK)
|
||||
|
||||
/* Page 0x1C Headset Bias Registers */
|
||||
#define CS42L42_HS_BIAS_CTL (CS42L42_PAGE_1C + 0x03)
|
||||
#define CS42L42_HSBIAS_RAMP_SHIFT 0
|
||||
#define CS42L42_HSBIAS_RAMP_MASK (3 << CS42L42_HSBIAS_RAMP_SHIFT)
|
||||
#define CS42L42_HSBIAS_PD_SHIFT 4
|
||||
#define CS42L42_HSBIAS_PD_MASK (1 << CS42L42_HSBIAS_PD_SHIFT)
|
||||
#define CS42L42_HSBIAS_CAPLESS_SHIFT 7
|
||||
#define CS42L42_HSBIAS_CAPLESS_MASK (1 << CS42L42_HSBIAS_CAPLESS_SHIFT)
|
||||
|
||||
/* Page 0x1D ADC Registers */
|
||||
#define CS42L42_ADC_CTL (CS42L42_PAGE_1D + 0x01)
|
||||
#define CS42L42_ADC_NOTCH_DIS_SHIFT 5
|
||||
#define CS42L42_ADC_FORCE_WEAK_VCM_SHIFT 4
|
||||
#define CS42L42_ADC_INV_SHIFT 2
|
||||
#define CS42L42_ADC_DIG_BOOST_SHIFT 0
|
||||
|
||||
#define CS42L42_ADC_VOLUME (CS42L42_PAGE_1D + 0x03)
|
||||
#define CS42L42_ADC_VOL_SHIFT 0
|
||||
|
||||
#define CS42L42_ADC_WNF_HPF_CTL (CS42L42_PAGE_1D + 0x04)
|
||||
#define CS42L42_ADC_WNF_CF_SHIFT 4
|
||||
#define CS42L42_ADC_WNF_EN_SHIFT 3
|
||||
#define CS42L42_ADC_HPF_CF_SHIFT 1
|
||||
#define CS42L42_ADC_HPF_EN_SHIFT 0
|
||||
|
||||
/* Page 0x1F DAC Registers */
|
||||
#define CS42L42_DAC_CTL1 (CS42L42_PAGE_1F + 0x01)
|
||||
#define CS42L42_DACB_INV_SHIFT 1
|
||||
#define CS42L42_DACA_INV_SHIFT 0
|
||||
|
||||
#define CS42L42_DAC_CTL2 (CS42L42_PAGE_1F + 0x06)
|
||||
#define CS42L42_HPOUT_PULLDOWN_SHIFT 4
|
||||
#define CS42L42_HPOUT_PULLDOWN_MASK (15 << CS42L42_HPOUT_PULLDOWN_SHIFT)
|
||||
#define CS42L42_HPOUT_LOAD_SHIFT 3
|
||||
#define CS42L42_HPOUT_LOAD_MASK (1 << CS42L42_HPOUT_LOAD_SHIFT)
|
||||
#define CS42L42_HPOUT_CLAMP_SHIFT 2
|
||||
#define CS42L42_HPOUT_CLAMP_MASK (1 << CS42L42_HPOUT_CLAMP_SHIFT)
|
||||
#define CS42L42_DAC_HPF_EN_SHIFT 1
|
||||
#define CS42L42_DAC_HPF_EN_MASK (1 << CS42L42_DAC_HPF_EN_SHIFT)
|
||||
#define CS42L42_DAC_MON_EN_SHIFT 0
|
||||
#define CS42L42_DAC_MON_EN_MASK (1 << CS42L42_DAC_MON_EN_SHIFT)
|
||||
|
||||
/* Page 0x20 HP CTL Registers */
|
||||
#define CS42L42_HP_CTL (CS42L42_PAGE_20 + 0x01)
|
||||
#define CS42L42_HP_ANA_BMUTE_SHIFT 3
|
||||
#define CS42L42_HP_ANA_BMUTE_MASK (1 << CS42L42_HP_ANA_BMUTE_SHIFT)
|
||||
#define CS42L42_HP_ANA_AMUTE_SHIFT 2
|
||||
#define CS42L42_HP_ANA_AMUTE_MASK (1 << CS42L42_HP_ANA_AMUTE_SHIFT)
|
||||
#define CS42L42_HP_FULL_SCALE_VOL_SHIFT 1
|
||||
#define CS42L42_HP_FULL_SCALE_VOL_MASK (1 << CS42L42_HP_FULL_SCALE_VOL_SHIFT)
|
||||
|
||||
/* Page 0x21 Class H Registers */
|
||||
#define CS42L42_CLASSH_CTL (CS42L42_PAGE_21 + 0x01)
|
||||
|
||||
/* Page 0x23 Mixer Volume Registers */
|
||||
#define CS42L42_MIXER_CHA_VOL (CS42L42_PAGE_23 + 0x01)
|
||||
#define CS42L42_MIXER_ADC_VOL (CS42L42_PAGE_23 + 0x02)
|
||||
|
||||
#define CS42L42_MIXER_CHB_VOL (CS42L42_PAGE_23 + 0x03)
|
||||
#define CS42L42_MIXER_CH_VOL_SHIFT 0
|
||||
#define CS42L42_MIXER_CH_VOL_MASK (0x3f << CS42L42_MIXER_CH_VOL_SHIFT)
|
||||
|
||||
/* Page 0x24 EQ Registers */
|
||||
#define CS42L42_EQ_COEF_IN0 (CS42L42_PAGE_24 + 0x01)
|
||||
#define CS42L42_EQ_COEF_IN1 (CS42L42_PAGE_24 + 0x02)
|
||||
#define CS42L42_EQ_COEF_IN2 (CS42L42_PAGE_24 + 0x03)
|
||||
#define CS42L42_EQ_COEF_IN3 (CS42L42_PAGE_24 + 0x04)
|
||||
#define CS42L42_EQ_COEF_RW (CS42L42_PAGE_24 + 0x06)
|
||||
#define CS42L42_EQ_COEF_OUT0 (CS42L42_PAGE_24 + 0x07)
|
||||
#define CS42L42_EQ_COEF_OUT1 (CS42L42_PAGE_24 + 0x08)
|
||||
#define CS42L42_EQ_COEF_OUT2 (CS42L42_PAGE_24 + 0x09)
|
||||
#define CS42L42_EQ_COEF_OUT3 (CS42L42_PAGE_24 + 0x0A)
|
||||
#define CS42L42_EQ_INIT_STAT (CS42L42_PAGE_24 + 0x0B)
|
||||
#define CS42L42_EQ_START_FILT (CS42L42_PAGE_24 + 0x0C)
|
||||
#define CS42L42_EQ_MUTE_CTL (CS42L42_PAGE_24 + 0x0E)
|
||||
|
||||
/* Page 0x25 Audio Port Registers */
|
||||
#define CS42L42_SP_RX_CH_SEL (CS42L42_PAGE_25 + 0x01)
|
||||
#define CS42L42_SP_RX_CHB_SEL_SHIFT 2
|
||||
#define CS42L42_SP_RX_CHB_SEL_MASK (3 << CS42L42_SP_RX_CHB_SEL_SHIFT)
|
||||
|
||||
#define CS42L42_SP_RX_ISOC_CTL (CS42L42_PAGE_25 + 0x02)
|
||||
#define CS42L42_SP_RX_RSYNC_SHIFT 6
|
||||
#define CS42L42_SP_RX_RSYNC_MASK (1 << CS42L42_SP_RX_RSYNC_SHIFT)
|
||||
#define CS42L42_SP_RX_NSB_POS_SHIFT 3
|
||||
#define CS42L42_SP_RX_NSB_POS_MASK (7 << CS42L42_SP_RX_NSB_POS_SHIFT)
|
||||
#define CS42L42_SP_RX_NFS_NSBB_SHIFT 2
|
||||
#define CS42L42_SP_RX_NFS_NSBB_MASK (1 << CS42L42_SP_RX_NFS_NSBB_SHIFT)
|
||||
#define CS42L42_SP_RX_ISOC_MODE_SHIFT 0
|
||||
#define CS42L42_SP_RX_ISOC_MODE_MASK (3 << CS42L42_SP_RX_ISOC_MODE_SHIFT)
|
||||
|
||||
#define CS42L42_SP_RX_FS (CS42L42_PAGE_25 + 0x03)
|
||||
#define CS42l42_SPDIF_CH_SEL (CS42L42_PAGE_25 + 0x04)
|
||||
#define CS42L42_SP_TX_ISOC_CTL (CS42L42_PAGE_25 + 0x05)
|
||||
#define CS42L42_SP_TX_FS (CS42L42_PAGE_25 + 0x06)
|
||||
#define CS42L42_SPDIF_SW_CTL1 (CS42L42_PAGE_25 + 0x07)
|
||||
|
||||
/* Page 0x26 SRC Registers */
|
||||
#define CS42L42_SRC_SDIN_FS (CS42L42_PAGE_26 + 0x01)
|
||||
#define CS42L42_SRC_SDIN_FS_SHIFT 0
|
||||
#define CS42L42_SRC_SDIN_FS_MASK (0x1f << CS42L42_SRC_SDIN_FS_SHIFT)
|
||||
|
||||
#define CS42L42_SRC_SDOUT_FS (CS42L42_PAGE_26 + 0x09)
|
||||
|
||||
/* Page 0x28 S/PDIF Registers */
|
||||
#define CS42L42_SPDIF_CTL1 (CS42L42_PAGE_28 + 0x01)
|
||||
#define CS42L42_SPDIF_CTL2 (CS42L42_PAGE_28 + 0x02)
|
||||
#define CS42L42_SPDIF_CTL3 (CS42L42_PAGE_28 + 0x03)
|
||||
#define CS42L42_SPDIF_CTL4 (CS42L42_PAGE_28 + 0x04)
|
||||
|
||||
/* Page 0x29 Serial Port TX Registers */
|
||||
#define CS42L42_ASP_TX_SZ_EN (CS42L42_PAGE_29 + 0x01)
|
||||
#define CS42L42_ASP_TX_EN_SHIFT 0
|
||||
#define CS42L42_ASP_TX_CH_EN (CS42L42_PAGE_29 + 0x02)
|
||||
#define CS42L42_ASP_TX0_CH2_SHIFT 1
|
||||
#define CS42L42_ASP_TX0_CH1_SHIFT 0
|
||||
|
||||
#define CS42L42_ASP_TX_CH_AP_RES (CS42L42_PAGE_29 + 0x03)
|
||||
#define CS42L42_ASP_TX_CH1_AP_SHIFT 7
|
||||
#define CS42L42_ASP_TX_CH1_AP_MASK (1 << CS42L42_ASP_TX_CH1_AP_SHIFT)
|
||||
#define CS42L42_ASP_TX_CH2_AP_SHIFT 6
|
||||
#define CS42L42_ASP_TX_CH2_AP_MASK (1 << CS42L42_ASP_TX_CH2_AP_SHIFT)
|
||||
#define CS42L42_ASP_TX_CH2_RES_SHIFT 2
|
||||
#define CS42L42_ASP_TX_CH2_RES_MASK (3 << CS42L42_ASP_TX_CH2_RES_SHIFT)
|
||||
#define CS42L42_ASP_TX_CH1_RES_SHIFT 0
|
||||
#define CS42L42_ASP_TX_CH1_RES_MASK (3 << CS42L42_ASP_TX_CH1_RES_SHIFT)
|
||||
#define CS42L42_ASP_TX_CH1_BIT_MSB (CS42L42_PAGE_29 + 0x04)
|
||||
#define CS42L42_ASP_TX_CH1_BIT_LSB (CS42L42_PAGE_29 + 0x05)
|
||||
#define CS42L42_ASP_TX_HIZ_DLY_CFG (CS42L42_PAGE_29 + 0x06)
|
||||
#define CS42L42_ASP_TX_CH2_BIT_MSB (CS42L42_PAGE_29 + 0x0A)
|
||||
#define CS42L42_ASP_TX_CH2_BIT_LSB (CS42L42_PAGE_29 + 0x0B)
|
||||
|
||||
/* Page 0x2A Serial Port RX Registers */
|
||||
#define CS42L42_ASP_RX_DAI0_EN (CS42L42_PAGE_2A + 0x01)
|
||||
#define CS42L42_ASP_RX0_CH_EN_SHIFT 2
|
||||
#define CS42L42_ASP_RX0_CH_EN_MASK (0xf << CS42L42_ASP_RX0_CH_EN_SHIFT)
|
||||
#define CS42L42_ASP_RX0_CH1_SHIFT 2
|
||||
#define CS42L42_ASP_RX0_CH2_SHIFT 3
|
||||
#define CS42L42_ASP_RX0_CH3_SHIFT 4
|
||||
#define CS42L42_ASP_RX0_CH4_SHIFT 5
|
||||
|
||||
#define CS42L42_ASP_RX_DAI0_CH1_AP_RES (CS42L42_PAGE_2A + 0x02)
|
||||
#define CS42L42_ASP_RX_DAI0_CH1_BIT_MSB (CS42L42_PAGE_2A + 0x03)
|
||||
#define CS42L42_ASP_RX_DAI0_CH1_BIT_LSB (CS42L42_PAGE_2A + 0x04)
|
||||
#define CS42L42_ASP_RX_DAI0_CH2_AP_RES (CS42L42_PAGE_2A + 0x05)
|
||||
#define CS42L42_ASP_RX_DAI0_CH2_BIT_MSB (CS42L42_PAGE_2A + 0x06)
|
||||
#define CS42L42_ASP_RX_DAI0_CH2_BIT_LSB (CS42L42_PAGE_2A + 0x07)
|
||||
#define CS42L42_ASP_RX_DAI0_CH3_AP_RES (CS42L42_PAGE_2A + 0x08)
|
||||
#define CS42L42_ASP_RX_DAI0_CH3_BIT_MSB (CS42L42_PAGE_2A + 0x09)
|
||||
#define CS42L42_ASP_RX_DAI0_CH3_BIT_LSB (CS42L42_PAGE_2A + 0x0A)
|
||||
#define CS42L42_ASP_RX_DAI0_CH4_AP_RES (CS42L42_PAGE_2A + 0x0B)
|
||||
#define CS42L42_ASP_RX_DAI0_CH4_BIT_MSB (CS42L42_PAGE_2A + 0x0C)
|
||||
#define CS42L42_ASP_RX_DAI0_CH4_BIT_LSB (CS42L42_PAGE_2A + 0x0D)
|
||||
#define CS42L42_ASP_RX_DAI1_CH1_AP_RES (CS42L42_PAGE_2A + 0x0E)
|
||||
#define CS42L42_ASP_RX_DAI1_CH1_BIT_MSB (CS42L42_PAGE_2A + 0x0F)
|
||||
#define CS42L42_ASP_RX_DAI1_CH1_BIT_LSB (CS42L42_PAGE_2A + 0x10)
|
||||
#define CS42L42_ASP_RX_DAI1_CH2_AP_RES (CS42L42_PAGE_2A + 0x11)
|
||||
#define CS42L42_ASP_RX_DAI1_CH2_BIT_MSB (CS42L42_PAGE_2A + 0x12)
|
||||
#define CS42L42_ASP_RX_DAI1_CH2_BIT_LSB (CS42L42_PAGE_2A + 0x13)
|
||||
|
||||
#define CS42L42_ASP_RX_CH_AP_SHIFT 6
|
||||
#define CS42L42_ASP_RX_CH_AP_MASK (1 << CS42L42_ASP_RX_CH_AP_SHIFT)
|
||||
#define CS42L42_ASP_RX_CH_AP_LOW 0
|
||||
#define CS42L42_ASP_RX_CH_AP_HI 1
|
||||
#define CS42L42_ASP_RX_CH_RES_SHIFT 0
|
||||
#define CS42L42_ASP_RX_CH_RES_MASK (3 << CS42L42_ASP_RX_CH_RES_SHIFT)
|
||||
#define CS42L42_ASP_RX_CH_RES_32 3
|
||||
#define CS42L42_ASP_RX_CH_RES_16 1
|
||||
#define CS42L42_ASP_RX_CH_BIT_ST_SHIFT 0
|
||||
#define CS42L42_ASP_RX_CH_BIT_ST_MASK (0xff << CS42L42_ASP_RX_CH_BIT_ST_SHIFT)
|
||||
|
||||
/* Page 0x30 ID Registers */
|
||||
#define CS42L42_SUB_REVID (CS42L42_PAGE_30 + 0x14)
|
||||
#define CS42L42_MAX_REGISTER (CS42L42_PAGE_30 + 0x14)
|
||||
|
||||
/* Defines for fracturing values spread across multiple registers */
|
||||
#define CS42L42_FRAC0_VAL(val) ((val) & 0x0000ff)
|
||||
#define CS42L42_FRAC1_VAL(val) (((val) & 0x00ff00) >> 8)
|
||||
#define CS42L42_FRAC2_VAL(val) (((val) & 0xff0000) >> 16)
|
||||
|
||||
#define CS42L42_NUM_SUPPLIES 5
|
||||
#define CS42L42_BOOT_TIME_US 3000
|
||||
#define CS42L42_PLL_DIVOUT_TIME_US 800
|
||||
#define CS42L42_CLOCK_SWITCH_DELAY_US 150
|
||||
#define CS42L42_PLL_LOCK_POLL_US 250
|
||||
#define CS42L42_PLL_LOCK_TIMEOUT_US 1250
|
||||
#define CS42L42_HP_ADC_EN_TIME_US 20000
|
||||
#define CS42L42_PDN_DONE_POLL_US 1000
|
||||
#define CS42L42_PDN_DONE_TIMEOUT_US 200000
|
||||
#define CS42L42_PDN_DONE_TIME_MS 100
|
||||
#define CS42L42_FILT_DISCHARGE_TIME_MS 46
|
||||
|
||||
#endif /* __CS42L42_H */
|
@ -59,6 +59,9 @@ struct hda_bus {
|
||||
unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
|
||||
unsigned int bus_probing :1; /* during probing process */
|
||||
unsigned int keep_power:1; /* keep power up for notification */
|
||||
unsigned int jackpoll_in_suspend:1; /* keep jack polling during
|
||||
* runtime suspend
|
||||
*/
|
||||
|
||||
int primary_dig_out_type; /* primary digital out PCM type */
|
||||
unsigned int mixer_assigned; /* codec addr for mixer name */
|
||||
|
@ -15,7 +15,8 @@ enum {
|
||||
SND_INTEL_DSP_DRIVER_LEGACY,
|
||||
SND_INTEL_DSP_DRIVER_SST,
|
||||
SND_INTEL_DSP_DRIVER_SOF,
|
||||
SND_INTEL_DSP_DRIVER_LAST = SND_INTEL_DSP_DRIVER_SOF
|
||||
SND_INTEL_DSP_DRIVER_AVS,
|
||||
SND_INTEL_DSP_DRIVER_LAST = SND_INTEL_DSP_DRIVER_AVS
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_INTEL_DSP_CONFIG)
|
||||
|
@ -25,8 +25,6 @@ enum nhlt_device_type {
|
||||
NHLT_DEVICE_INVALID
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
|
||||
|
||||
struct wav_fmt {
|
||||
u16 fmt_tag;
|
||||
u16 channels;
|
||||
@ -126,6 +124,8 @@ enum {
|
||||
NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
|
||||
|
||||
struct nhlt_acpi_table *intel_nhlt_init(struct device *dev);
|
||||
|
||||
void intel_nhlt_free(struct nhlt_acpi_table *addr);
|
||||
@ -143,8 +143,6 @@ intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
|
||||
|
||||
#else
|
||||
|
||||
struct nhlt_acpi_table;
|
||||
|
||||
static inline struct nhlt_acpi_table *intel_nhlt_init(struct device *dev)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -62,6 +62,7 @@ struct snd_jack {
|
||||
const char *id;
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
struct input_dev *input_dev;
|
||||
struct mutex input_dev_lock;
|
||||
int registered;
|
||||
int type;
|
||||
char name[100];
|
||||
|
@ -156,6 +156,7 @@ struct snd_soc_acpi_link_adr {
|
||||
* @links: array of link _ADR descriptors, null terminated.
|
||||
* @drv_name: machine driver name
|
||||
* @fw_filename: firmware file name. Used when SOF is not enabled.
|
||||
* @tplg_filename: topology file name. Used when SOF is not enabled.
|
||||
* @board: board name
|
||||
* @machine_quirk: pointer to quirk, usually based on DMI information when
|
||||
* ACPI ID alone is not sufficient, wrong or misleading
|
||||
@ -174,6 +175,7 @@ struct snd_soc_acpi_mach {
|
||||
const struct snd_soc_acpi_link_adr *links;
|
||||
const char *drv_name;
|
||||
const char *fw_filename;
|
||||
const char *tplg_filename;
|
||||
const char *board;
|
||||
struct snd_soc_acpi_mach * (*machine_quirk)(void *arg);
|
||||
const void *quirk_data;
|
||||
|
@ -16,8 +16,11 @@ enum snd_soc_card_subclass {
|
||||
struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
|
||||
const char *name);
|
||||
int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
|
||||
struct snd_soc_jack *jack,
|
||||
struct snd_soc_jack_pin *pins, unsigned int num_pins);
|
||||
struct snd_soc_jack *jack);
|
||||
int snd_soc_card_jack_new_pins(struct snd_soc_card *card, const char *id,
|
||||
int type, struct snd_soc_jack *jack,
|
||||
struct snd_soc_jack_pin *pins,
|
||||
unsigned int num_pins);
|
||||
|
||||
int snd_soc_card_suspend_pre(struct snd_soc_card *card);
|
||||
int snd_soc_card_suspend_post(struct snd_soc_card *card);
|
||||
|
@ -169,6 +169,15 @@ struct snd_soc_component_driver {
|
||||
unsigned int idle_bias_on:1;
|
||||
unsigned int suspend_bias_off:1;
|
||||
unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
|
||||
/*
|
||||
* Indicates that the component does not care about the endianness of
|
||||
* PCM audio data and the core will ensure that both LE and BE variants
|
||||
* of each used format are present. Typically this is because the
|
||||
* component sits behind a bus that abstracts away the endian of the
|
||||
* original data, ie. one for which the transmission endian is defined
|
||||
* (I2S/SLIMbus/SoundWire), or the concept of endian doesn't exist (PDM,
|
||||
* analogue).
|
||||
*/
|
||||
unsigned int endianness:1;
|
||||
unsigned int non_legacy_dai_naming:1;
|
||||
|
||||
|
@ -103,6 +103,8 @@ struct snd_soc_dpcm_runtime {
|
||||
int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */
|
||||
|
||||
int be_start; /* refcount protected by BE stream pcm lock */
|
||||
int be_pause; /* refcount protected by BE stream pcm lock */
|
||||
bool fe_pause; /* used to track STOP after PAUSE */
|
||||
};
|
||||
|
||||
#define for_each_dpcm_fe(be, stream, _dpcm) \
|
||||
|
@ -176,6 +176,8 @@
|
||||
.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_DOUBLE_R_S_VALUE(reg_left, reg_right, xshift, \
|
||||
xmin, xmax, xsign_bit, xinvert) }
|
||||
#define SOC_SINGLE_S_TLV(xname, xreg, xshift, xmin, xmax, xsign_bit, xinvert, tlv_array) \
|
||||
SOC_DOUBLE_R_S_TLV(xname, xreg, xreg, xshift, xmin, xmax, xsign_bit, xinvert, tlv_array)
|
||||
#define SOC_SINGLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
|
||||
@ -280,6 +282,23 @@
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
|
||||
xmax, xinvert) }
|
||||
#define SOC_DOUBLE_R_S_EXT_TLV(xname, reg_left, reg_right, xshift, xmin, xmax, \
|
||||
xsign_bit, xinvert, xhandler_get, xhandler_put, \
|
||||
tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE, \
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = SOC_DOUBLE_R_S_VALUE(reg_left, reg_right, xshift, \
|
||||
xmin, xmax, xsign_bit, xinvert) }
|
||||
#define SOC_SINGLE_S_EXT_TLV(xname, xreg, xshift, xmin, xmax, \
|
||||
xsign_bit, xinvert, xhandler_get, xhandler_put, \
|
||||
tlv_array) \
|
||||
SOC_DOUBLE_R_S_EXT_TLV(xname, xreg, xreg, xshift, xmin, xmax, \
|
||||
xsign_bit, xinvert, xhandler_get, xhandler_put, \
|
||||
tlv_array)
|
||||
#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_bool_ext, \
|
||||
@ -485,6 +504,8 @@ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
|
||||
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
|
||||
int snd_soc_calc_bclk(int fs, int sample_size, int channels, int tdm_slots);
|
||||
int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
|
||||
int snd_soc_tdm_params_to_bclk(struct snd_pcm_hw_params *params,
|
||||
int tdm_width, int tdm_slots, int slot_multiple);
|
||||
|
||||
/* set runtime hw params */
|
||||
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
|
||||
@ -1238,7 +1259,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
||||
const char *propname);
|
||||
int snd_soc_of_parse_aux_devs(struct snd_soc_card *card, const char *propname);
|
||||
|
||||
unsigned int snd_soc_daifmt_clock_provider_fliped(unsigned int dai_fmt);
|
||||
unsigned int snd_soc_daifmt_clock_provider_flipped(unsigned int dai_fmt);
|
||||
unsigned int snd_soc_daifmt_clock_provider_from_bitmap(unsigned int bit_frame);
|
||||
|
||||
unsigned int snd_soc_daifmt_parse_format(struct device_node *np, const char *prefix);
|
||||
@ -1263,6 +1284,10 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
|
||||
struct device_node *of_node,
|
||||
struct snd_soc_dai_link *dai_link);
|
||||
void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link);
|
||||
int snd_soc_of_get_dai_link_cpus(struct device *dev,
|
||||
struct device_node *of_node,
|
||||
struct snd_soc_dai_link *dai_link);
|
||||
void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link);
|
||||
|
||||
int snd_soc_add_pcm_runtime(struct snd_soc_card *card,
|
||||
struct snd_soc_dai_link *dai_link);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <sound/soc-acpi.h>
|
||||
|
||||
struct snd_sof_dsp_ops;
|
||||
struct snd_sof_dev;
|
||||
|
||||
/**
|
||||
* enum sof_fw_state - DSP firmware state definitions
|
||||
@ -47,6 +48,13 @@ enum sof_dsp_power_states {
|
||||
SOF_DSP_PM_D3,
|
||||
};
|
||||
|
||||
/* Definitions for multiple IPCs */
|
||||
enum sof_ipc_type {
|
||||
SOF_IPC,
|
||||
SOF_INTEL_IPC4,
|
||||
SOF_IPC_TYPE_COUNT
|
||||
};
|
||||
|
||||
/*
|
||||
* SOF Platform data.
|
||||
*/
|
||||
@ -83,6 +91,8 @@ struct snd_sof_pdata {
|
||||
const struct snd_soc_acpi_mach *machine;
|
||||
|
||||
void *hw_pdata;
|
||||
|
||||
enum sof_ipc_type ipc_type;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -115,14 +125,19 @@ struct sof_dev_desc {
|
||||
/* defaults for no codec mode */
|
||||
const char *nocodec_tplg_filename;
|
||||
|
||||
/* information on supported IPCs */
|
||||
unsigned int ipc_supported_mask;
|
||||
enum sof_ipc_type ipc_default;
|
||||
|
||||
/* defaults paths for firmware and topology files */
|
||||
const char *default_fw_path;
|
||||
const char *default_tplg_path;
|
||||
const char *default_fw_path[SOF_IPC_TYPE_COUNT];
|
||||
const char *default_tplg_path[SOF_IPC_TYPE_COUNT];
|
||||
|
||||
/* default firmware name */
|
||||
const char *default_fw_filename;
|
||||
const char *default_fw_filename[SOF_IPC_TYPE_COUNT];
|
||||
|
||||
const struct snd_sof_dsp_ops *ops;
|
||||
struct snd_sof_dsp_ops *ops;
|
||||
int (*ops_init)(struct snd_sof_dev *sdev);
|
||||
};
|
||||
|
||||
int sof_dai_get_mclk(struct snd_soc_pcm_runtime *rtd);
|
||||
|
119
include/sound/sof/ext_manifest4.h
Normal file
119
include/sound/sof/ext_manifest4.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
/*
|
||||
* 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) 2022 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extended manifest is a place to store metadata about firmware, known during
|
||||
* compilation time - for example firmware version or used compiler.
|
||||
* Given information are read on host side before firmware startup.
|
||||
* This part of output binary is not signed.
|
||||
*/
|
||||
|
||||
#ifndef __SOF_FIRMWARE_EXT_MANIFEST4_H__
|
||||
#define __SOF_FIRMWARE_EXT_MANIFEST4_H__
|
||||
|
||||
#include <linux/uuid.h>
|
||||
|
||||
/* In ASCII $AE1 */
|
||||
#define SOF_EXT_MAN4_MAGIC_NUMBER 0x31454124
|
||||
|
||||
#define MAX_MODULE_NAME_LEN 8
|
||||
#define MAX_FW_BINARY_NAME 8
|
||||
#define DEFAULT_HASH_SHA256_LEN 32
|
||||
#define SOF_MAN4_FW_HDR_OFFSET 0x2000
|
||||
#define SOF_MAN4_FW_HDR_OFFSET_CAVS_1_5 0x284
|
||||
|
||||
/*********************************************************************
|
||||
* extended manifest (struct sof_ext_manifest4_hdr)
|
||||
*-------------------
|
||||
* css_manifest hdr
|
||||
*-------------------
|
||||
* offset reserved for future
|
||||
*-------------------
|
||||
* fw_hdr (struct sof_man4_fw_binary_header)
|
||||
*-------------------
|
||||
* module_entry[0] (struct sof_man4_module)
|
||||
*-------------------
|
||||
* module_entry[1]
|
||||
*-------------------
|
||||
* ...
|
||||
*-------------------
|
||||
* module_entry[n]
|
||||
*-------------------
|
||||
* module_config[0] (struct sof_man4_module_config)
|
||||
*-------------------
|
||||
* module_config[1]
|
||||
*-------------------
|
||||
* ...
|
||||
*-------------------
|
||||
* module_config[m]
|
||||
*-------------------
|
||||
* FW content
|
||||
*-------------------
|
||||
*********************************************************************/
|
||||
|
||||
struct sof_ext_manifest4_hdr {
|
||||
uint32_t id;
|
||||
uint32_t len; /* length of extension manifest */
|
||||
uint16_t version_major; /* header version */
|
||||
uint16_t version_minor;
|
||||
uint32_t num_module_entries;
|
||||
} __packed;
|
||||
|
||||
struct sof_man4_fw_binary_header {
|
||||
/* This part must be unchanged to be backward compatible with SPT-LP ROM */
|
||||
uint32_t id;
|
||||
uint32_t len; /* sizeof(sof_man4_fw_binary_header) in bytes */
|
||||
uint8_t name[MAX_FW_BINARY_NAME];
|
||||
uint32_t preload_page_count; /* number of pages of preloaded image */
|
||||
uint32_t fw_image_flags;
|
||||
uint32_t feature_mask;
|
||||
uint16_t major_version; /* Firmware version */
|
||||
uint16_t minor_version;
|
||||
uint16_t hotfix_version;
|
||||
uint16_t build_version;
|
||||
uint32_t num_module_entries;
|
||||
|
||||
/* This part may change to contain any additional data for BaseFw that is skipped by ROM */
|
||||
uint32_t hw_buf_base_addr;
|
||||
uint32_t hw_buf_length;
|
||||
uint32_t load_offset; /* This value is used by ROM */
|
||||
} __packed;
|
||||
|
||||
struct sof_man4_segment_desc {
|
||||
uint32_t flags;
|
||||
uint32_t v_base_addr;
|
||||
uint32_t file_offset;
|
||||
} __packed;
|
||||
|
||||
struct sof_man4_module {
|
||||
uint32_t id;
|
||||
uint8_t name[MAX_MODULE_NAME_LEN];
|
||||
guid_t uuid;
|
||||
uint32_t type;
|
||||
uint8_t hash[DEFAULT_HASH_SHA256_LEN];
|
||||
uint32_t entry_point;
|
||||
uint16_t cfg_offset;
|
||||
uint16_t cfg_count;
|
||||
uint32_t affinity_mask;
|
||||
uint16_t instance_max_count;
|
||||
uint16_t instance_stack_size;
|
||||
struct sof_man4_segment_desc segments[3];
|
||||
} __packed;
|
||||
|
||||
struct sof_man4_module_config {
|
||||
uint32_t par[4]; /* module parameters */
|
||||
uint32_t is_bytes; /* actual size of instance .bss (bytes) */
|
||||
uint32_t cps; /* cycles per second */
|
||||
uint32_t ibs; /* input buffer size (bytes) */
|
||||
uint32_t obs; /* output buffer size (bytes) */
|
||||
uint32_t module_flags; /* flags, reserved for future use */
|
||||
uint32_t cpc; /* cycles per single run */
|
||||
uint32_t obls; /* output block size, reserved for future use */
|
||||
} __packed;
|
||||
|
||||
#endif /* __SOF_FIRMWARE_EXT_MANIFEST4_H__ */
|
460
include/sound/sof/ipc4/header.h
Normal file
460
include/sound/sof/ipc4/header.h
Normal file
@ -0,0 +1,460 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* 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) 2022 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_SOUND_SOF_IPC4_HEADER_H__
|
||||
#define __INCLUDE_SOUND_SOF_IPC4_HEADER_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <uapi/sound/sof/abi.h>
|
||||
|
||||
/* maximum message size for mailbox Tx/Rx */
|
||||
#define SOF_IPC4_MSG_MAX_SIZE 4096
|
||||
|
||||
/** \addtogroup sof_uapi uAPI
|
||||
* SOF uAPI specification.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_msg - Placeholder of an IPC4 message
|
||||
* @header_u64: IPC4 header as single u64 number
|
||||
* @primary: Primary, mandatory part of the header
|
||||
* @extension: Extended part of the header, if not used it should be
|
||||
* set to 0
|
||||
* @data_size: Size of data in bytes pointed by @data_ptr
|
||||
* @data_ptr: Pointer to the optional payload of a message
|
||||
*/
|
||||
struct sof_ipc4_msg {
|
||||
union {
|
||||
u64 header_u64;
|
||||
struct {
|
||||
u32 primary;
|
||||
u32 extension;
|
||||
};
|
||||
};
|
||||
|
||||
size_t data_size;
|
||||
void *data_ptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sof_ipc4_tuple - Generic type/ID and parameter tuple
|
||||
* @type: type/ID
|
||||
* @size: size of the @value array in bytes
|
||||
* @value: value for the given type
|
||||
*/
|
||||
struct sof_ipc4_tuple {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t value[];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* IPC4 messages have two 32 bit identifier made up as follows :-
|
||||
*
|
||||
* header - msg type, msg id, msg direction ...
|
||||
* extension - extra params such as msg data size in mailbox
|
||||
*
|
||||
* These are sent at the start of the IPC message in the mailbox. Messages
|
||||
* should not be sent in the doorbell (special exceptions for firmware).
|
||||
*/
|
||||
|
||||
/*
|
||||
* IPC4 primary header bit allocation for messages
|
||||
* bit 0-23: message type specific
|
||||
* bit 24-28: type: enum sof_ipc4_global_msg if target is SOF_IPC4_FW_GEN_MSG
|
||||
* enum sof_ipc4_module_type if target is SOF_IPC4_MODULE_MSG
|
||||
* bit 29: response - sof_ipc4_msg_dir
|
||||
* bit 30: target - enum sof_ipc4_msg_target
|
||||
* bit 31: reserved, unused
|
||||
*/
|
||||
|
||||
/* Value of target field - must fit into 1 bit */
|
||||
enum sof_ipc4_msg_target {
|
||||
/* Global FW message */
|
||||
SOF_IPC4_FW_GEN_MSG,
|
||||
|
||||
/* Module message */
|
||||
SOF_IPC4_MODULE_MSG
|
||||
};
|
||||
|
||||
/* Value of type field - must fit into 5 bits */
|
||||
enum sof_ipc4_global_msg {
|
||||
SOF_IPC4_GLB_BOOT_CONFIG,
|
||||
SOF_IPC4_GLB_ROM_CONTROL,
|
||||
SOF_IPC4_GLB_IPCGATEWAY_CMD,
|
||||
|
||||
/* 3 .. 12: RESERVED - do not use */
|
||||
|
||||
SOF_IPC4_GLB_PERF_MEASUREMENTS_CMD = 13,
|
||||
SOF_IPC4_GLB_CHAIN_DMA,
|
||||
|
||||
SOF_IPC4_GLB_LOAD_MULTIPLE_MODULES,
|
||||
SOF_IPC4_GLB_UNLOAD_MULTIPLE_MODULES,
|
||||
|
||||
/* pipeline settings */
|
||||
SOF_IPC4_GLB_CREATE_PIPELINE,
|
||||
SOF_IPC4_GLB_DELETE_PIPELINE,
|
||||
SOF_IPC4_GLB_SET_PIPELINE_STATE,
|
||||
SOF_IPC4_GLB_GET_PIPELINE_STATE,
|
||||
SOF_IPC4_GLB_GET_PIPELINE_CONTEXT_SIZE,
|
||||
SOF_IPC4_GLB_SAVE_PIPELINE,
|
||||
SOF_IPC4_GLB_RESTORE_PIPELINE,
|
||||
|
||||
/* Loads library (using Code Load or HD/A Host Output DMA) */
|
||||
SOF_IPC4_GLB_LOAD_LIBRARY,
|
||||
|
||||
/* 25: RESERVED - do not use */
|
||||
|
||||
SOF_IPC4_GLB_INTERNAL_MESSAGE = 26,
|
||||
|
||||
/* Notification (FW to SW driver) */
|
||||
SOF_IPC4_GLB_NOTIFICATION,
|
||||
|
||||
/* 28 .. 31: RESERVED - do not use */
|
||||
|
||||
SOF_IPC4_GLB_TYPE_LAST,
|
||||
};
|
||||
|
||||
/* Value of response field - must fit into 1 bit */
|
||||
enum sof_ipc4_msg_dir {
|
||||
SOF_IPC4_MSG_REQUEST,
|
||||
SOF_IPC4_MSG_REPLY,
|
||||
};
|
||||
|
||||
enum sof_ipc4_pipeline_state {
|
||||
SOF_IPC4_PIPE_INVALID_STATE,
|
||||
SOF_IPC4_PIPE_UNINITIALIZED,
|
||||
SOF_IPC4_PIPE_RESET,
|
||||
SOF_IPC4_PIPE_PAUSED,
|
||||
SOF_IPC4_PIPE_RUNNING,
|
||||
SOF_IPC4_PIPE_EOS
|
||||
};
|
||||
|
||||
/* Generic message fields (bit 24-30) */
|
||||
|
||||
/* encoded to header's msg_tgt field */
|
||||
#define SOF_IPC4_MSG_TARGET_SHIFT 30
|
||||
#define SOF_IPC4_MSG_TARGET_MASK BIT(30)
|
||||
#define SOF_IPC4_MSG_TARGET(x) ((x) << SOF_IPC4_MSG_TARGET_SHIFT)
|
||||
#define SOF_IPC4_MSG_IS_MODULE_MSG(x) ((x) & SOF_IPC4_MSG_TARGET_MASK ? 1 : 0)
|
||||
|
||||
/* encoded to header's rsp field */
|
||||
#define SOF_IPC4_MSG_DIR_SHIFT 29
|
||||
#define SOF_IPC4_MSG_DIR_MASK BIT(29)
|
||||
#define SOF_IPC4_MSG_DIR(x) ((x) << SOF_IPC4_MSG_DIR_SHIFT)
|
||||
|
||||
/* encoded to header's type field */
|
||||
#define SOF_IPC4_MSG_TYPE_SHIFT 24
|
||||
#define SOF_IPC4_MSG_TYPE_MASK GENMASK(28, 24)
|
||||
#define SOF_IPC4_MSG_TYPE_SET(x) (((x) << SOF_IPC4_MSG_TYPE_SHIFT) & \
|
||||
SOF_IPC4_MSG_TYPE_MASK)
|
||||
#define SOF_IPC4_MSG_TYPE_GET(x) (((x) & SOF_IPC4_MSG_TYPE_MASK) >> \
|
||||
SOF_IPC4_MSG_TYPE_SHIFT)
|
||||
|
||||
/* Global message type specific field definitions */
|
||||
|
||||
/* pipeline creation ipc msg */
|
||||
#define SOF_IPC4_GLB_PIPE_INSTANCE_SHIFT 16
|
||||
#define SOF_IPC4_GLB_PIPE_INSTANCE_MASK GENMASK(23, 16)
|
||||
#define SOF_IPC4_GLB_PIPE_INSTANCE_ID(x) ((x) << SOF_IPC4_GLB_PIPE_INSTANCE_SHIFT)
|
||||
|
||||
#define SOF_IPC4_GLB_PIPE_PRIORITY_SHIFT 11
|
||||
#define SOF_IPC4_GLB_PIPE_PRIORITY_MASK GENMASK(15, 11)
|
||||
#define SOF_IPC4_GLB_PIPE_PRIORITY(x) ((x) << SOF_IPC4_GLB_PIPE_PRIORITY_SHIFT)
|
||||
|
||||
#define SOF_IPC4_GLB_PIPE_MEM_SIZE_SHIFT 0
|
||||
#define SOF_IPC4_GLB_PIPE_MEM_SIZE_MASK GENMASK(10, 0)
|
||||
#define SOF_IPC4_GLB_PIPE_MEM_SIZE(x) ((x) << SOF_IPC4_GLB_PIPE_MEM_SIZE_SHIFT)
|
||||
|
||||
#define SOF_IPC4_GLB_PIPE_EXT_LP_SHIFT 0
|
||||
#define SOF_IPC4_GLB_PIPE_EXT_LP_MASK BIT(0)
|
||||
#define SOF_IPC4_GLB_PIPE_EXT_LP(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_LP_SHIFT)
|
||||
|
||||
/* pipeline set state ipc msg */
|
||||
#define SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT 16
|
||||
#define SOF_IPC4_GLB_PIPE_STATE_ID_MASK GENMASK(23, 16)
|
||||
#define SOF_IPC4_GLB_PIPE_STATE_ID(x) ((x) << SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT)
|
||||
|
||||
#define SOF_IPC4_GLB_PIPE_STATE_SHIFT 0
|
||||
#define SOF_IPC4_GLB_PIPE_STATE_MASK GENMASK(15, 0)
|
||||
#define SOF_IPC4_GLB_PIPE_STATE(x) ((x) << SOF_IPC4_GLB_PIPE_STATE_SHIFT)
|
||||
|
||||
enum sof_ipc4_channel_config {
|
||||
/* one channel only. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_MONO,
|
||||
/* L & R. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_STEREO,
|
||||
/* L, R & LFE; PCM only. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_2_POINT_1,
|
||||
/* L, C & R; MP3 & AAC only. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_3_POINT_0,
|
||||
/* L, C, R & LFE; PCM only. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_3_POINT_1,
|
||||
/* L, R, Ls & Rs; PCM only. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_QUATRO,
|
||||
/* L, C, R & Cs; MP3 & AAC only. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_4_POINT_0,
|
||||
/* L, C, R, Ls & Rs. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_5_POINT_0,
|
||||
/* L, C, R, Ls, Rs & LFE. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_5_POINT_1,
|
||||
/* one channel replicated in two. */
|
||||
SOF_IPC4_CHANNEL_CONFIG_DUAL_MONO,
|
||||
/* Stereo (L,R) in 4 slots, 1st stream: [ L, R, -, - ] */
|
||||
SOF_IPC4_CHANNEL_CONFIG_I2S_DUAL_STEREO_0,
|
||||
/* Stereo (L,R) in 4 slots, 2nd stream: [ -, -, L, R ] */
|
||||
SOF_IPC4_CHANNEL_CONFIG_I2S_DUAL_STEREO_1,
|
||||
/* L, C, R, Ls, Rs & LFE., LS, RS */
|
||||
SOF_IPC4_CHANNEL_CONFIG_7_POINT_1,
|
||||
};
|
||||
|
||||
enum sof_ipc4_interleaved_style {
|
||||
SOF_IPC4_CHANNELS_INTERLEAVED,
|
||||
SOF_IPC4_CHANNELS_NONINTERLEAVED,
|
||||
};
|
||||
|
||||
enum sof_ipc4_sample_type {
|
||||
SOF_IPC4_MSB_INTEGER, /* integer with Most Significant Byte first */
|
||||
SOF_IPC4_LSB_INTEGER, /* integer with Least Significant Byte first */
|
||||
};
|
||||
|
||||
struct sof_ipc4_audio_format {
|
||||
uint32_t sampling_frequency;
|
||||
uint32_t bit_depth;
|
||||
uint32_t ch_map;
|
||||
uint32_t ch_cfg; /* sof_ipc4_channel_config */
|
||||
uint32_t interleaving_style;
|
||||
uint32_t fmt_cfg; /* channels_count valid_bit_depth s_type */
|
||||
} __packed __aligned(4);
|
||||
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT_SHIFT 0
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT_MASK GENMASK(7, 0)
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(x) \
|
||||
((x) & SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT_MASK)
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH_SHIFT 8
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH_MASK GENMASK(15, 8)
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(x) \
|
||||
(((x) & SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH_MASK) >> \
|
||||
SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH_SHIFT)
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE_SHIFT 16
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE_MASK GENMASK(23, 16)
|
||||
#define SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE(x) \
|
||||
(((x) & SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE_MASK) >> \
|
||||
SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE_SHIFT)
|
||||
|
||||
/* Module message type specific field definitions */
|
||||
|
||||
enum sof_ipc4_module_type {
|
||||
SOF_IPC4_MOD_INIT_INSTANCE,
|
||||
SOF_IPC4_MOD_CONFIG_GET,
|
||||
SOF_IPC4_MOD_CONFIG_SET,
|
||||
SOF_IPC4_MOD_LARGE_CONFIG_GET,
|
||||
SOF_IPC4_MOD_LARGE_CONFIG_SET,
|
||||
SOF_IPC4_MOD_BIND,
|
||||
SOF_IPC4_MOD_UNBIND,
|
||||
SOF_IPC4_MOD_SET_DX,
|
||||
SOF_IPC4_MOD_SET_D0IX,
|
||||
SOF_IPC4_MOD_ENTER_MODULE_RESTORE,
|
||||
SOF_IPC4_MOD_EXIT_MODULE_RESTORE,
|
||||
SOF_IPC4_MOD_DELETE_INSTANCE,
|
||||
|
||||
SOF_IPC4_MOD_TYPE_LAST,
|
||||
};
|
||||
|
||||
struct sof_ipc4_base_module_cfg {
|
||||
uint32_t cpc; /* the max count of Cycles Per Chunk processing */
|
||||
uint32_t ibs; /* input Buffer Size (in bytes) */
|
||||
uint32_t obs; /* output Buffer Size (in bytes) */
|
||||
uint32_t is_pages; /* number of physical pages used */
|
||||
struct sof_ipc4_audio_format audio_fmt;
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* common module ipc msg */
|
||||
#define SOF_IPC4_MOD_INSTANCE_SHIFT 16
|
||||
#define SOF_IPC4_MOD_INSTANCE_MASK GENMASK(23, 16)
|
||||
#define SOF_IPC4_MOD_INSTANCE(x) ((x) << SOF_IPC4_MOD_INSTANCE_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_ID_SHIFT 0
|
||||
#define SOF_IPC4_MOD_ID_MASK GENMASK(15, 0)
|
||||
#define SOF_IPC4_MOD_ID(x) ((x) << SOF_IPC4_MOD_ID_SHIFT)
|
||||
|
||||
/* init module ipc msg */
|
||||
#define SOF_IPC4_MOD_EXT_PARAM_SIZE_SHIFT 0
|
||||
#define SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK GENMASK(15, 0)
|
||||
#define SOF_IPC4_MOD_EXT_PARAM_SIZE(x) ((x) << SOF_IPC4_MOD_EXT_PARAM_SIZE_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_PPL_ID_SHIFT 16
|
||||
#define SOF_IPC4_MOD_EXT_PPL_ID_MASK GENMASK(23, 16)
|
||||
#define SOF_IPC4_MOD_EXT_PPL_ID(x) ((x) << SOF_IPC4_MOD_EXT_PPL_ID_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_CORE_ID_SHIFT 24
|
||||
#define SOF_IPC4_MOD_EXT_CORE_ID_MASK GENMASK(27, 24)
|
||||
#define SOF_IPC4_MOD_EXT_CORE_ID(x) ((x) << SOF_IPC4_MOD_EXT_CORE_ID_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_DOMAIN_SHIFT 28
|
||||
#define SOF_IPC4_MOD_EXT_DOMAIN_MASK BIT(28)
|
||||
#define SOF_IPC4_MOD_EXT_DOMAIN(x) ((x) << SOF_IPC4_MOD_EXT_DOMAIN_SHIFT)
|
||||
|
||||
/* bind/unbind module ipc msg */
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_ID_SHIFT 0
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_ID_MASK GENMASK(15, 0)
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_ID(x) ((x) << SOF_IPC4_MOD_EXT_DST_MOD_ID_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE_SHIFT 16
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE_MASK GENMASK(23, 16)
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(x) ((x) << SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID_SHIFT 24
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID_MASK GENMASK(26, 24)
|
||||
#define SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(x) ((x) << SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID_SHIFT 27
|
||||
#define SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID_MASK GENMASK(29, 27)
|
||||
#define SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(x) ((x) << SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID_SHIFT)
|
||||
|
||||
#define MOD_ENABLE_LOG 6
|
||||
#define MOD_SYSTEM_TIME 20
|
||||
|
||||
/* set module large config */
|
||||
#define SOF_IPC4_MOD_EXT_MSG_SIZE_SHIFT 0
|
||||
#define SOF_IPC4_MOD_EXT_MSG_SIZE_MASK GENMASK(19, 0)
|
||||
#define SOF_IPC4_MOD_EXT_MSG_SIZE(x) ((x) << SOF_IPC4_MOD_EXT_MSG_SIZE_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_MSG_PARAM_ID_SHIFT 20
|
||||
#define SOF_IPC4_MOD_EXT_MSG_PARAM_ID_MASK GENMASK(27, 20)
|
||||
#define SOF_IPC4_MOD_EXT_MSG_PARAM_ID(x) ((x) << SOF_IPC4_MOD_EXT_MSG_PARAM_ID_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_MSG_LAST_BLOCK_SHIFT 28
|
||||
#define SOF_IPC4_MOD_EXT_MSG_LAST_BLOCK_MASK BIT(28)
|
||||
#define SOF_IPC4_MOD_EXT_MSG_LAST_BLOCK(x) ((x) << SOF_IPC4_MOD_EXT_MSG_LAST_BLOCK_SHIFT)
|
||||
|
||||
#define SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK_SHIFT 29
|
||||
#define SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK_MASK BIT(29)
|
||||
#define SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK(x) ((x) << SOF_IPC4_MOD_EXT_MSG_FIRST_BLOCK_SHIFT)
|
||||
|
||||
/* Init instance messagees */
|
||||
#define SOF_IPC4_MOD_INIT_BASEFW_MOD_ID 0
|
||||
#define SOF_IPC4_MOD_INIT_BASEFW_INSTANCE_ID 0
|
||||
|
||||
enum sof_ipc4_base_fw_params {
|
||||
SOF_IPC4_FW_PARAM_ENABLE_LOGS = 6,
|
||||
SOF_IPC4_FW_PARAM_FW_CONFIG,
|
||||
SOF_IPC4_FW_PARAM_HW_CONFIG_GET,
|
||||
SOF_IPC4_FW_PARAM_MODULES_INFO_GET,
|
||||
SOF_IPC4_FW_PARAM_LIBRARIES_INFO_GET = 16,
|
||||
SOF_IPC4_FW_PARAM_SYSTEM_TIME = 20,
|
||||
};
|
||||
|
||||
enum sof_ipc4_fw_config_params {
|
||||
SOF_IPC4_FW_CFG_FW_VERSION,
|
||||
SOF_IPC4_FW_CFG_MEMORY_RECLAIMED,
|
||||
SOF_IPC4_FW_CFG_SLOW_CLOCK_FREQ_HZ,
|
||||
SOF_IPC4_FW_CFG_FAST_CLOCK_FREQ_HZ,
|
||||
SOF_IPC4_FW_CFG_DMA_BUFFER_CONFIG,
|
||||
SOF_IPC4_FW_CFG_ALH_SUPPORT_LEVEL,
|
||||
SOF_IPC4_FW_CFG_DL_MAILBOX_BYTES,
|
||||
SOF_IPC4_FW_CFG_UL_MAILBOX_BYTES,
|
||||
SOF_IPC4_FW_CFG_TRACE_LOG_BYTES,
|
||||
SOF_IPC4_FW_CFG_MAX_PPL_COUNT,
|
||||
SOF_IPC4_FW_CFG_MAX_ASTATE_COUNT,
|
||||
SOF_IPC4_FW_CFG_MAX_MODULE_PIN_COUNT,
|
||||
SOF_IPC4_FW_CFG_MODULES_COUNT,
|
||||
SOF_IPC4_FW_CFG_MAX_MOD_INST_COUNT,
|
||||
SOF_IPC4_FW_CFG_MAX_LL_TASKS_PER_PRI_COUNT,
|
||||
SOF_IPC4_FW_CFG_LL_PRI_COUNT,
|
||||
SOF_IPC4_FW_CFG_MAX_DP_TASKS_COUNT,
|
||||
SOF_IPC4_FW_CFG_MAX_LIBS_COUNT,
|
||||
SOF_IPC4_FW_CFG_SCHEDULER_CONFIG,
|
||||
SOF_IPC4_FW_CFG_XTAL_FREQ_HZ,
|
||||
SOF_IPC4_FW_CFG_CLOCKS_CONFIG,
|
||||
SOF_IPC4_FW_CFG_RESERVED,
|
||||
SOF_IPC4_FW_CFG_POWER_GATING_POLICY,
|
||||
SOF_IPC4_FW_CFG_ASSERT_MODE,
|
||||
};
|
||||
|
||||
struct sof_ipc4_fw_version {
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
uint16_t hotfix;
|
||||
uint16_t build;
|
||||
} __packed;
|
||||
|
||||
/* Reply messages */
|
||||
|
||||
/*
|
||||
* IPC4 primary header bit allocation for replies
|
||||
* bit 0-23: status
|
||||
* bit 24-28: type: enum sof_ipc4_global_msg if target is SOF_IPC4_FW_GEN_MSG
|
||||
* enum sof_ipc4_module_type if target is SOF_IPC4_MODULE_MSG
|
||||
* bit 29: response - sof_ipc4_msg_dir
|
||||
* bit 30: target - enum sof_ipc4_msg_target
|
||||
* bit 31: reserved, unused
|
||||
*/
|
||||
|
||||
#define SOF_IPC4_REPLY_STATUS GENMASK(23, 0)
|
||||
|
||||
/* Notification messages */
|
||||
|
||||
/*
|
||||
* IPC4 primary header bit allocation for notifications
|
||||
* bit 0-15: notification type specific
|
||||
* bit 16-23: enum sof_ipc4_notification_type
|
||||
* bit 24-28: SOF_IPC4_GLB_NOTIFICATION
|
||||
* bit 29: response - sof_ipc4_msg_dir
|
||||
* bit 30: target - enum sof_ipc4_msg_target
|
||||
* bit 31: reserved, unused
|
||||
*/
|
||||
|
||||
#define SOF_IPC4_MSG_IS_NOTIFICATION(x) (SOF_IPC4_MSG_TYPE_GET(x) == \
|
||||
SOF_IPC4_GLB_NOTIFICATION)
|
||||
|
||||
#define SOF_IPC4_NOTIFICATION_TYPE_SHIFT 16
|
||||
#define SOF_IPC4_NOTIFICATION_TYPE_MASK GENMASK(23, 16)
|
||||
#define SOF_IPC4_NOTIFICATION_TYPE_GET(x) (((x) & SOF_IPC4_NOTIFICATION_TYPE_MASK) >> \
|
||||
SOF_IPC4_NOTIFICATION_TYPE_SHIFT)
|
||||
|
||||
/* Value of notification type field - must fit into 8 bits */
|
||||
enum sof_ipc4_notification_type {
|
||||
/* Phrase detected (notification from WoV module) */
|
||||
SOF_IPC4_NOTIFY_PHRASE_DETECTED = 4,
|
||||
/* Event from a resource (pipeline or module instance) */
|
||||
SOF_IPC4_NOTIFY_RESOURCE_EVENT,
|
||||
/* Debug log buffer status changed */
|
||||
SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS,
|
||||
/* Timestamp captured at the link */
|
||||
SOF_IPC4_NOTIFY_TIMESTAMP_CAPTURED,
|
||||
/* FW complete initialization */
|
||||
SOF_IPC4_NOTIFY_FW_READY,
|
||||
/* Audio classifier result (ACA) */
|
||||
SOF_IPC4_NOTIFY_FW_AUD_CLASS_RESULT,
|
||||
/* Exception caught by DSP FW */
|
||||
SOF_IPC4_NOTIFY_EXCEPTION_CAUGHT,
|
||||
/* 11 is skipped by the existing cavs firmware */
|
||||
/* Custom module notification */
|
||||
SOF_IPC4_NOTIFY_MODULE_NOTIFICATION = 12,
|
||||
/* 13 is reserved - do not use */
|
||||
/* Probe notify data available */
|
||||
SOF_IPC4_NOTIFY_PROBE_DATA_AVAILABLE = 14,
|
||||
/* AM module notifications */
|
||||
SOF_IPC4_NOTIFY_ASYNC_MSG_SRVC_MESSAGE,
|
||||
|
||||
SOF_IPC4_NOTIFY_TYPE_LAST,
|
||||
};
|
||||
|
||||
struct sof_ipc4_notify_resource_data {
|
||||
uint32_t resource_type;
|
||||
uint32_t resource_id;
|
||||
uint32_t event_type;
|
||||
uint32_t reserved;
|
||||
uint32_t data[6];
|
||||
} __packed __aligned(4);
|
||||
|
||||
/** @}*/
|
||||
|
||||
#endif
|
@ -85,8 +85,9 @@ struct sof_ipc_stream_params {
|
||||
|
||||
uint32_t host_period_bytes;
|
||||
uint16_t no_stream_position; /**< 1 means don't send stream position */
|
||||
uint8_t cont_update_posn; /**< 1 means continuous update stream position */
|
||||
|
||||
uint16_t reserved[3];
|
||||
uint8_t reserved[5];
|
||||
uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */
|
||||
} __packed;
|
||||
|
||||
|
126
include/uapi/sound/intel/avs/tokens.h
Normal file
126
include/uapi/sound/intel/avs/tokens.h
Normal file
@ -0,0 +1,126 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright(c) 2021 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Authors: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
* Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __UAPI_SOUND_INTEL_AVS_TOKENS_H
|
||||
#define __UAPI_SOUND_INTEL_AVS_TOKENS_H
|
||||
|
||||
enum avs_tplg_token {
|
||||
/* struct avs_tplg */
|
||||
AVS_TKN_MANIFEST_NAME_STRING = 1,
|
||||
AVS_TKN_MANIFEST_VERSION_U32 = 2,
|
||||
AVS_TKN_MANIFEST_NUM_LIBRARIES_U32 = 3,
|
||||
AVS_TKN_MANIFEST_NUM_AFMTS_U32 = 4,
|
||||
AVS_TKN_MANIFEST_NUM_MODCFGS_BASE_U32 = 5,
|
||||
AVS_TKN_MANIFEST_NUM_MODCFGS_EXT_U32 = 6,
|
||||
AVS_TKN_MANIFEST_NUM_PPLCFGS_U32 = 7,
|
||||
AVS_TKN_MANIFEST_NUM_BINDINGS_U32 = 8,
|
||||
|
||||
/* struct avs_tplg_library */
|
||||
AVS_TKN_LIBRARY_ID_U32 = 101,
|
||||
AVS_TKN_LIBRARY_NAME_STRING = 102,
|
||||
|
||||
/* struct avs_audio_format */
|
||||
AVS_TKN_AFMT_ID_U32 = 201,
|
||||
AVS_TKN_AFMT_SAMPLE_RATE_U32 = 202,
|
||||
AVS_TKN_AFMT_BIT_DEPTH_U32 = 203,
|
||||
AVS_TKN_AFMT_CHANNEL_MAP_U32 = 204,
|
||||
AVS_TKN_AFMT_CHANNEL_CFG_U32 = 205,
|
||||
AVS_TKN_AFMT_INTERLEAVING_U32 = 206,
|
||||
AVS_TKN_AFMT_NUM_CHANNELS_U32 = 207,
|
||||
AVS_TKN_AFMT_VALID_BIT_DEPTH_U32 = 208,
|
||||
AVS_TKN_AFMT_SAMPLE_TYPE_U32 = 209,
|
||||
|
||||
/* struct avs_tplg_modcfg_base */
|
||||
AVS_TKN_MODCFG_BASE_ID_U32 = 301,
|
||||
AVS_TKN_MODCFG_BASE_CPC_U32 = 302,
|
||||
AVS_TKN_MODCFG_BASE_IBS_U32 = 303,
|
||||
AVS_TKN_MODCFG_BASE_OBS_U32 = 304,
|
||||
AVS_TKN_MODCFG_BASE_PAGES_U32 = 305,
|
||||
|
||||
/* struct avs_tplg_modcfg_ext */
|
||||
AVS_TKN_MODCFG_EXT_ID_U32 = 401,
|
||||
AVS_TKN_MODCFG_EXT_TYPE_UUID = 402,
|
||||
AVS_TKN_MODCFG_CPR_OUT_AFMT_ID_U32 = 403,
|
||||
AVS_TKN_MODCFG_CPR_FEATURE_MASK_U32 = 404,
|
||||
AVS_TKN_MODCFG_CPR_DMA_TYPE_U32 = 405,
|
||||
AVS_TKN_MODCFG_CPR_DMABUFF_SIZE_U32 = 406,
|
||||
AVS_TKN_MODCFG_CPR_VINDEX_U8 = 407,
|
||||
AVS_TKN_MODCFG_CPR_BLOB_FMT_ID_U32 = 408,
|
||||
AVS_TKN_MODCFG_MICSEL_OUT_AFMT_ID_U32 = 409,
|
||||
AVS_TKN_MODCFG_INTELWOV_CPC_LP_MODE_U32 = 410,
|
||||
AVS_TKN_MODCFG_SRC_OUT_FREQ_U32 = 411,
|
||||
AVS_TKN_MODCFG_MUX_REF_AFMT_ID_U32 = 412,
|
||||
AVS_TKN_MODCFG_MUX_OUT_AFMT_ID_U32 = 413,
|
||||
AVS_TKN_MODCFG_AEC_REF_AFMT_ID_U32 = 414,
|
||||
AVS_TKN_MODCFG_AEC_OUT_AFMT_ID_U32 = 415,
|
||||
AVS_TKN_MODCFG_AEC_CPC_LP_MODE_U32 = 416,
|
||||
AVS_TKN_MODCFG_ASRC_OUT_FREQ_U32 = 417,
|
||||
AVS_TKN_MODCFG_ASRC_MODE_U8 = 418,
|
||||
AVS_TKN_MODCFG_ASRC_DISABLE_JITTER_U8 = 419,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_OUT_CHAN_CFG_U32 = 420,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_SELECT_U32 = 421,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_0_S32 = 422,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_1_S32 = 423,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_2_S32 = 424,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_3_S32 = 425,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_4_S32 = 426,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_5_S32 = 427,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_6_S32 = 428,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_COEFF_7_S32 = 429,
|
||||
AVS_TKN_MODCFG_UPDOWN_MIX_CHAN_MAP_U32 = 430,
|
||||
AVS_TKN_MODCFG_EXT_NUM_INPUT_PINS_U16 = 431,
|
||||
AVS_TKN_MODCFG_EXT_NUM_OUTPUT_PINS_U16 = 432,
|
||||
|
||||
/* struct avs_tplg_pplcfg */
|
||||
AVS_TKN_PPLCFG_ID_U32 = 1401,
|
||||
AVS_TKN_PPLCFG_REQ_SIZE_U16 = 1402,
|
||||
AVS_TKN_PPLCFG_PRIORITY_U8 = 1403,
|
||||
AVS_TKN_PPLCFG_LOW_POWER_BOOL = 1404,
|
||||
AVS_TKN_PPLCFG_ATTRIBUTES_U16 = 1405,
|
||||
AVS_TKN_PPLCFG_TRIGGER_U32 = 1406,
|
||||
|
||||
/* struct avs_tplg_binding */
|
||||
AVS_TKN_BINDING_ID_U32 = 1501,
|
||||
AVS_TKN_BINDING_TARGET_TPLG_NAME_STRING = 1502,
|
||||
AVS_TKN_BINDING_TARGET_PATH_TMPL_ID_U32 = 1503,
|
||||
AVS_TKN_BINDING_TARGET_PPL_ID_U32 = 1504,
|
||||
AVS_TKN_BINDING_TARGET_MOD_ID_U32 = 1505,
|
||||
AVS_TKN_BINDING_TARGET_MOD_PIN_U8 = 1506,
|
||||
AVS_TKN_BINDING_MOD_ID_U32 = 1507,
|
||||
AVS_TKN_BINDING_MOD_PIN_U8 = 1508,
|
||||
AVS_TKN_BINDING_IS_SINK_U8 = 1509,
|
||||
|
||||
/* struct avs_tplg_pipeline */
|
||||
AVS_TKN_PPL_ID_U32 = 1601,
|
||||
AVS_TKN_PPL_PPLCFG_ID_U32 = 1602,
|
||||
AVS_TKN_PPL_NUM_BINDING_IDS_U32 = 1603,
|
||||
AVS_TKN_PPL_BINDING_ID_U32 = 1604,
|
||||
|
||||
/* struct avs_tplg_module */
|
||||
AVS_TKN_MOD_ID_U32 = 1701,
|
||||
AVS_TKN_MOD_MODCFG_BASE_ID_U32 = 1702,
|
||||
AVS_TKN_MOD_IN_AFMT_ID_U32 = 1703,
|
||||
AVS_TKN_MOD_CORE_ID_U8 = 1704,
|
||||
AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
|
||||
AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
|
||||
|
||||
/* struct avs_tplg_path_template */
|
||||
AVS_TKN_PATH_TMPL_ID_U32 = 1801,
|
||||
|
||||
/* struct avs_tplg_path */
|
||||
AVS_TKN_PATH_ID_U32 = 1901,
|
||||
AVS_TKN_PATH_FE_FMT_ID_U32 = 1902,
|
||||
AVS_TKN_PATH_BE_FMT_ID_U32 = 1903,
|
||||
|
||||
/* struct avs_tplg_pin_format */
|
||||
AVS_TKN_PIN_FMT_INDEX_U32 = 2201,
|
||||
AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
|
||||
AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
|
||||
};
|
||||
|
||||
#endif
|
@ -26,8 +26,8 @@
|
||||
|
||||
/* SOF ABI version major, minor and patch numbers */
|
||||
#define SOF_ABI_MAJOR 3
|
||||
#define SOF_ABI_MINOR 19
|
||||
#define SOF_ABI_PATCH 1
|
||||
#define SOF_ABI_MINOR 21
|
||||
#define SOF_ABI_PATCH 0
|
||||
|
||||
/* SOF ABI version number. Format within 32bit word is MMmmmppp */
|
||||
#define SOF_ABI_MAJOR_SHIFT 24
|
||||
|
@ -42,8 +42,11 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
struct snd_jack *jack = device->device_data;
|
||||
|
||||
if (!jack->input_dev)
|
||||
mutex_lock(&jack->input_dev_lock);
|
||||
if (!jack->input_dev) {
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the input device is registered with the input subsystem
|
||||
* then we need to use a different deallocator. */
|
||||
@ -52,6 +55,7 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
|
||||
else
|
||||
input_free_device(jack->input_dev);
|
||||
jack->input_dev = NULL;
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
return 0;
|
||||
}
|
||||
@ -90,8 +94,11 @@ static int snd_jack_dev_register(struct snd_device *device)
|
||||
snprintf(jack->name, sizeof(jack->name), "%s %s",
|
||||
card->shortname, jack->id);
|
||||
|
||||
if (!jack->input_dev)
|
||||
mutex_lock(&jack->input_dev_lock);
|
||||
if (!jack->input_dev) {
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack->input_dev->name = jack->name;
|
||||
|
||||
@ -116,6 +123,7 @@ static int snd_jack_dev_register(struct snd_device *device)
|
||||
if (err == 0)
|
||||
jack->registered = 1;
|
||||
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
@ -517,9 +525,11 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* don't creat input device for phantom jack */
|
||||
if (!phantom_jack) {
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
mutex_init(&jack->input_dev_lock);
|
||||
|
||||
/* don't create input device for phantom jack */
|
||||
if (!phantom_jack) {
|
||||
int i;
|
||||
|
||||
jack->input_dev = input_allocate_device();
|
||||
@ -537,8 +547,8 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
|
||||
input_set_capability(jack->input_dev, EV_SW,
|
||||
jack_switch_types[i]);
|
||||
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
}
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
|
||||
if (err < 0)
|
||||
@ -578,10 +588,14 @@ EXPORT_SYMBOL(snd_jack_new);
|
||||
void snd_jack_set_parent(struct snd_jack *jack, struct device *parent)
|
||||
{
|
||||
WARN_ON(jack->registered);
|
||||
if (!jack->input_dev)
|
||||
mutex_lock(&jack->input_dev_lock);
|
||||
if (!jack->input_dev) {
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
jack->input_dev->dev.parent = parent;
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_jack_set_parent);
|
||||
|
||||
@ -629,6 +643,8 @@ EXPORT_SYMBOL(snd_jack_set_key);
|
||||
|
||||
/**
|
||||
* snd_jack_report - Report the current status of a jack
|
||||
* Note: This function uses mutexes and should be called from a
|
||||
* context which can sleep (such as a workqueue).
|
||||
*
|
||||
* @jack: The jack to report status for
|
||||
* @status: The current status of the jack
|
||||
@ -654,8 +670,11 @@ void snd_jack_report(struct snd_jack *jack, int status)
|
||||
status & jack_kctl->mask_bits);
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
if (!jack->input_dev)
|
||||
mutex_lock(&jack->input_dev_lock);
|
||||
if (!jack->input_dev) {
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
|
||||
int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits);
|
||||
@ -675,6 +694,7 @@ void snd_jack_report(struct snd_jack *jack, int status)
|
||||
}
|
||||
|
||||
input_sync(jack->input_dev);
|
||||
mutex_unlock(&jack->input_dev_lock);
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
}
|
||||
EXPORT_SYMBOL(snd_jack_report);
|
||||
|
@ -453,7 +453,6 @@ EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
|
||||
*/
|
||||
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_card *card = substream->pcm->card;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
@ -462,6 +461,8 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
|
||||
if (runtime->dma_area == NULL)
|
||||
return 0;
|
||||
if (runtime->dma_buffer_p != &substream->dma_buffer) {
|
||||
struct snd_card *card = substream->pcm->card;
|
||||
|
||||
/* it's a newly allocated buffer. release it now. */
|
||||
do_free_pages(card, runtime->dma_buffer_p);
|
||||
kfree(runtime->dma_buffer_p);
|
||||
|
@ -139,7 +139,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
|
||||
port_subs_info_init(&new_port->c_dest);
|
||||
snd_use_lock_use(&new_port->use_lock);
|
||||
|
||||
num = port >= 0 ? port : 0;
|
||||
num = max(port, 0);
|
||||
mutex_lock(&client->ports_mutex);
|
||||
write_lock_irq(&client->ports_lock);
|
||||
list_for_each_entry(p, &client->ports_list_head, list) {
|
||||
|
@ -165,6 +165,24 @@ config SND_SERIAL_U16550
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-serial-u16550.
|
||||
|
||||
config SND_SERIAL_GENERIC
|
||||
tristate "Generic serial MIDI driver"
|
||||
depends on SERIAL_DEV_BUS
|
||||
depends on OF
|
||||
select SND_RAWMIDI
|
||||
help
|
||||
To include support for mapping generic serial devices as raw
|
||||
ALSA MIDI devices, say Y here. The driver only supports setting
|
||||
the serial port to standard baudrates. To attain the standard MIDI
|
||||
baudrate of 31.25 kBaud, configure the clock of the underlying serial
|
||||
device so that a requested 38.4 kBaud will result in the standard speed.
|
||||
|
||||
Use this devicetree binding to configure serial port mapping
|
||||
<file:Documentation/devicetree/bindings/sound/serial-midi.yaml>
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-serial-generic.
|
||||
|
||||
config SND_MPU401
|
||||
tristate "Generic MPU-401 UART driver"
|
||||
select SND_MPU401_UART
|
||||
|
@ -10,6 +10,7 @@ snd-mtpav-objs := mtpav.o
|
||||
snd-mts64-objs := mts64.o
|
||||
snd-portman2x4-objs := portman2x4.o
|
||||
snd-serial-u16550-objs := serial-u16550.o
|
||||
snd-serial-generic-objs := serial-generic.o
|
||||
snd-virmidi-objs := virmidi.o
|
||||
|
||||
# Toplevel Module Dependency
|
||||
@ -17,6 +18,7 @@ obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
|
||||
obj-$(CONFIG_SND_ALOOP) += snd-aloop.o
|
||||
obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o
|
||||
obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o
|
||||
obj-$(CONFIG_SND_SERIAL_GENERIC) += snd-serial-generic.o
|
||||
obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
|
||||
obj-$(CONFIG_SND_MTS64) += snd-mts64.o
|
||||
obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
|
||||
|
374
sound/drivers/serial-generic.c
Normal file
374
sound/drivers/serial-generic.c
Normal file
@ -0,0 +1,374 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* serial-generic.c
|
||||
* Copyright (c) by Daniel Kaehn <kaehndan@gmail.com
|
||||
* Based on serial-u16550.c by Jaroslav Kysela <perex@perex.cz>,
|
||||
* Isaku Yamahata <yamahata@private.email.ne.jp>,
|
||||
* George Hansper <ghansper@apana.org.au>,
|
||||
* Hannu Savolainen
|
||||
*
|
||||
* Generic serial MIDI driver using the serdev serial bus API for hardware interaction
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/serdev.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dev_printk.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/rawmidi.h>
|
||||
#include <sound/initval.h>
|
||||
|
||||
MODULE_DESCRIPTION("Generic serial MIDI driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#define SERIAL_MODE_INPUT_OPEN 1
|
||||
#define SERIAL_MODE_OUTPUT_OPEN 2
|
||||
#define SERIAL_MODE_INPUT_TRIGGERED 3
|
||||
#define SERIAL_MODE_OUTPUT_TRIGGERED 4
|
||||
|
||||
#define SERIAL_TX_STATE_ACTIVE 1
|
||||
#define SERIAL_TX_STATE_WAKEUP 2
|
||||
|
||||
struct snd_serial_generic {
|
||||
struct serdev_device *serdev;
|
||||
|
||||
struct snd_card *card;
|
||||
struct snd_rawmidi *rmidi;
|
||||
struct snd_rawmidi_substream *midi_output;
|
||||
struct snd_rawmidi_substream *midi_input;
|
||||
|
||||
unsigned int baudrate;
|
||||
|
||||
unsigned long filemode; /* open status of file */
|
||||
struct work_struct tx_work;
|
||||
unsigned long tx_state;
|
||||
|
||||
};
|
||||
|
||||
static void snd_serial_generic_tx_wakeup(struct snd_serial_generic *drvdata)
|
||||
{
|
||||
if (test_and_set_bit(SERIAL_TX_STATE_ACTIVE, &drvdata->tx_state))
|
||||
set_bit(SERIAL_TX_STATE_WAKEUP, &drvdata->tx_state);
|
||||
|
||||
schedule_work(&drvdata->tx_work);
|
||||
}
|
||||
|
||||
#define INTERNAL_BUF_SIZE 256
|
||||
|
||||
static void snd_serial_generic_tx_work(struct work_struct *work)
|
||||
{
|
||||
static char buf[INTERNAL_BUF_SIZE];
|
||||
int num_bytes;
|
||||
struct snd_serial_generic *drvdata = container_of(work, struct snd_serial_generic,
|
||||
tx_work);
|
||||
struct snd_rawmidi_substream *substream = drvdata->midi_output;
|
||||
|
||||
clear_bit(SERIAL_TX_STATE_WAKEUP, &drvdata->tx_state);
|
||||
|
||||
while (!snd_rawmidi_transmit_empty(substream)) {
|
||||
|
||||
if (!test_bit(SERIAL_MODE_OUTPUT_OPEN, &drvdata->filemode))
|
||||
break;
|
||||
|
||||
num_bytes = snd_rawmidi_transmit_peek(substream, buf, INTERNAL_BUF_SIZE);
|
||||
num_bytes = serdev_device_write_buf(drvdata->serdev, buf, num_bytes);
|
||||
|
||||
if (!num_bytes)
|
||||
break;
|
||||
|
||||
snd_rawmidi_transmit_ack(substream, num_bytes);
|
||||
|
||||
if (!test_bit(SERIAL_TX_STATE_WAKEUP, &drvdata->tx_state))
|
||||
break;
|
||||
}
|
||||
|
||||
clear_bit(SERIAL_TX_STATE_ACTIVE, &drvdata->tx_state);
|
||||
}
|
||||
|
||||
static void snd_serial_generic_write_wakeup(struct serdev_device *serdev)
|
||||
{
|
||||
struct snd_serial_generic *drvdata = serdev_device_get_drvdata(serdev);
|
||||
|
||||
snd_serial_generic_tx_wakeup(drvdata);
|
||||
}
|
||||
|
||||
static int snd_serial_generic_receive_buf(struct serdev_device *serdev,
|
||||
const unsigned char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
struct snd_serial_generic *drvdata = serdev_device_get_drvdata(serdev);
|
||||
|
||||
if (!test_bit(SERIAL_MODE_INPUT_OPEN, &drvdata->filemode))
|
||||
return 0;
|
||||
|
||||
ret = snd_rawmidi_receive(drvdata->midi_input, buf, count);
|
||||
return ret < 0 ? 0 : ret;
|
||||
}
|
||||
|
||||
static const struct serdev_device_ops snd_serial_generic_serdev_device_ops = {
|
||||
.receive_buf = snd_serial_generic_receive_buf,
|
||||
.write_wakeup = snd_serial_generic_write_wakeup
|
||||
};
|
||||
|
||||
static int snd_serial_generic_ensure_serdev_open(struct snd_serial_generic *drvdata)
|
||||
{
|
||||
int err;
|
||||
unsigned int actual_baud;
|
||||
|
||||
if (drvdata->filemode)
|
||||
return 0;
|
||||
|
||||
dev_dbg(drvdata->card->dev, "Opening serial port for card %s\n",
|
||||
drvdata->card->shortname);
|
||||
err = serdev_device_open(drvdata->serdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
actual_baud = serdev_device_set_baudrate(drvdata->serdev,
|
||||
drvdata->baudrate);
|
||||
if (actual_baud != drvdata->baudrate) {
|
||||
dev_warn(drvdata->card->dev, "requested %d baud for card %s but it was actually set to %d\n",
|
||||
drvdata->baudrate, drvdata->card->shortname, actual_baud);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_serial_generic_input_open(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
int err;
|
||||
struct snd_serial_generic *drvdata = substream->rmidi->card->private_data;
|
||||
|
||||
dev_dbg(drvdata->card->dev, "Opening input for card %s\n",
|
||||
drvdata->card->shortname);
|
||||
|
||||
err = snd_serial_generic_ensure_serdev_open(drvdata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
set_bit(SERIAL_MODE_INPUT_OPEN, &drvdata->filemode);
|
||||
drvdata->midi_input = substream;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_serial_generic_input_close(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_serial_generic *drvdata = substream->rmidi->card->private_data;
|
||||
|
||||
dev_dbg(drvdata->card->dev, "Closing input for card %s\n",
|
||||
drvdata->card->shortname);
|
||||
|
||||
clear_bit(SERIAL_MODE_INPUT_OPEN, &drvdata->filemode);
|
||||
clear_bit(SERIAL_MODE_INPUT_TRIGGERED, &drvdata->filemode);
|
||||
|
||||
drvdata->midi_input = NULL;
|
||||
|
||||
if (!drvdata->filemode)
|
||||
serdev_device_close(drvdata->serdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_serial_generic_input_trigger(struct snd_rawmidi_substream *substream,
|
||||
int up)
|
||||
{
|
||||
struct snd_serial_generic *drvdata = substream->rmidi->card->private_data;
|
||||
|
||||
if (up)
|
||||
set_bit(SERIAL_MODE_INPUT_TRIGGERED, &drvdata->filemode);
|
||||
else
|
||||
clear_bit(SERIAL_MODE_INPUT_TRIGGERED, &drvdata->filemode);
|
||||
}
|
||||
|
||||
static int snd_serial_generic_output_open(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_serial_generic *drvdata = substream->rmidi->card->private_data;
|
||||
int err;
|
||||
|
||||
dev_dbg(drvdata->card->dev, "Opening output for card %s\n",
|
||||
drvdata->card->shortname);
|
||||
|
||||
err = snd_serial_generic_ensure_serdev_open(drvdata);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
set_bit(SERIAL_MODE_OUTPUT_OPEN, &drvdata->filemode);
|
||||
|
||||
drvdata->midi_output = substream;
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int snd_serial_generic_output_close(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_serial_generic *drvdata = substream->rmidi->card->private_data;
|
||||
|
||||
dev_dbg(drvdata->card->dev, "Closing output for card %s\n",
|
||||
drvdata->card->shortname);
|
||||
|
||||
clear_bit(SERIAL_MODE_OUTPUT_OPEN, &drvdata->filemode);
|
||||
clear_bit(SERIAL_MODE_OUTPUT_TRIGGERED, &drvdata->filemode);
|
||||
|
||||
if (!drvdata->filemode)
|
||||
serdev_device_close(drvdata->serdev);
|
||||
|
||||
drvdata->midi_output = NULL;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static void snd_serial_generic_output_trigger(struct snd_rawmidi_substream *substream,
|
||||
int up)
|
||||
{
|
||||
struct snd_serial_generic *drvdata = substream->rmidi->card->private_data;
|
||||
|
||||
if (up)
|
||||
set_bit(SERIAL_MODE_OUTPUT_TRIGGERED, &drvdata->filemode);
|
||||
else
|
||||
clear_bit(SERIAL_MODE_OUTPUT_TRIGGERED, &drvdata->filemode);
|
||||
|
||||
if (up)
|
||||
snd_serial_generic_tx_wakeup(drvdata);
|
||||
}
|
||||
|
||||
static void snd_serial_generic_output_drain(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct snd_serial_generic *drvdata = substream->rmidi->card->private_data;
|
||||
|
||||
/* Flush any pending characters */
|
||||
serdev_device_write_flush(drvdata->serdev);
|
||||
cancel_work_sync(&drvdata->tx_work);
|
||||
}
|
||||
|
||||
static const struct snd_rawmidi_ops snd_serial_generic_output = {
|
||||
.open = snd_serial_generic_output_open,
|
||||
.close = snd_serial_generic_output_close,
|
||||
.trigger = snd_serial_generic_output_trigger,
|
||||
.drain = snd_serial_generic_output_drain,
|
||||
};
|
||||
|
||||
static const struct snd_rawmidi_ops snd_serial_generic_input = {
|
||||
.open = snd_serial_generic_input_open,
|
||||
.close = snd_serial_generic_input_close,
|
||||
.trigger = snd_serial_generic_input_trigger,
|
||||
};
|
||||
|
||||
static void snd_serial_generic_parse_dt(struct serdev_device *serdev,
|
||||
struct snd_serial_generic *drvdata)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = of_property_read_u32(serdev->dev.of_node, "current-speed",
|
||||
&drvdata->baudrate);
|
||||
if (err < 0) {
|
||||
dev_dbg(drvdata->card->dev,
|
||||
"MIDI device reading of current-speed DT param failed with error %d, using default of 38400\n",
|
||||
err);
|
||||
drvdata->baudrate = 38400;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void snd_serial_generic_substreams(struct snd_rawmidi_str *stream, int dev_num)
|
||||
{
|
||||
struct snd_rawmidi_substream *substream;
|
||||
|
||||
list_for_each_entry(substream, &stream->substreams, list) {
|
||||
sprintf(substream->name, "Serial MIDI %d-%d", dev_num, substream->number);
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_serial_generic_rmidi(struct snd_serial_generic *drvdata,
|
||||
int outs, int ins, struct snd_rawmidi **rmidi)
|
||||
{
|
||||
struct snd_rawmidi *rrawmidi;
|
||||
int err;
|
||||
|
||||
err = snd_rawmidi_new(drvdata->card, drvdata->card->driver, 0,
|
||||
outs, ins, &rrawmidi);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT,
|
||||
&snd_serial_generic_input);
|
||||
snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&snd_serial_generic_output);
|
||||
strcpy(rrawmidi->name, drvdata->card->shortname);
|
||||
|
||||
snd_serial_generic_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
|
||||
drvdata->serdev->ctrl->nr);
|
||||
snd_serial_generic_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
|
||||
drvdata->serdev->ctrl->nr);
|
||||
|
||||
rrawmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
|
||||
SNDRV_RAWMIDI_INFO_INPUT |
|
||||
SNDRV_RAWMIDI_INFO_DUPLEX;
|
||||
|
||||
if (rmidi)
|
||||
*rmidi = rrawmidi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_serial_generic_probe(struct serdev_device *serdev)
|
||||
{
|
||||
struct snd_card *card;
|
||||
struct snd_serial_generic *drvdata;
|
||||
int err;
|
||||
|
||||
err = snd_devm_card_new(&serdev->dev, SNDRV_DEFAULT_IDX1,
|
||||
SNDRV_DEFAULT_STR1, THIS_MODULE,
|
||||
sizeof(struct snd_serial_generic), &card);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, "SerialMIDI");
|
||||
sprintf(card->shortname, "SerialMIDI-%d", serdev->ctrl->nr);
|
||||
sprintf(card->longname, "Serial MIDI device at serial%d", serdev->ctrl->nr);
|
||||
|
||||
drvdata = card->private_data;
|
||||
|
||||
drvdata->serdev = serdev;
|
||||
drvdata->card = card;
|
||||
|
||||
snd_serial_generic_parse_dt(serdev, drvdata);
|
||||
|
||||
INIT_WORK(&drvdata->tx_work, snd_serial_generic_tx_work);
|
||||
|
||||
err = snd_serial_generic_rmidi(drvdata, 1, 1, &drvdata->rmidi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
serdev_device_set_client_ops(serdev, &snd_serial_generic_serdev_device_ops);
|
||||
serdev_device_set_drvdata(drvdata->serdev, drvdata);
|
||||
|
||||
err = snd_card_register(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id snd_serial_generic_dt_ids[] = {
|
||||
{ .compatible = "serial-midi" },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, snd_serial_generic_dt_ids);
|
||||
|
||||
static struct serdev_device_driver snd_serial_generic_driver = {
|
||||
.driver = {
|
||||
.name = "snd-serial-generic",
|
||||
.of_match_table = of_match_ptr(snd_serial_generic_dt_ids),
|
||||
},
|
||||
.probe = snd_serial_generic_probe,
|
||||
};
|
||||
|
||||
module_serdev_device_driver(snd_serial_generic_driver);
|
@ -129,7 +129,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
|
||||
return 0;
|
||||
|
||||
/* the u32 cast is okay because in snd*create we successfully told
|
||||
pci alloc that we're only 32 bit capable so the uppper will be 0 */
|
||||
pci alloc that we're only 32 bit capable so the upper will be 0 */
|
||||
addr = (u32) substream->runtime->dma_addr;
|
||||
desc_addr = (u32) dma->desc_buf.addr;
|
||||
for (i = 0; i < periods; i++) {
|
||||
|
@ -36,6 +36,7 @@
|
||||
| ((IEC958_AES3_CON_FS_48000) << 24))
|
||||
|
||||
static const struct snd_pci_quirk subsys_20k1_list[] = {
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0021, "SB046x", CTSB046X),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X),
|
||||
@ -64,6 +65,7 @@ static const struct snd_pci_quirk subsys_20k2_list[] = {
|
||||
|
||||
static const char *ct_subsys_name[NUM_CTCARDS] = {
|
||||
/* 20k1 models */
|
||||
[CTSB046X] = "SB046x",
|
||||
[CTSB055X] = "SB055x",
|
||||
[CTSB073X] = "SB073x",
|
||||
[CTUAA] = "UAA",
|
||||
|
@ -26,8 +26,9 @@ enum CHIPTYP {
|
||||
|
||||
enum CTCARDS {
|
||||
/* 20k1 models */
|
||||
CTSB046X,
|
||||
CT20K1_MODEL_FIRST = CTSB046X,
|
||||
CTSB055X,
|
||||
CT20K1_MODEL_FIRST = CTSB055X,
|
||||
CTSB073X,
|
||||
CTUAA,
|
||||
CT20K1_UNKNOWN,
|
||||
|
@ -1916,7 +1916,7 @@ static int hw_card_start(struct hw *hw)
|
||||
|
||||
}
|
||||
|
||||
/* Switch to X-Fi mode from UAA mode if neeeded */
|
||||
/* Switch to X-Fi mode from UAA mode if needed */
|
||||
if (hw->model == CTUAA) {
|
||||
err = uaa_to_xfi(pci);
|
||||
if (err)
|
||||
|
@ -124,7 +124,6 @@ static int midi_service_irq(struct echoaudio *chip)
|
||||
return 0;
|
||||
|
||||
/* Get the MIDI data from the comm page */
|
||||
i = 1;
|
||||
received = 0;
|
||||
for (i = 1; i <= count; i++) {
|
||||
/* Get the MIDI byte */
|
||||
|
@ -1751,11 +1751,8 @@ static void snd_emu10k1_detect_iommu(struct snd_emu10k1 *emu)
|
||||
|
||||
emu->iommu_workaround = false;
|
||||
|
||||
if (!iommu_present(emu->card->dev->bus))
|
||||
return;
|
||||
|
||||
domain = iommu_get_domain_for_dev(emu->card->dev);
|
||||
if (domain && domain->type == IOMMU_DOMAIN_IDENTITY)
|
||||
if (!domain || domain->type == IOMMU_DOMAIN_IDENTITY)
|
||||
return;
|
||||
|
||||
dev_notice(emu->card->dev,
|
||||
|
@ -102,6 +102,7 @@ config SND_HDA_SCODEC_CS35L41_I2C
|
||||
select SND_HDA_GENERIC
|
||||
select SND_SOC_CS35L41_LIB
|
||||
select SND_HDA_SCODEC_CS35L41
|
||||
select REGMAP_IRQ
|
||||
help
|
||||
Say Y or M here to include CS35L41 I2C HD-audio side codec support
|
||||
in snd-hda-intel driver, such as ALC287.
|
||||
@ -117,6 +118,7 @@ config SND_HDA_SCODEC_CS35L41_SPI
|
||||
select SND_HDA_GENERIC
|
||||
select SND_SOC_CS35L41_LIB
|
||||
select SND_HDA_SCODEC_CS35L41
|
||||
select REGMAP_IRQ
|
||||
help
|
||||
Say Y or M here to include CS35L41 SPI HD-audio side codec support
|
||||
in snd-hda-intel driver, such as ALC287.
|
||||
|
@ -17,163 +17,88 @@
|
||||
#include "cs35l41_hda.h"
|
||||
|
||||
static const struct reg_sequence cs35l41_hda_config[] = {
|
||||
{ CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3200000Hz, BCLK Input, PLL_REFCLK_EN = 1
|
||||
{ CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1
|
||||
{ CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz
|
||||
{ CS35L41_SP_ENABLES, 0x00010000 }, // ASP_RX1_EN = 1
|
||||
{ CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz
|
||||
{ CS35L41_SP_FORMAT, 0x20200200 }, // 24 bits, I2S, BCLK Slave, FSYNC Slave
|
||||
{ CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer
|
||||
{ CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1
|
||||
{ CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB
|
||||
{ CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB
|
||||
{ CS35L41_PWR_CTRL2, 0x00000001 }, // AMP_EN = 1
|
||||
};
|
||||
|
||||
static const struct reg_sequence cs35l41_hda_start_bst[] = {
|
||||
{ CS35L41_PWR_CTRL2, 0x00000021 }, // BST_EN = 10, AMP_EN = 1
|
||||
{ CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1
|
||||
};
|
||||
|
||||
static const struct reg_sequence cs35l41_hda_stop_bst[] = {
|
||||
{ CS35L41_PWR_CTRL1, 0x00000000, 3000}, // set GLOBAL_EN = 0
|
||||
};
|
||||
|
||||
// only on amps where GPIO1 is used to control ext. VSPK switch
|
||||
static const struct reg_sequence cs35l41_start_ext_vspk[] = {
|
||||
{ 0x00000040, 0x00000055 },
|
||||
{ 0x00000040, 0x000000AA },
|
||||
{ 0x00007438, 0x00585941 },
|
||||
{ 0x00007414, 0x08C82222 },
|
||||
{ 0x0000742C, 0x00000009 },
|
||||
{ 0x00011008, 0x00008001 },
|
||||
{ 0x0000742C, 0x0000000F },
|
||||
{ 0x0000742C, 0x00000079 },
|
||||
{ 0x00007438, 0x00585941 },
|
||||
{ CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1
|
||||
{ 0x0000742C, 0x000000F9 },
|
||||
{ 0x00007438, 0x00580941 },
|
||||
{ 0x00000040, 0x000000CC },
|
||||
{ 0x00000040, 0x00000033 },
|
||||
};
|
||||
|
||||
//only on amps where GPIO1 is used to control ext. VSPK switch
|
||||
static const struct reg_sequence cs35l41_stop_ext_vspk[] = {
|
||||
{ 0x00000040, 0x00000055 },
|
||||
{ 0x00000040, 0x000000AA },
|
||||
{ 0x00007438, 0x00585941 },
|
||||
{ 0x00002014, 0x00000000, 3000}, // set GLOBAL_EN = 0
|
||||
{ 0x0000742C, 0x00000009 },
|
||||
{ 0x00007438, 0x00580941 },
|
||||
{ 0x00011008, 0x00000001 },
|
||||
{ 0x0000393C, 0x000000C0, 6000},
|
||||
{ 0x0000393C, 0x00000000 },
|
||||
{ 0x00007414, 0x00C82222 },
|
||||
{ 0x0000742C, 0x00000000 },
|
||||
{ 0x00000040, 0x000000CC },
|
||||
{ 0x00000040, 0x00000033 },
|
||||
};
|
||||
|
||||
static const struct reg_sequence cs35l41_safe_to_active[] = {
|
||||
{ 0x00000040, 0x00000055 },
|
||||
{ 0x00000040, 0x000000AA },
|
||||
{ 0x0000742C, 0x0000000F },
|
||||
{ 0x0000742C, 0x00000079 },
|
||||
{ 0x00007438, 0x00585941 },
|
||||
{ CS35L41_PWR_CTRL1, 0x00000001, 2000 }, // GLOBAL_EN = 1
|
||||
{ 0x0000742C, 0x000000F9 },
|
||||
{ 0x00007438, 0x00580941 },
|
||||
{ 0x00000040, 0x000000CC },
|
||||
{ 0x00000040, 0x00000033 },
|
||||
};
|
||||
|
||||
static const struct reg_sequence cs35l41_active_to_safe[] = {
|
||||
{ 0x00000040, 0x00000055 },
|
||||
{ 0x00000040, 0x000000AA },
|
||||
{ 0x00007438, 0x00585941 },
|
||||
static const struct reg_sequence cs35l41_hda_mute[] = {
|
||||
{ CS35L41_AMP_GAIN_CTRL, 0x00000000 }, // AMP_GAIN_PCM 0.5 dB
|
||||
{ CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute
|
||||
{ CS35L41_PWR_CTRL2, 0x00000000 }, // AMP_EN = 0
|
||||
{ CS35L41_PWR_CTRL1, 0x00000000 },
|
||||
{ 0x0000742C, 0x00000009, 2000 },
|
||||
{ 0x00007438, 0x00580941 },
|
||||
{ 0x00000040, 0x000000CC },
|
||||
{ 0x00000040, 0x00000033 },
|
||||
};
|
||||
|
||||
static const struct reg_sequence cs35l41_reset_to_safe[] = {
|
||||
{ 0x00000040, 0x00000055 },
|
||||
{ 0x00000040, 0x000000AA },
|
||||
{ 0x00007438, 0x00585941 },
|
||||
{ 0x00007414, 0x08C82222 },
|
||||
{ 0x0000742C, 0x00000009 },
|
||||
{ 0x00000040, 0x000000CC },
|
||||
{ 0x00000040, 0x00000033 },
|
||||
};
|
||||
/* Protection release cycle to get the speaker out of Safe-Mode */
|
||||
static void cs35l41_error_release(struct device *dev, struct regmap *regmap, unsigned int mask)
|
||||
{
|
||||
regmap_write(regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
|
||||
regmap_set_bits(regmap, CS35L41_PROTECT_REL_ERR_IGN, mask);
|
||||
regmap_clear_bits(regmap, CS35L41_PROTECT_REL_ERR_IGN, mask);
|
||||
}
|
||||
|
||||
static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = {
|
||||
.probe = cs35l41_reset_to_safe,
|
||||
.num_probe = ARRAY_SIZE(cs35l41_reset_to_safe),
|
||||
.open = cs35l41_hda_config,
|
||||
.num_open = ARRAY_SIZE(cs35l41_hda_config),
|
||||
.prepare = cs35l41_safe_to_active,
|
||||
.num_prepare = ARRAY_SIZE(cs35l41_safe_to_active),
|
||||
.cleanup = cs35l41_active_to_safe,
|
||||
.num_cleanup = ARRAY_SIZE(cs35l41_active_to_safe),
|
||||
};
|
||||
|
||||
static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = {
|
||||
.open = cs35l41_hda_config,
|
||||
.num_open = ARRAY_SIZE(cs35l41_hda_config),
|
||||
.prepare = cs35l41_start_ext_vspk,
|
||||
.num_prepare = ARRAY_SIZE(cs35l41_start_ext_vspk),
|
||||
.cleanup = cs35l41_stop_ext_vspk,
|
||||
.num_cleanup = ARRAY_SIZE(cs35l41_stop_ext_vspk),
|
||||
};
|
||||
|
||||
static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_int_bst = {
|
||||
.open = cs35l41_hda_config,
|
||||
.num_open = ARRAY_SIZE(cs35l41_hda_config),
|
||||
.prepare = cs35l41_hda_start_bst,
|
||||
.num_prepare = ARRAY_SIZE(cs35l41_hda_start_bst),
|
||||
.cleanup = cs35l41_hda_stop_bst,
|
||||
.num_cleanup = ARRAY_SIZE(cs35l41_hda_stop_bst),
|
||||
};
|
||||
/* Clear all errors to release safe mode. Global Enable must be cleared first. */
|
||||
static void cs35l41_irq_release(struct cs35l41_hda *cs35l41)
|
||||
{
|
||||
cs35l41_error_release(cs35l41->dev, cs35l41->regmap, cs35l41->irq_errors);
|
||||
cs35l41->irq_errors = 0;
|
||||
}
|
||||
|
||||
static void cs35l41_hda_playback_hook(struct device *dev, int action)
|
||||
{
|
||||
struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
|
||||
const struct cs35l41_hda_reg_sequence *reg_seq = cs35l41->reg_seq;
|
||||
struct regmap *reg = cs35l41->regmap;
|
||||
int ret = 0;
|
||||
|
||||
switch (action) {
|
||||
case HDA_GEN_PCM_ACT_OPEN:
|
||||
if (reg_seq->open)
|
||||
ret = regmap_multi_reg_write(reg, reg_seq->open, reg_seq->num_open);
|
||||
regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config));
|
||||
ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2,
|
||||
CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT);
|
||||
if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
|
||||
regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001);
|
||||
break;
|
||||
case HDA_GEN_PCM_ACT_PREPARE:
|
||||
if (reg_seq->prepare)
|
||||
ret = regmap_multi_reg_write(reg, reg_seq->prepare, reg_seq->num_prepare);
|
||||
ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1);
|
||||
break;
|
||||
case HDA_GEN_PCM_ACT_CLEANUP:
|
||||
if (reg_seq->cleanup)
|
||||
ret = regmap_multi_reg_write(reg, reg_seq->cleanup, reg_seq->num_cleanup);
|
||||
regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));
|
||||
ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0);
|
||||
break;
|
||||
case HDA_GEN_PCM_ACT_CLOSE:
|
||||
if (reg_seq->close)
|
||||
ret = regmap_multi_reg_write(reg, reg_seq->close, reg_seq->num_close);
|
||||
ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2,
|
||||
CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
|
||||
if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
|
||||
regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001);
|
||||
cs35l41_irq_release(cs35l41);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_warn(cs35l41->dev, "Failed to apply multi reg write: %d\n", ret);
|
||||
dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret);
|
||||
}
|
||||
|
||||
static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot,
|
||||
unsigned int rx_num, unsigned int *rx_slot)
|
||||
{
|
||||
struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
|
||||
static const char * const channel_name[] = { "L", "R" };
|
||||
|
||||
if (!cs35l41->amp_name) {
|
||||
if (*rx_slot >= ARRAY_SIZE(channel_name))
|
||||
return -EINVAL;
|
||||
|
||||
cs35l41->amp_name = devm_kasprintf(cs35l41->dev, GFP_KERNEL, "%s%d",
|
||||
channel_name[*rx_slot], cs35l41->channel_index);
|
||||
if (!cs35l41->amp_name)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_num, tx_slot, rx_num,
|
||||
rx_slot);
|
||||
@ -194,7 +119,6 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas
|
||||
comps->dev = dev;
|
||||
strscpy(comps->name, dev_name(dev), sizeof(comps->name));
|
||||
comps->playback_hook = cs35l41_hda_playback_hook;
|
||||
comps->set_channel_map = cs35l41_hda_channel_map;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -213,67 +137,169 @@ static const struct component_ops cs35l41_hda_comp_ops = {
|
||||
.unbind = cs35l41_hda_unbind,
|
||||
};
|
||||
|
||||
static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
|
||||
const struct cs35l41_hda_hw_config *hw_cfg)
|
||||
static irqreturn_t cs35l41_bst_short_err(int irq, void *data)
|
||||
{
|
||||
bool internal_boost = false;
|
||||
int ret;
|
||||
struct cs35l41_hda *cs35l41 = data;
|
||||
|
||||
if (!hw_cfg) {
|
||||
cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst;
|
||||
return 0;
|
||||
}
|
||||
dev_crit_ratelimited(cs35l41->dev, "LBST Error\n");
|
||||
set_bit(CS35L41_BST_SHORT_ERR_RLS_SHIFT, &cs35l41->irq_errors);
|
||||
|
||||
if (hw_cfg->bst_ind || hw_cfg->bst_cap || hw_cfg->bst_ipk)
|
||||
internal_boost = true;
|
||||
|
||||
switch (hw_cfg->gpio1_func) {
|
||||
case CS35L41_NOT_USED:
|
||||
break;
|
||||
case CS35l41_VSPK_SWITCH:
|
||||
regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
|
||||
CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT);
|
||||
break;
|
||||
case CS35l41_SYNC:
|
||||
regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
|
||||
CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT);
|
||||
break;
|
||||
default:
|
||||
dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", hw_cfg->gpio1_func);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (hw_cfg->gpio2_func) {
|
||||
case CS35L41_NOT_USED:
|
||||
break;
|
||||
case CS35L41_INTERRUPT:
|
||||
regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
|
||||
CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT);
|
||||
break;
|
||||
default:
|
||||
dev_err(cs35l41->dev, "Invalid function %d for GPIO2\n", hw_cfg->gpio2_func);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (internal_boost) {
|
||||
cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst;
|
||||
if (!(hw_cfg->bst_ind && hw_cfg->bst_cap && hw_cfg->bst_ipk))
|
||||
return -EINVAL;
|
||||
ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap,
|
||||
hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst;
|
||||
}
|
||||
|
||||
return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, (unsigned int *)&hw_cfg->spk_pos);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41,
|
||||
const char *hid, int id)
|
||||
static irqreturn_t cs35l41_bst_dcm_uvp_err(int irq, void *data)
|
||||
{
|
||||
struct cs35l41_hda_hw_config *hw_cfg;
|
||||
struct cs35l41_hda *cs35l41 = data;
|
||||
|
||||
dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
|
||||
set_bit(CS35L41_BST_UVP_ERR_RLS_SHIFT, &cs35l41->irq_errors);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t cs35l41_bst_ovp_err(int irq, void *data)
|
||||
{
|
||||
struct cs35l41_hda *cs35l41 = data;
|
||||
|
||||
dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
|
||||
set_bit(CS35L41_BST_OVP_ERR_RLS_SHIFT, &cs35l41->irq_errors);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t cs35l41_temp_err(int irq, void *data)
|
||||
{
|
||||
struct cs35l41_hda *cs35l41 = data;
|
||||
|
||||
dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
|
||||
set_bit(CS35L41_TEMP_ERR_RLS_SHIFT, &cs35l41->irq_errors);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t cs35l41_temp_warn(int irq, void *data)
|
||||
{
|
||||
struct cs35l41_hda *cs35l41 = data;
|
||||
|
||||
dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
|
||||
set_bit(CS35L41_TEMP_WARN_ERR_RLS_SHIFT, &cs35l41->irq_errors);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t cs35l41_amp_short(int irq, void *data)
|
||||
{
|
||||
struct cs35l41_hda *cs35l41 = data;
|
||||
|
||||
dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
|
||||
set_bit(CS35L41_AMP_SHORT_ERR_RLS_SHIFT, &cs35l41->irq_errors);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static const struct cs35l41_irq cs35l41_irqs[] = {
|
||||
CS35L41_IRQ(BST_OVP_ERR, "Boost Overvoltage Error", cs35l41_bst_ovp_err),
|
||||
CS35L41_IRQ(BST_DCM_UVP_ERR, "Boost Undervoltage Error", cs35l41_bst_dcm_uvp_err),
|
||||
CS35L41_IRQ(BST_SHORT_ERR, "Boost Inductor Short Error", cs35l41_bst_short_err),
|
||||
CS35L41_IRQ(TEMP_WARN, "Temperature Warning", cs35l41_temp_warn),
|
||||
CS35L41_IRQ(TEMP_ERR, "Temperature Error", cs35l41_temp_err),
|
||||
CS35L41_IRQ(AMP_SHORT_ERR, "Amp Short", cs35l41_amp_short),
|
||||
};
|
||||
|
||||
static const struct regmap_irq cs35l41_reg_irqs[] = {
|
||||
CS35L41_REG_IRQ(IRQ1_STATUS1, BST_OVP_ERR),
|
||||
CS35L41_REG_IRQ(IRQ1_STATUS1, BST_DCM_UVP_ERR),
|
||||
CS35L41_REG_IRQ(IRQ1_STATUS1, BST_SHORT_ERR),
|
||||
CS35L41_REG_IRQ(IRQ1_STATUS1, TEMP_WARN),
|
||||
CS35L41_REG_IRQ(IRQ1_STATUS1, TEMP_ERR),
|
||||
CS35L41_REG_IRQ(IRQ1_STATUS1, AMP_SHORT_ERR),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip cs35l41_regmap_irq_chip = {
|
||||
.name = "cs35l41 IRQ1 Controller",
|
||||
.status_base = CS35L41_IRQ1_STATUS1,
|
||||
.mask_base = CS35L41_IRQ1_MASK1,
|
||||
.ack_base = CS35L41_IRQ1_STATUS1,
|
||||
.num_regs = 4,
|
||||
.irqs = cs35l41_reg_irqs,
|
||||
.num_irqs = ARRAY_SIZE(cs35l41_reg_irqs),
|
||||
};
|
||||
|
||||
static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
|
||||
{
|
||||
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
|
||||
bool using_irq = false;
|
||||
int irq, irq_pol;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (!cs35l41->hw_cfg.valid)
|
||||
return -EINVAL;
|
||||
|
||||
ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (hw_cfg->gpio1.valid) {
|
||||
switch (hw_cfg->gpio1.func) {
|
||||
case CS35L41_NOT_USED:
|
||||
break;
|
||||
case CS35l41_VSPK_SWITCH:
|
||||
hw_cfg->gpio1.func = CS35L41_GPIO1_GPIO;
|
||||
hw_cfg->gpio1.out_en = true;
|
||||
break;
|
||||
case CS35l41_SYNC:
|
||||
hw_cfg->gpio1.func = CS35L41_GPIO1_MDSYNC;
|
||||
break;
|
||||
default:
|
||||
dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n",
|
||||
hw_cfg->gpio1.func);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (hw_cfg->gpio2.valid) {
|
||||
switch (hw_cfg->gpio2.func) {
|
||||
case CS35L41_NOT_USED:
|
||||
break;
|
||||
case CS35L41_INTERRUPT:
|
||||
using_irq = true;
|
||||
break;
|
||||
default:
|
||||
dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg);
|
||||
|
||||
if (cs35l41->irq && using_irq) {
|
||||
ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED | irq_pol,
|
||||
0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs35l41_irqs); i++) {
|
||||
irq = regmap_irq_get_virq(cs35l41->irq_data, cs35l41_irqs[i].irq);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = devm_request_threaded_irq(cs35l41->dev, irq, NULL,
|
||||
cs35l41_irqs[i].handler,
|
||||
IRQF_ONESHOT | IRQF_SHARED | irq_pol,
|
||||
cs35l41_irqs[i].name, cs35l41);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);
|
||||
}
|
||||
|
||||
static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
|
||||
{
|
||||
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
|
||||
u32 values[HDA_MAX_COMPONENTS];
|
||||
struct acpi_device *adev;
|
||||
struct device *physdev;
|
||||
@ -284,7 +310,7 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
|
||||
adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
|
||||
if (!adev) {
|
||||
dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid);
|
||||
return ERR_PTR(-ENODEV);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
physdev = get_device(acpi_get_first_physical_node(adev));
|
||||
@ -324,56 +350,67 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
|
||||
cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index,
|
||||
GPIOD_OUT_LOW, "cs35l41-reset");
|
||||
|
||||
hw_cfg = kzalloc(sizeof(*hw_cfg), GFP_KERNEL);
|
||||
if (!hw_cfg) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
property = "cirrus,speaker-position";
|
||||
ret = device_property_read_u32_array(physdev, property, values, nval);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
goto err;
|
||||
hw_cfg->spk_pos = values[cs35l41->index];
|
||||
|
||||
cs35l41->channel_index = 0;
|
||||
for (i = 0; i < cs35l41->index; i++)
|
||||
if (values[i] == hw_cfg->spk_pos)
|
||||
cs35l41->channel_index++;
|
||||
|
||||
property = "cirrus,gpio1-func";
|
||||
ret = device_property_read_u32_array(physdev, property, values, nval);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
hw_cfg->gpio1_func = values[cs35l41->index];
|
||||
goto err;
|
||||
hw_cfg->gpio1.func = values[cs35l41->index];
|
||||
hw_cfg->gpio1.valid = true;
|
||||
|
||||
property = "cirrus,gpio2-func";
|
||||
ret = device_property_read_u32_array(physdev, property, values, nval);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
hw_cfg->gpio2_func = values[cs35l41->index];
|
||||
goto err;
|
||||
hw_cfg->gpio2.func = values[cs35l41->index];
|
||||
hw_cfg->gpio2.valid = true;
|
||||
|
||||
property = "cirrus,boost-peak-milliamp";
|
||||
ret = device_property_read_u32_array(physdev, property, values, nval);
|
||||
if (ret == 0)
|
||||
hw_cfg->bst_ipk = values[cs35l41->index];
|
||||
else
|
||||
hw_cfg->bst_ipk = -1;
|
||||
|
||||
property = "cirrus,boost-ind-nanohenry";
|
||||
ret = device_property_read_u32_array(physdev, property, values, nval);
|
||||
if (ret == 0)
|
||||
hw_cfg->bst_ind = values[cs35l41->index];
|
||||
else
|
||||
hw_cfg->bst_ind = -1;
|
||||
|
||||
property = "cirrus,boost-cap-microfarad";
|
||||
ret = device_property_read_u32_array(physdev, property, values, nval);
|
||||
if (ret == 0)
|
||||
hw_cfg->bst_cap = values[cs35l41->index];
|
||||
else
|
||||
hw_cfg->bst_cap = -1;
|
||||
|
||||
if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0)
|
||||
hw_cfg->bst_type = CS35L41_INT_BOOST;
|
||||
else
|
||||
hw_cfg->bst_type = CS35L41_EXT_BOOST;
|
||||
|
||||
hw_cfg->valid = true;
|
||||
put_device(physdev);
|
||||
|
||||
return hw_cfg;
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
kfree(hw_cfg);
|
||||
err:
|
||||
put_device(physdev);
|
||||
dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);
|
||||
|
||||
return ERR_PTR(ret);
|
||||
return ret;
|
||||
|
||||
no_acpi_dsd:
|
||||
/*
|
||||
@ -384,25 +421,32 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
|
||||
* fwnode.
|
||||
*/
|
||||
if (strncmp(hid, "CLSA0100", 8) != 0)
|
||||
return ERR_PTR(-EINVAL);
|
||||
return -EINVAL;
|
||||
|
||||
/* check I2C address to assign the index */
|
||||
cs35l41->index = id == 0x40 ? 0 : 1;
|
||||
cs35l41->hw_cfg.spk_pos = cs35l41->index;
|
||||
cs35l41->channel_index = 0;
|
||||
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
|
||||
cs35l41->vspk_always_on = true;
|
||||
cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
|
||||
hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN;
|
||||
hw_cfg->gpio2.valid = true;
|
||||
cs35l41->hw_cfg.valid = true;
|
||||
put_device(physdev);
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
|
||||
struct regmap *regmap)
|
||||
{
|
||||
unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status;
|
||||
struct cs35l41_hda_hw_config *acpi_hw_cfg;
|
||||
struct cs35l41_hda *cs35l41;
|
||||
int ret;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(cs35l41_irqs) != ARRAY_SIZE(cs35l41_reg_irqs));
|
||||
BUILD_BUG_ON(ARRAY_SIZE(cs35l41_irqs) != CS35L41_NUM_IRQ);
|
||||
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
@ -415,9 +459,11 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
|
||||
cs35l41->regmap = regmap;
|
||||
dev_set_drvdata(dev, cs35l41);
|
||||
|
||||
acpi_hw_cfg = cs35l41_hda_read_acpi(cs35l41, device_name, id);
|
||||
if (IS_ERR(acpi_hw_cfg))
|
||||
return PTR_ERR(acpi_hw_cfg);
|
||||
ret = cs35l41_hda_read_acpi(cs35l41, device_name, id);
|
||||
if (ret) {
|
||||
dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (IS_ERR(cs35l41->reset_gpio)) {
|
||||
ret = PTR_ERR(cs35l41->reset_gpio);
|
||||
@ -490,20 +536,9 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = cs35l41_hda_apply_properties(cs35l41, acpi_hw_cfg);
|
||||
ret = cs35l41_hda_apply_properties(cs35l41);
|
||||
if (ret)
|
||||
goto err;
|
||||
kfree(acpi_hw_cfg);
|
||||
acpi_hw_cfg = NULL;
|
||||
|
||||
if (cs35l41->reg_seq->probe) {
|
||||
ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41->reg_seq->probe,
|
||||
cs35l41->reg_seq->num_probe);
|
||||
if (ret) {
|
||||
dev_err(cs35l41->dev, "Fail to apply probe reg patch: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops);
|
||||
if (ret) {
|
||||
@ -516,8 +551,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
|
||||
return 0;
|
||||
|
||||
err:
|
||||
kfree(acpi_hw_cfg);
|
||||
if (!cs35l41->vspk_always_on)
|
||||
if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type))
|
||||
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
|
||||
gpiod_put(cs35l41->reset_gpio);
|
||||
|
||||
@ -531,7 +565,7 @@ void cs35l41_hda_remove(struct device *dev)
|
||||
|
||||
component_del(cs35l41->dev, &cs35l41_hda_comp_ops);
|
||||
|
||||
if (!cs35l41->vspk_always_on)
|
||||
if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type))
|
||||
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
|
||||
gpiod_put(cs35l41->reset_gpio);
|
||||
}
|
||||
|
@ -27,39 +27,18 @@ enum cs35l41_hda_gpio_function {
|
||||
CS35l41_SYNC,
|
||||
};
|
||||
|
||||
struct cs35l41_hda_reg_sequence {
|
||||
const struct reg_sequence *probe;
|
||||
unsigned int num_probe;
|
||||
const struct reg_sequence *open;
|
||||
unsigned int num_open;
|
||||
const struct reg_sequence *prepare;
|
||||
unsigned int num_prepare;
|
||||
const struct reg_sequence *cleanup;
|
||||
unsigned int num_cleanup;
|
||||
const struct reg_sequence *close;
|
||||
unsigned int num_close;
|
||||
};
|
||||
|
||||
struct cs35l41_hda_hw_config {
|
||||
unsigned int spk_pos;
|
||||
unsigned int gpio1_func;
|
||||
unsigned int gpio2_func;
|
||||
int bst_ind;
|
||||
int bst_ipk;
|
||||
int bst_cap;
|
||||
};
|
||||
|
||||
struct cs35l41_hda {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct gpio_desc *reset_gpio;
|
||||
const struct cs35l41_hda_reg_sequence *reg_seq;
|
||||
struct cs35l41_hw_cfg hw_cfg;
|
||||
|
||||
int irq;
|
||||
int index;
|
||||
|
||||
/* Don't put the AMP in reset of VSPK can not be turned off */
|
||||
bool vspk_always_on;
|
||||
int channel_index;
|
||||
unsigned volatile long irq_errors;
|
||||
const char *amp_name;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
};
|
||||
|
||||
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
|
||||
|
@ -48,7 +48,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match);
|
||||
|
||||
static struct spi_driver cs35l41_spi_driver = {
|
||||
.driver = {
|
||||
.name = "cs35l41_hda",
|
||||
.name = "cs35l41-hda",
|
||||
.acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match),
|
||||
},
|
||||
.id_table = cs35l41_hda_spi_id,
|
||||
|
@ -2935,7 +2935,9 @@ static int hda_codec_runtime_suspend(struct device *dev)
|
||||
if (!codec->card)
|
||||
return 0;
|
||||
|
||||
cancel_delayed_work_sync(&codec->jackpoll_work);
|
||||
if (!codec->bus->jackpoll_in_suspend)
|
||||
cancel_delayed_work_sync(&codec->jackpoll_work);
|
||||
|
||||
state = hda_call_codec_suspend(codec);
|
||||
if (codec->link_down_at_suspend ||
|
||||
(codec_has_clkstop(codec) && codec_has_epss(codec) &&
|
||||
@ -2984,6 +2986,9 @@ static void hda_codec_pm_complete(struct device *dev)
|
||||
|
||||
static int hda_codec_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct hda_codec *codec = dev_to_hda_codec(dev);
|
||||
|
||||
cancel_delayed_work_sync(&codec->jackpoll_work);
|
||||
dev->power.power_state = PMSG_SUSPEND;
|
||||
return pm_runtime_force_suspend(dev);
|
||||
}
|
||||
@ -2996,6 +3001,9 @@ static int hda_codec_pm_resume(struct device *dev)
|
||||
|
||||
static int hda_codec_pm_freeze(struct device *dev)
|
||||
{
|
||||
struct hda_codec *codec = dev_to_hda_codec(dev);
|
||||
|
||||
cancel_delayed_work_sync(&codec->jackpoll_work);
|
||||
dev->power.power_state = PMSG_FREEZE;
|
||||
return pm_runtime_force_suspend(dev);
|
||||
}
|
||||
@ -3038,6 +3046,7 @@ void snd_hda_codec_shutdown(struct hda_codec *codec)
|
||||
if (!codec->registered)
|
||||
return;
|
||||
|
||||
cancel_delayed_work_sync(&codec->jackpoll_work);
|
||||
list_for_each_entry(cpcm, &codec->pcm_list_head, list)
|
||||
snd_pcm_suspend_all(cpcm->pcm);
|
||||
|
||||
|
@ -15,6 +15,4 @@ struct hda_component {
|
||||
struct device *dev;
|
||||
char name[HDA_MAX_NAME_SIZE];
|
||||
void (*playback_hook)(struct device *dev, int action);
|
||||
int (*set_channel_map)(struct device *dev, unsigned int rx_num, unsigned int *rx_slot,
|
||||
unsigned int tx_num, unsigned int *tx_slot);
|
||||
};
|
||||
|
@ -420,6 +420,7 @@ static int hda_tegra_create(struct snd_card *card,
|
||||
chip->driver_caps = driver_caps;
|
||||
chip->driver_type = driver_caps & 0xff;
|
||||
chip->dev_index = 0;
|
||||
chip->jackpoll_interval = msecs_to_jiffies(5000);
|
||||
INIT_LIST_HEAD(&chip->pcm_list);
|
||||
|
||||
chip->codec_probe_mask = -1;
|
||||
@ -436,6 +437,7 @@ static int hda_tegra_create(struct snd_card *card,
|
||||
chip->bus.core.sync_write = 0;
|
||||
chip->bus.core.needs_damn_long_delay = 1;
|
||||
chip->bus.core.aligned_mmio = 1;
|
||||
chip->bus.jackpoll_in_suspend = 1;
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
||||
if (err < 0) {
|
||||
|
@ -1105,6 +1105,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
||||
|
||||
static const struct hda_device_id snd_hda_id_conexant[] = {
|
||||
HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f11f87, "SN6140", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
|
||||
|
@ -76,67 +76,74 @@ const struct hda_pintbl cs8409_cs42l42_pincfgs[] = {
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
const struct hda_pintbl cs8409_cs42l42_pincfgs_no_dmic[] = {
|
||||
{ CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */
|
||||
{ CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */
|
||||
{ CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
/* Vendor specific HW configuration for CS42L42 */
|
||||
static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = {
|
||||
{ 0x1010, 0xB0 },
|
||||
{ 0x1D01, 0x00 },
|
||||
{ CS42L42_I2C_TIMEOUT, 0xB0 },
|
||||
{ CS42L42_ADC_CTL, 0x00 },
|
||||
{ 0x1D02, 0x06 },
|
||||
{ 0x1D03, 0x9F },
|
||||
{ 0x1107, 0x01 },
|
||||
{ 0x1009, 0x02 },
|
||||
{ 0x1007, 0x03 },
|
||||
{ 0x1201, 0x00 },
|
||||
{ 0x1208, 0x13 },
|
||||
{ 0x1205, 0xFF },
|
||||
{ 0x1206, 0x00 },
|
||||
{ 0x1207, 0x20 },
|
||||
{ 0x1202, 0x0D },
|
||||
{ 0x2A02, 0x02 },
|
||||
{ 0x2A03, 0x00 },
|
||||
{ 0x2A04, 0x00 },
|
||||
{ 0x2A05, 0x02 },
|
||||
{ 0x2A06, 0x00 },
|
||||
{ 0x2A07, 0x20 },
|
||||
{ 0x2A08, 0x02 },
|
||||
{ 0x2A09, 0x00 },
|
||||
{ 0x2A0A, 0x80 },
|
||||
{ 0x2A0B, 0x02 },
|
||||
{ 0x2A0C, 0x00 },
|
||||
{ 0x2A0D, 0xA0 },
|
||||
{ 0x2A01, 0x0C },
|
||||
{ 0x2902, 0x01 },
|
||||
{ 0x2903, 0x02 },
|
||||
{ 0x2904, 0x00 },
|
||||
{ 0x2905, 0x00 },
|
||||
{ 0x2901, 0x01 },
|
||||
{ 0x1101, 0x0A },
|
||||
{ 0x1102, 0x84 },
|
||||
{ 0x2301, 0x3F },
|
||||
{ 0x2303, 0x3F },
|
||||
{ 0x2302, 0x3f },
|
||||
{ 0x2001, 0x03 },
|
||||
{ 0x1B75, 0xB6 },
|
||||
{ 0x1B73, 0xC2 },
|
||||
{ 0x1129, 0x01 },
|
||||
{ 0x1121, 0xF3 },
|
||||
{ 0x1103, 0x20 },
|
||||
{ 0x1105, 0x00 },
|
||||
{ 0x1112, 0x00 },
|
||||
{ 0x1113, 0x80 },
|
||||
{ 0x1C03, 0xC0 },
|
||||
{ 0x1101, 0x02 },
|
||||
{ 0x1316, 0xff },
|
||||
{ 0x1317, 0xff },
|
||||
{ 0x1318, 0xff },
|
||||
{ 0x1319, 0xff },
|
||||
{ 0x131a, 0xff },
|
||||
{ 0x131b, 0xff },
|
||||
{ 0x131c, 0xff },
|
||||
{ 0x131e, 0xff },
|
||||
{ 0x131f, 0xff },
|
||||
{ 0x1320, 0xff },
|
||||
{ 0x1b79, 0xff },
|
||||
{ 0x1b7a, 0xff },
|
||||
{ CS42L42_ADC_VOLUME, 0x9F },
|
||||
{ CS42L42_OSC_SWITCH, 0x01 },
|
||||
{ CS42L42_MCLK_CTL, 0x02 },
|
||||
{ CS42L42_SRC_CTL, 0x03 },
|
||||
{ CS42L42_MCLK_SRC_SEL, 0x00 },
|
||||
{ CS42L42_ASP_FRM_CFG, 0x13 },
|
||||
{ CS42L42_FSYNC_P_LOWER, 0xFF },
|
||||
{ CS42L42_FSYNC_P_UPPER, 0x00 },
|
||||
{ CS42L42_ASP_CLK_CFG, 0x20 },
|
||||
{ CS42L42_SPDIF_CLK_CFG, 0x0D },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0x20 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH3_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH3_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH3_BIT_LSB, 0x80 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH4_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH4_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH4_BIT_LSB, 0xA0 },
|
||||
{ CS42L42_ASP_RX_DAI0_EN, 0x0C },
|
||||
{ CS42L42_ASP_TX_CH_EN, 0x01 },
|
||||
{ CS42L42_ASP_TX_CH_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 },
|
||||
{ CS42L42_ASP_TX_SZ_EN, 0x01 },
|
||||
{ CS42L42_PWR_CTL1, 0x0A },
|
||||
{ CS42L42_PWR_CTL2, 0x84 },
|
||||
{ CS42L42_MIXER_CHA_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_CHB_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_ADC_VOL, 0x3f },
|
||||
{ CS42L42_HP_CTL, 0x03 },
|
||||
{ CS42L42_MIC_DET_CTL1, 0xB6 },
|
||||
{ CS42L42_TIPSENSE_CTL, 0xC2 },
|
||||
{ CS42L42_HS_CLAMP_DISABLE, 0x01 },
|
||||
{ CS42L42_HS_SWITCH_CTL, 0xF3 },
|
||||
{ CS42L42_PWR_CTL3, 0x20 },
|
||||
{ CS42L42_RSENSE_CTL2, 0x00 },
|
||||
{ CS42L42_RSENSE_CTL3, 0x00 },
|
||||
{ CS42L42_TSENSE_CTL, 0x80 },
|
||||
{ CS42L42_HS_BIAS_CTL, 0xC0 },
|
||||
{ CS42L42_PWR_CTL1, 0x02 },
|
||||
{ CS42L42_ADC_OVFL_INT_MASK, 0xff },
|
||||
{ CS42L42_MIXER_INT_MASK, 0xff },
|
||||
{ CS42L42_SRC_INT_MASK, 0xff },
|
||||
{ CS42L42_ASP_RX_INT_MASK, 0xff },
|
||||
{ CS42L42_ASP_TX_INT_MASK, 0xff },
|
||||
{ CS42L42_CODEC_INT_MASK, 0xff },
|
||||
{ CS42L42_SRCPL_INT_MASK, 0xff },
|
||||
{ CS42L42_VPMON_INT_MASK, 0xff },
|
||||
{ CS42L42_PLL_LOCK_INT_MASK, 0xff },
|
||||
{ CS42L42_TSRS_PLUG_INT_MASK, 0xff },
|
||||
{ CS42L42_DET_INT1_MASK, 0xff },
|
||||
{ CS42L42_DET_INT2_MASK, 0xff },
|
||||
};
|
||||
|
||||
/* Vendor specific hw configuration for CS8409 */
|
||||
@ -252,7 +259,6 @@ struct sub_codec cs8409_cs42l42_codec = {
|
||||
.init_seq_num = ARRAY_SIZE(cs42l42_init_reg_seq),
|
||||
.hp_jack_in = 0,
|
||||
.mic_jack_in = 0,
|
||||
.force_status_change = 1,
|
||||
.paged = 1,
|
||||
.suspended = 1,
|
||||
.no_type_dect = 0,
|
||||
@ -282,115 +288,115 @@ const struct hda_pintbl dolphin_pincfgs[] = {
|
||||
|
||||
/* Vendor specific HW configuration for CS42L42 */
|
||||
static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = {
|
||||
{ 0x1010, 0xB0 },
|
||||
{ 0x1D01, 0x00 },
|
||||
{ CS42L42_I2C_TIMEOUT, 0xB0 },
|
||||
{ CS42L42_ADC_CTL, 0x00 },
|
||||
{ 0x1D02, 0x06 },
|
||||
{ 0x1D03, 0x9F },
|
||||
{ 0x1107, 0x01 },
|
||||
{ 0x1009, 0x02 },
|
||||
{ 0x1007, 0x03 },
|
||||
{ 0x1201, 0x00 },
|
||||
{ 0x1208, 0x13 },
|
||||
{ 0x1205, 0xFF },
|
||||
{ 0x1206, 0x00 },
|
||||
{ 0x1207, 0x20 },
|
||||
{ 0x1202, 0x0D },
|
||||
{ 0x2A02, 0x02 },
|
||||
{ 0x2A03, 0x00 },
|
||||
{ 0x2A04, 0x00 },
|
||||
{ 0x2A05, 0x02 },
|
||||
{ 0x2A06, 0x00 },
|
||||
{ 0x2A07, 0x20 },
|
||||
{ 0x2A01, 0x0C },
|
||||
{ 0x2902, 0x01 },
|
||||
{ 0x2903, 0x02 },
|
||||
{ 0x2904, 0x00 },
|
||||
{ 0x2905, 0x00 },
|
||||
{ 0x2901, 0x01 },
|
||||
{ 0x1101, 0x0A },
|
||||
{ 0x1102, 0x84 },
|
||||
{ 0x2001, 0x03 },
|
||||
{ 0x2301, 0x3F },
|
||||
{ 0x2303, 0x3F },
|
||||
{ 0x2302, 0x3f },
|
||||
{ 0x1B75, 0xB6 },
|
||||
{ 0x1B73, 0xC2 },
|
||||
{ 0x1129, 0x01 },
|
||||
{ 0x1121, 0xF3 },
|
||||
{ 0x1103, 0x20 },
|
||||
{ 0x1105, 0x00 },
|
||||
{ 0x1112, 0x00 },
|
||||
{ 0x1113, 0x80 },
|
||||
{ 0x1C03, 0xC0 },
|
||||
{ 0x1101, 0x02 },
|
||||
{ 0x1316, 0xff },
|
||||
{ 0x1317, 0xff },
|
||||
{ 0x1318, 0xff },
|
||||
{ 0x1319, 0xff },
|
||||
{ 0x131a, 0xff },
|
||||
{ 0x131b, 0xff },
|
||||
{ 0x131c, 0xff },
|
||||
{ 0x131e, 0xff },
|
||||
{ 0x131f, 0xff },
|
||||
{ 0x1320, 0xff },
|
||||
{ 0x1b79, 0xff },
|
||||
{ 0x1b7a, 0xff }
|
||||
{ CS42L42_ADC_VOLUME, 0x9F },
|
||||
{ CS42L42_OSC_SWITCH, 0x01 },
|
||||
{ CS42L42_MCLK_CTL, 0x02 },
|
||||
{ CS42L42_SRC_CTL, 0x03 },
|
||||
{ CS42L42_MCLK_SRC_SEL, 0x00 },
|
||||
{ CS42L42_ASP_FRM_CFG, 0x13 },
|
||||
{ CS42L42_FSYNC_P_LOWER, 0xFF },
|
||||
{ CS42L42_FSYNC_P_UPPER, 0x00 },
|
||||
{ CS42L42_ASP_CLK_CFG, 0x20 },
|
||||
{ CS42L42_SPDIF_CLK_CFG, 0x0D },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0x20 },
|
||||
{ CS42L42_ASP_RX_DAI0_EN, 0x0C },
|
||||
{ CS42L42_ASP_TX_CH_EN, 0x01 },
|
||||
{ CS42L42_ASP_TX_CH_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 },
|
||||
{ CS42L42_ASP_TX_SZ_EN, 0x01 },
|
||||
{ CS42L42_PWR_CTL1, 0x0A },
|
||||
{ CS42L42_PWR_CTL2, 0x84 },
|
||||
{ CS42L42_HP_CTL, 0x03 },
|
||||
{ CS42L42_MIXER_CHA_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_CHB_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_ADC_VOL, 0x3f },
|
||||
{ CS42L42_MIC_DET_CTL1, 0xB6 },
|
||||
{ CS42L42_TIPSENSE_CTL, 0xC2 },
|
||||
{ CS42L42_HS_CLAMP_DISABLE, 0x01 },
|
||||
{ CS42L42_HS_SWITCH_CTL, 0xF3 },
|
||||
{ CS42L42_PWR_CTL3, 0x20 },
|
||||
{ CS42L42_RSENSE_CTL2, 0x00 },
|
||||
{ CS42L42_RSENSE_CTL3, 0x00 },
|
||||
{ CS42L42_TSENSE_CTL, 0x80 },
|
||||
{ CS42L42_HS_BIAS_CTL, 0xC0 },
|
||||
{ CS42L42_PWR_CTL1, 0x02 },
|
||||
{ CS42L42_ADC_OVFL_INT_MASK, 0xff },
|
||||
{ CS42L42_MIXER_INT_MASK, 0xff },
|
||||
{ CS42L42_SRC_INT_MASK, 0xff },
|
||||
{ CS42L42_ASP_RX_INT_MASK, 0xff },
|
||||
{ CS42L42_ASP_TX_INT_MASK, 0xff },
|
||||
{ CS42L42_CODEC_INT_MASK, 0xff },
|
||||
{ CS42L42_SRCPL_INT_MASK, 0xff },
|
||||
{ CS42L42_VPMON_INT_MASK, 0xff },
|
||||
{ CS42L42_PLL_LOCK_INT_MASK, 0xff },
|
||||
{ CS42L42_TSRS_PLUG_INT_MASK, 0xff },
|
||||
{ CS42L42_DET_INT1_MASK, 0xff },
|
||||
{ CS42L42_DET_INT2_MASK, 0xff }
|
||||
};
|
||||
|
||||
static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = {
|
||||
{ 0x1010, 0xB0 },
|
||||
{ 0x1D01, 0x00 },
|
||||
{ CS42L42_I2C_TIMEOUT, 0xB0 },
|
||||
{ CS42L42_ADC_CTL, 0x00 },
|
||||
{ 0x1D02, 0x06 },
|
||||
{ 0x1D03, 0x9F },
|
||||
{ 0x1107, 0x01 },
|
||||
{ 0x1009, 0x02 },
|
||||
{ 0x1007, 0x03 },
|
||||
{ 0x1201, 0x00 },
|
||||
{ 0x1208, 0x13 },
|
||||
{ 0x1205, 0xFF },
|
||||
{ 0x1206, 0x00 },
|
||||
{ 0x1207, 0x20 },
|
||||
{ 0x1202, 0x0D },
|
||||
{ 0x2A02, 0x02 },
|
||||
{ 0x2A03, 0x00 },
|
||||
{ 0x2A04, 0x80 },
|
||||
{ 0x2A05, 0x02 },
|
||||
{ 0x2A06, 0x00 },
|
||||
{ 0x2A07, 0xA0 },
|
||||
{ 0x2A01, 0x0C },
|
||||
{ 0x2902, 0x00 },
|
||||
{ 0x2903, 0x02 },
|
||||
{ 0x2904, 0x00 },
|
||||
{ 0x2905, 0x00 },
|
||||
{ 0x2901, 0x00 },
|
||||
{ 0x1101, 0x0E },
|
||||
{ 0x1102, 0x84 },
|
||||
{ 0x2001, 0x01 },
|
||||
{ 0x2301, 0x3F },
|
||||
{ 0x2303, 0x3F },
|
||||
{ 0x2302, 0x3f },
|
||||
{ 0x1B75, 0xB6 },
|
||||
{ 0x1B73, 0xC2 },
|
||||
{ 0x1129, 0x01 },
|
||||
{ 0x1121, 0xF3 },
|
||||
{ 0x1103, 0x20 },
|
||||
{ 0x1105, 0x00 },
|
||||
{ 0x1112, 0x00 },
|
||||
{ 0x1113, 0x80 },
|
||||
{ 0x1C03, 0xC0 },
|
||||
{ 0x1101, 0x06 },
|
||||
{ 0x1316, 0xff },
|
||||
{ 0x1317, 0xff },
|
||||
{ 0x1318, 0xff },
|
||||
{ 0x1319, 0xff },
|
||||
{ 0x131a, 0xff },
|
||||
{ 0x131b, 0xff },
|
||||
{ 0x131c, 0xff },
|
||||
{ 0x131e, 0xff },
|
||||
{ 0x131f, 0xff },
|
||||
{ 0x1320, 0xff },
|
||||
{ 0x1b79, 0xff },
|
||||
{ 0x1b7a, 0xff }
|
||||
{ CS42L42_ADC_VOLUME, 0x9F },
|
||||
{ CS42L42_OSC_SWITCH, 0x01 },
|
||||
{ CS42L42_MCLK_CTL, 0x02 },
|
||||
{ CS42L42_SRC_CTL, 0x03 },
|
||||
{ CS42L42_MCLK_SRC_SEL, 0x00 },
|
||||
{ CS42L42_ASP_FRM_CFG, 0x13 },
|
||||
{ CS42L42_FSYNC_P_LOWER, 0xFF },
|
||||
{ CS42L42_FSYNC_P_UPPER, 0x00 },
|
||||
{ CS42L42_ASP_CLK_CFG, 0x20 },
|
||||
{ CS42L42_SPDIF_CLK_CFG, 0x0D },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x80 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0xA0 },
|
||||
{ CS42L42_ASP_RX_DAI0_EN, 0x0C },
|
||||
{ CS42L42_ASP_TX_CH_EN, 0x00 },
|
||||
{ CS42L42_ASP_TX_CH_AP_RES, 0x02 },
|
||||
{ CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 },
|
||||
{ CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 },
|
||||
{ CS42L42_ASP_TX_SZ_EN, 0x00 },
|
||||
{ CS42L42_PWR_CTL1, 0x0E },
|
||||
{ CS42L42_PWR_CTL2, 0x84 },
|
||||
{ CS42L42_HP_CTL, 0x01 },
|
||||
{ CS42L42_MIXER_CHA_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_CHB_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_ADC_VOL, 0x3f },
|
||||
{ CS42L42_MIC_DET_CTL1, 0xB6 },
|
||||
{ CS42L42_TIPSENSE_CTL, 0xC2 },
|
||||
{ CS42L42_HS_CLAMP_DISABLE, 0x01 },
|
||||
{ CS42L42_HS_SWITCH_CTL, 0xF3 },
|
||||
{ CS42L42_PWR_CTL3, 0x20 },
|
||||
{ CS42L42_RSENSE_CTL2, 0x00 },
|
||||
{ CS42L42_RSENSE_CTL3, 0x00 },
|
||||
{ CS42L42_TSENSE_CTL, 0x80 },
|
||||
{ CS42L42_HS_BIAS_CTL, 0xC0 },
|
||||
{ CS42L42_PWR_CTL1, 0x06 },
|
||||
{ CS42L42_ADC_OVFL_INT_MASK, 0xff },
|
||||
{ CS42L42_MIXER_INT_MASK, 0xff },
|
||||
{ CS42L42_SRC_INT_MASK, 0xff },
|
||||
{ CS42L42_ASP_RX_INT_MASK, 0xff },
|
||||
{ CS42L42_ASP_TX_INT_MASK, 0xff },
|
||||
{ CS42L42_CODEC_INT_MASK, 0xff },
|
||||
{ CS42L42_SRCPL_INT_MASK, 0xff },
|
||||
{ CS42L42_VPMON_INT_MASK, 0xff },
|
||||
{ CS42L42_PLL_LOCK_INT_MASK, 0xff },
|
||||
{ CS42L42_TSRS_PLUG_INT_MASK, 0xff },
|
||||
{ CS42L42_DET_INT1_MASK, 0xff },
|
||||
{ CS42L42_DET_INT2_MASK, 0xff }
|
||||
};
|
||||
|
||||
/* Vendor specific hw configuration for CS8409 */
|
||||
@ -444,7 +450,6 @@ struct sub_codec dolphin_cs42l42_0 = {
|
||||
.init_seq_num = ARRAY_SIZE(dolphin_c0_init_reg_seq),
|
||||
.hp_jack_in = 0,
|
||||
.mic_jack_in = 0,
|
||||
.force_status_change = 1,
|
||||
.paged = 1,
|
||||
.suspended = 1,
|
||||
.no_type_dect = 0,
|
||||
@ -458,7 +463,6 @@ struct sub_codec dolphin_cs42l42_1 = {
|
||||
.init_seq_num = ARRAY_SIZE(dolphin_c1_init_reg_seq),
|
||||
.hp_jack_in = 0,
|
||||
.mic_jack_in = 0,
|
||||
.force_status_change = 1,
|
||||
.paged = 1,
|
||||
.suspended = 1,
|
||||
.no_type_dect = 1,
|
||||
@ -521,6 +525,11 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x0B95, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
||||
SND_PCI_QUIRK(0x1028, 0x0B96, "Warlock MLK", CS8409_WARLOCK_MLK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0B97, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BA5, "Odin", CS8409_ODIN),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BA6, "Odin", CS8409_ODIN),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BA8, "Odin", CS8409_ODIN),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BAA, "Odin", CS8409_ODIN),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BAE, "Odin", CS8409_ODIN),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BB2, "Warlock MLK", CS8409_WARLOCK_MLK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BB3, "Warlock MLK", CS8409_WARLOCK_MLK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0BB4, "Warlock MLK", CS8409_WARLOCK_MLK),
|
||||
@ -548,6 +557,7 @@ const struct hda_model_fixup cs8409_models[] = {
|
||||
{ .id = CS8409_WARLOCK_MLK_DUAL_MIC, .name = "warlock mlk dual mic" },
|
||||
{ .id = CS8409_CYBORG, .name = "cyborg" },
|
||||
{ .id = CS8409_DOLPHIN, .name = "dolphin" },
|
||||
{ .id = CS8409_ODIN, .name = "odin" },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -596,4 +606,10 @@ const struct hda_fixup cs8409_fixups[] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = dolphin_fixups,
|
||||
},
|
||||
[CS8409_ODIN] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = cs8409_cs42l42_pincfgs_no_dmic,
|
||||
.chained = true,
|
||||
.chain_id = CS8409_FIXUPS,
|
||||
},
|
||||
};
|
||||
|
@ -419,6 +419,39 @@ static void cs8409_fix_caps(struct hda_codec *codec, unsigned int nid)
|
||||
snd_hda_override_wcaps(codec, nid, (get_wcaps(codec, nid) | AC_WCAP_UNSOL_CAP));
|
||||
}
|
||||
|
||||
static int cs8409_spk_sw_gpio_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct cs8409_spec *spec = codec->spec;
|
||||
|
||||
ucontrol->value.integer.value[0] = !!(spec->gpio_data & spec->speaker_pdn_gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs8409_spk_sw_gpio_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct cs8409_spec *spec = codec->spec;
|
||||
unsigned int gpio_data;
|
||||
|
||||
gpio_data = (spec->gpio_data & ~spec->speaker_pdn_gpio) |
|
||||
(ucontrol->value.integer.value[0] ? spec->speaker_pdn_gpio : 0);
|
||||
if (gpio_data == spec->gpio_data)
|
||||
return 0;
|
||||
spec->gpio_data = gpio_data;
|
||||
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new cs8409_spk_sw_ctrl = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.info = snd_ctl_boolean_mono_info,
|
||||
.get = cs8409_spk_sw_gpio_get,
|
||||
.put = cs8409_spk_sw_gpio_put,
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* CS42L42 Specific Functions
|
||||
******************************************************************************/
|
||||
@ -481,26 +514,26 @@ static void cs42l42_mute(struct sub_codec *cs42l42, int vol_type,
|
||||
if (mute) {
|
||||
if (vol_type == CS42L42_VOL_DAC) {
|
||||
if (chs & BIT(0))
|
||||
cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, 0x3f);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHA_VOL, 0x3f);
|
||||
if (chs & BIT(1))
|
||||
cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, 0x3f);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHB_VOL, 0x3f);
|
||||
} else if (vol_type == CS42L42_VOL_ADC) {
|
||||
if (chs & BIT(0))
|
||||
cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, 0x9f);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_ADC_VOLUME, 0x9f);
|
||||
}
|
||||
} else {
|
||||
if (vol_type == CS42L42_VOL_DAC) {
|
||||
if (chs & BIT(0))
|
||||
cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA,
|
||||
cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHA_VOL,
|
||||
-(cs42l42->vol[CS42L42_DAC_CH0_VOL_OFFSET])
|
||||
& CS42L42_REG_HS_VOL_MASK);
|
||||
& CS42L42_MIXER_CH_VOL_MASK);
|
||||
if (chs & BIT(1))
|
||||
cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB,
|
||||
cs8409_i2c_write(cs42l42, CS42L42_MIXER_CHB_VOL,
|
||||
-(cs42l42->vol[CS42L42_DAC_CH1_VOL_OFFSET])
|
||||
& CS42L42_REG_HS_VOL_MASK);
|
||||
& CS42L42_MIXER_CH_VOL_MASK);
|
||||
} else if (vol_type == CS42L42_VOL_ADC) {
|
||||
if (chs & BIT(0))
|
||||
cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL,
|
||||
cs8409_i2c_write(cs42l42, CS42L42_ADC_VOLUME,
|
||||
cs42l42->vol[CS42L42_ADC_VOL_OFFSET]
|
||||
& CS42L42_REG_AMIC_VOL_MASK);
|
||||
}
|
||||
@ -601,76 +634,167 @@ static void cs42l42_capture_pcm_hook(struct hda_pcm_stream *hinfo,
|
||||
/* Configure CS42L42 slave codec for jack autodetect */
|
||||
static void cs42l42_enable_jack_detect(struct sub_codec *cs42l42)
|
||||
{
|
||||
cs8409_i2c_write(cs42l42, 0x1b70, cs42l42->hsbias_hiz);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSBIAS_SC_AUTOCTL, cs42l42->hsbias_hiz);
|
||||
/* Clear WAKE# */
|
||||
cs8409_i2c_write(cs42l42, 0x1b71, 0x00C1);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_WAKE_CTL, 0x00C1);
|
||||
/* Wait ~2.5ms */
|
||||
usleep_range(2500, 3000);
|
||||
/* Set mode WAKE# output follows the combination logic directly */
|
||||
cs8409_i2c_write(cs42l42, 0x1b71, 0x00C0);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_WAKE_CTL, 0x00C0);
|
||||
/* Clear interrupts status */
|
||||
cs8409_i2c_read(cs42l42, 0x130f);
|
||||
cs8409_i2c_read(cs42l42, CS42L42_TSRS_PLUG_STATUS);
|
||||
/* Enable interrupt */
|
||||
cs8409_i2c_write(cs42l42, 0x1320, 0xF3);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_TSRS_PLUG_INT_MASK, 0xF3);
|
||||
}
|
||||
|
||||
/* Enable and run CS42L42 slave codec jack auto detect */
|
||||
static void cs42l42_run_jack_detect(struct sub_codec *cs42l42)
|
||||
{
|
||||
/* Clear interrupts */
|
||||
cs8409_i2c_read(cs42l42, 0x1308);
|
||||
cs8409_i2c_read(cs42l42, 0x1b77);
|
||||
cs8409_i2c_write(cs42l42, 0x1320, 0xFF);
|
||||
cs8409_i2c_read(cs42l42, 0x130f);
|
||||
cs8409_i2c_read(cs42l42, CS42L42_CODEC_STATUS);
|
||||
cs8409_i2c_read(cs42l42, CS42L42_DET_STATUS1);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_TSRS_PLUG_INT_MASK, 0xFF);
|
||||
cs8409_i2c_read(cs42l42, CS42L42_TSRS_PLUG_STATUS);
|
||||
|
||||
cs8409_i2c_write(cs42l42, 0x1102, 0x87);
|
||||
cs8409_i2c_write(cs42l42, 0x1f06, 0x86);
|
||||
cs8409_i2c_write(cs42l42, 0x1b74, 0x07);
|
||||
cs8409_i2c_write(cs42l42, 0x131b, 0xFD);
|
||||
cs8409_i2c_write(cs42l42, 0x1120, 0x80);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_PWR_CTL2, 0x87);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_DAC_CTL2, 0x86);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_MISC_DET_CTL, 0x07);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_CODEC_INT_MASK, 0xFD);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0x80);
|
||||
/* Wait ~20ms*/
|
||||
usleep_range(20000, 25000);
|
||||
cs8409_i2c_write(cs42l42, 0x111f, 0x77);
|
||||
cs8409_i2c_write(cs42l42, 0x1120, 0xc0);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL1, 0x77);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0xc0);
|
||||
}
|
||||
|
||||
static int cs42l42_manual_hs_det(struct sub_codec *cs42l42)
|
||||
{
|
||||
unsigned int hs_det_status;
|
||||
unsigned int hs_det_comp1;
|
||||
unsigned int hs_det_comp2;
|
||||
unsigned int hs_det_sw;
|
||||
unsigned int hs_type;
|
||||
|
||||
/* Set hs detect to manual, active mode */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2,
|
||||
(1 << CS42L42_HSDET_CTRL_SHIFT) |
|
||||
(0 << CS42L42_HSDET_SET_SHIFT) |
|
||||
(0 << CS42L42_HSBIAS_REF_SHIFT) |
|
||||
(0 << CS42L42_HSDET_AUTO_TIME_SHIFT));
|
||||
|
||||
/* Configure HS DET comparator reference levels. */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL1,
|
||||
(CS42L42_HSDET_COMP1_LVL_VAL << CS42L42_HSDET_COMP1_LVL_SHIFT) |
|
||||
(CS42L42_HSDET_COMP2_LVL_VAL << CS42L42_HSDET_COMP2_LVL_SHIFT));
|
||||
|
||||
/* Open the SW_HSB_HS3 switch and close SW_HSB_HS4 for a Type 1 headset. */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP1);
|
||||
|
||||
msleep(100);
|
||||
|
||||
hs_det_status = cs8409_i2c_read(cs42l42, CS42L42_HS_DET_STATUS);
|
||||
|
||||
hs_det_comp1 = (hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >>
|
||||
CS42L42_HSDET_COMP1_OUT_SHIFT;
|
||||
hs_det_comp2 = (hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >>
|
||||
CS42L42_HSDET_COMP2_OUT_SHIFT;
|
||||
|
||||
/* Close the SW_HSB_HS3 switch for a Type 2 headset. */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP2);
|
||||
|
||||
msleep(100);
|
||||
|
||||
hs_det_status = cs8409_i2c_read(cs42l42, CS42L42_HS_DET_STATUS);
|
||||
|
||||
hs_det_comp1 |= ((hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >>
|
||||
CS42L42_HSDET_COMP1_OUT_SHIFT) << 1;
|
||||
hs_det_comp2 |= ((hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >>
|
||||
CS42L42_HSDET_COMP2_OUT_SHIFT) << 1;
|
||||
|
||||
/* Use Comparator 1 with 1.25V Threshold. */
|
||||
switch (hs_det_comp1) {
|
||||
case CS42L42_HSDET_COMP_TYPE1:
|
||||
hs_type = CS42L42_PLUG_CTIA;
|
||||
hs_det_sw = CS42L42_HSDET_SW_TYPE1;
|
||||
break;
|
||||
case CS42L42_HSDET_COMP_TYPE2:
|
||||
hs_type = CS42L42_PLUG_OMTP;
|
||||
hs_det_sw = CS42L42_HSDET_SW_TYPE2;
|
||||
break;
|
||||
default:
|
||||
/* Fallback to Comparator 2 with 1.75V Threshold. */
|
||||
switch (hs_det_comp2) {
|
||||
case CS42L42_HSDET_COMP_TYPE1:
|
||||
hs_type = CS42L42_PLUG_CTIA;
|
||||
hs_det_sw = CS42L42_HSDET_SW_TYPE1;
|
||||
break;
|
||||
case CS42L42_HSDET_COMP_TYPE2:
|
||||
hs_type = CS42L42_PLUG_OMTP;
|
||||
hs_det_sw = CS42L42_HSDET_SW_TYPE2;
|
||||
break;
|
||||
case CS42L42_HSDET_COMP_TYPE3:
|
||||
hs_type = CS42L42_PLUG_HEADPHONE;
|
||||
hs_det_sw = CS42L42_HSDET_SW_TYPE3;
|
||||
break;
|
||||
default:
|
||||
hs_type = CS42L42_PLUG_INVALID;
|
||||
hs_det_sw = CS42L42_HSDET_SW_TYPE4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set Switches */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HS_SWITCH_CTL, hs_det_sw);
|
||||
|
||||
/* Set HSDET mode to Manual—Disabled */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2,
|
||||
(0 << CS42L42_HSDET_CTRL_SHIFT) |
|
||||
(0 << CS42L42_HSDET_SET_SHIFT) |
|
||||
(0 << CS42L42_HSBIAS_REF_SHIFT) |
|
||||
(0 << CS42L42_HSDET_AUTO_TIME_SHIFT));
|
||||
|
||||
/* Configure HS DET comparator reference levels. */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL1,
|
||||
(CS42L42_HSDET_COMP1_LVL_DEFAULT << CS42L42_HSDET_COMP1_LVL_SHIFT) |
|
||||
(CS42L42_HSDET_COMP2_LVL_DEFAULT << CS42L42_HSDET_COMP2_LVL_SHIFT));
|
||||
|
||||
return hs_type;
|
||||
}
|
||||
|
||||
static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status)
|
||||
{
|
||||
int status_changed = cs42l42->force_status_change;
|
||||
|
||||
cs42l42->force_status_change = 0;
|
||||
int status_changed = 0;
|
||||
|
||||
/* TIP_SENSE INSERT/REMOVE */
|
||||
switch (reg_ts_status) {
|
||||
case CS42L42_JACK_INSERTED:
|
||||
if (!cs42l42->hp_jack_in) {
|
||||
if (cs42l42->no_type_dect) {
|
||||
status_changed = 1;
|
||||
cs42l42->hp_jack_in = 1;
|
||||
cs42l42->mic_jack_in = 0;
|
||||
} else {
|
||||
cs42l42_run_jack_detect(cs42l42);
|
||||
}
|
||||
case CS42L42_TS_PLUG:
|
||||
if (cs42l42->no_type_dect) {
|
||||
status_changed = 1;
|
||||
cs42l42->hp_jack_in = 1;
|
||||
cs42l42->mic_jack_in = 0;
|
||||
} else {
|
||||
cs42l42_run_jack_detect(cs42l42);
|
||||
}
|
||||
break;
|
||||
|
||||
case CS42L42_JACK_REMOVED:
|
||||
if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) {
|
||||
status_changed = 1;
|
||||
cs42l42->hp_jack_in = 0;
|
||||
cs42l42->mic_jack_in = 0;
|
||||
}
|
||||
case CS42L42_TS_UNPLUG:
|
||||
status_changed = 1;
|
||||
cs42l42->hp_jack_in = 0;
|
||||
cs42l42->mic_jack_in = 0;
|
||||
break;
|
||||
default:
|
||||
/* jack in transition */
|
||||
break;
|
||||
}
|
||||
|
||||
codec_dbg(cs42l42->codec, "Tip Sense Detection: (%d)\n", reg_ts_status);
|
||||
|
||||
return status_changed;
|
||||
}
|
||||
|
||||
static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42)
|
||||
{
|
||||
int current_plug_status;
|
||||
int status_changed = 0;
|
||||
int reg_cdc_status;
|
||||
int reg_hs_status;
|
||||
@ -678,46 +802,65 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42)
|
||||
int type;
|
||||
|
||||
/* Read jack detect status registers */
|
||||
reg_cdc_status = cs8409_i2c_read(cs42l42, 0x1308);
|
||||
reg_hs_status = cs8409_i2c_read(cs42l42, 0x1124);
|
||||
reg_ts_status = cs8409_i2c_read(cs42l42, 0x130f);
|
||||
reg_cdc_status = cs8409_i2c_read(cs42l42, CS42L42_CODEC_STATUS);
|
||||
reg_hs_status = cs8409_i2c_read(cs42l42, CS42L42_HS_DET_STATUS);
|
||||
reg_ts_status = cs8409_i2c_read(cs42l42, CS42L42_TSRS_PLUG_STATUS);
|
||||
|
||||
/* If status values are < 0, read error has occurred. */
|
||||
if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0)
|
||||
return -EIO;
|
||||
|
||||
current_plug_status = (reg_ts_status & (CS42L42_TS_PLUG_MASK | CS42L42_TS_UNPLUG_MASK))
|
||||
>> CS42L42_TS_PLUG_SHIFT;
|
||||
|
||||
/* HSDET_AUTO_DONE */
|
||||
if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) {
|
||||
if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE_MASK) {
|
||||
|
||||
/* Disable HSDET_AUTO_DONE */
|
||||
cs8409_i2c_write(cs42l42, 0x131b, 0xFF);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_CODEC_INT_MASK, 0xFF);
|
||||
|
||||
type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1);
|
||||
type = (reg_hs_status & CS42L42_HSDET_TYPE_MASK) >> CS42L42_HSDET_TYPE_SHIFT;
|
||||
|
||||
/* Configure the HSDET mode. */
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HSDET_CTL2, 0x80);
|
||||
|
||||
if (cs42l42->no_type_dect) {
|
||||
status_changed = cs42l42_handle_tip_sense(cs42l42, reg_ts_status);
|
||||
} else if (type == 4) {
|
||||
/* Type 4 not supported */
|
||||
status_changed = cs42l42_handle_tip_sense(cs42l42, CS42L42_JACK_REMOVED);
|
||||
status_changed = cs42l42_handle_tip_sense(cs42l42, current_plug_status);
|
||||
} else {
|
||||
if (!cs42l42->hp_jack_in) {
|
||||
if (type == CS42L42_PLUG_INVALID || type == CS42L42_PLUG_HEADPHONE) {
|
||||
codec_dbg(cs42l42->codec,
|
||||
"Auto detect value not valid (%d), running manual det\n",
|
||||
type);
|
||||
type = cs42l42_manual_hs_det(cs42l42);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case CS42L42_PLUG_CTIA:
|
||||
case CS42L42_PLUG_OMTP:
|
||||
status_changed = 1;
|
||||
cs42l42->hp_jack_in = 1;
|
||||
}
|
||||
/* type = 3 has no mic */
|
||||
if ((!cs42l42->mic_jack_in) && (type != 3)) {
|
||||
status_changed = 1;
|
||||
cs42l42->mic_jack_in = 1;
|
||||
break;
|
||||
case CS42L42_PLUG_HEADPHONE:
|
||||
status_changed = 1;
|
||||
cs42l42->hp_jack_in = 1;
|
||||
cs42l42->mic_jack_in = 0;
|
||||
break;
|
||||
default:
|
||||
status_changed = 1;
|
||||
cs42l42->hp_jack_in = 0;
|
||||
cs42l42->mic_jack_in = 0;
|
||||
break;
|
||||
}
|
||||
codec_dbg(cs42l42->codec, "Detection done (%d)\n", type);
|
||||
}
|
||||
/* Configure the HSDET mode. */
|
||||
cs8409_i2c_write(cs42l42, 0x1120, 0x80);
|
||||
|
||||
/* Enable the HPOUT ground clamp and configure the HP pull-down */
|
||||
cs8409_i2c_write(cs42l42, 0x1F06, 0x02);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_DAC_CTL2, 0x02);
|
||||
/* Re-Enable Tip Sense Interrupt */
|
||||
cs8409_i2c_write(cs42l42, 0x1320, 0xF3);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_TSRS_PLUG_INT_MASK, 0xF3);
|
||||
} else {
|
||||
status_changed = cs42l42_handle_tip_sense(cs42l42, reg_ts_status);
|
||||
status_changed = cs42l42_handle_tip_sense(cs42l42, current_plug_status);
|
||||
}
|
||||
|
||||
return status_changed;
|
||||
@ -726,19 +869,19 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42)
|
||||
static void cs42l42_resume(struct sub_codec *cs42l42)
|
||||
{
|
||||
struct hda_codec *codec = cs42l42->codec;
|
||||
unsigned int gpio_data;
|
||||
struct cs8409_spec *spec = codec->spec;
|
||||
struct cs8409_i2c_param irq_regs[] = {
|
||||
{ 0x1308, 0x00 },
|
||||
{ 0x1309, 0x00 },
|
||||
{ 0x130A, 0x00 },
|
||||
{ 0x130F, 0x00 },
|
||||
{ CS42L42_CODEC_STATUS, 0x00 },
|
||||
{ CS42L42_DET_INT_STATUS1, 0x00 },
|
||||
{ CS42L42_DET_INT_STATUS2, 0x00 },
|
||||
{ CS42L42_TSRS_PLUG_STATUS, 0x00 },
|
||||
};
|
||||
int fsv_old, fsv_new;
|
||||
|
||||
/* Bring CS42L42 out of Reset */
|
||||
gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
|
||||
gpio_data |= cs42l42->reset_gpio;
|
||||
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
|
||||
spec->gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
|
||||
spec->gpio_data |= cs42l42->reset_gpio;
|
||||
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data);
|
||||
usleep_range(10000, 15000);
|
||||
|
||||
cs42l42->suspended = 0;
|
||||
@ -750,13 +893,13 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
|
||||
/* Clear interrupts, by reading interrupt status registers */
|
||||
cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs));
|
||||
|
||||
fsv_old = cs8409_i2c_read(cs42l42, 0x2001);
|
||||
fsv_old = cs8409_i2c_read(cs42l42, CS42L42_HP_CTL);
|
||||
if (cs42l42->full_scale_vol == CS42L42_FULL_SCALE_VOL_0DB)
|
||||
fsv_new = fsv_old & ~CS42L42_FULL_SCALE_VOL_MASK;
|
||||
else
|
||||
fsv_new = fsv_old & CS42L42_FULL_SCALE_VOL_MASK;
|
||||
if (fsv_new != fsv_old)
|
||||
cs8409_i2c_write(cs42l42, 0x2001, fsv_new);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_HP_CTL, fsv_new);
|
||||
|
||||
/* we have to explicitly allow unsol event handling even during the
|
||||
* resume phase so that the jack event is processed properly
|
||||
@ -770,41 +913,40 @@ static void cs42l42_resume(struct sub_codec *cs42l42)
|
||||
static void cs42l42_suspend(struct sub_codec *cs42l42)
|
||||
{
|
||||
struct hda_codec *codec = cs42l42->codec;
|
||||
unsigned int gpio_data;
|
||||
struct cs8409_spec *spec = codec->spec;
|
||||
int reg_cdc_status = 0;
|
||||
const struct cs8409_i2c_param cs42l42_pwr_down_seq[] = {
|
||||
{ 0x1F06, 0x02 },
|
||||
{ 0x1129, 0x00 },
|
||||
{ 0x2301, 0x3F },
|
||||
{ 0x2302, 0x3F },
|
||||
{ 0x2303, 0x3F },
|
||||
{ 0x2001, 0x0F },
|
||||
{ 0x2A01, 0x00 },
|
||||
{ 0x1207, 0x00 },
|
||||
{ 0x1101, 0xFE },
|
||||
{ 0x1102, 0x8C },
|
||||
{ 0x1101, 0xFF },
|
||||
{ CS42L42_DAC_CTL2, 0x02 },
|
||||
{ CS42L42_HS_CLAMP_DISABLE, 0x00 },
|
||||
{ CS42L42_MIXER_CHA_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_ADC_VOL, 0x3F },
|
||||
{ CS42L42_MIXER_CHB_VOL, 0x3F },
|
||||
{ CS42L42_HP_CTL, 0x0F },
|
||||
{ CS42L42_ASP_RX_DAI0_EN, 0x00 },
|
||||
{ CS42L42_ASP_CLK_CFG, 0x00 },
|
||||
{ CS42L42_PWR_CTL1, 0xFE },
|
||||
{ CS42L42_PWR_CTL2, 0x8C },
|
||||
{ CS42L42_PWR_CTL1, 0xFF },
|
||||
};
|
||||
|
||||
cs8409_i2c_bulk_write(cs42l42, cs42l42_pwr_down_seq, ARRAY_SIZE(cs42l42_pwr_down_seq));
|
||||
|
||||
if (read_poll_timeout(cs8409_i2c_read, reg_cdc_status,
|
||||
(reg_cdc_status & 0x1), CS42L42_PDN_SLEEP_US, CS42L42_PDN_TIMEOUT_US,
|
||||
true, cs42l42, 0x1308) < 0)
|
||||
true, cs42l42, CS42L42_CODEC_STATUS) < 0)
|
||||
codec_warn(codec, "Timeout waiting for PDN_DONE for CS42L42\n");
|
||||
|
||||
/* Power down CS42L42 ASP/EQ/MIX/HP */
|
||||
cs8409_i2c_write(cs42l42, 0x1102, 0x9C);
|
||||
cs8409_i2c_write(cs42l42, CS42L42_PWR_CTL2, 0x9C);
|
||||
cs42l42->suspended = 1;
|
||||
cs42l42->last_page = 0;
|
||||
cs42l42->hp_jack_in = 0;
|
||||
cs42l42->mic_jack_in = 0;
|
||||
cs42l42->force_status_change = 1;
|
||||
|
||||
/* Put CS42L42 into Reset */
|
||||
gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
|
||||
gpio_data &= ~cs42l42->reset_gpio;
|
||||
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
|
||||
spec->gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0);
|
||||
spec->gpio_data &= ~cs42l42->reset_gpio;
|
||||
snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -918,6 +1060,10 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
|
||||
/* DMIC1_MO=00b, DMIC1/2_SR=1 */
|
||||
cs8409_vendor_coef_set(codec, CS8409_DMIC_CFG, 0x0003);
|
||||
break;
|
||||
case CS8409_ODIN:
|
||||
/* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=0 */
|
||||
cs8409_vendor_coef_set(codec, CS8409_PAD_CFG_SLW_RATE_CTRL, 0xfc00);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -994,6 +1140,8 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix,
|
||||
spec->gen.no_primary_hp = 1;
|
||||
spec->gen.suppress_vmaster = 1;
|
||||
|
||||
spec->speaker_pdn_gpio = 0;
|
||||
|
||||
/* GPIO 5 out, 3,4 in */
|
||||
spec->gpio_dir = spec->scodecs[CS8409_CODEC0]->reset_gpio;
|
||||
spec->gpio_data = 0;
|
||||
@ -1005,18 +1153,33 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix,
|
||||
cs8409_fix_caps(codec, CS8409_CS42L42_HP_PIN_NID);
|
||||
cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID);
|
||||
|
||||
/* Set HSBIAS_SENSE_EN and Full Scale volume for some variants. */
|
||||
spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020;
|
||||
|
||||
switch (codec->fixup_id) {
|
||||
case CS8409_WARLOCK_MLK:
|
||||
case CS8409_WARLOCK_MLK_DUAL_MIC:
|
||||
spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020;
|
||||
spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB;
|
||||
break;
|
||||
default:
|
||||
spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020;
|
||||
case CS8409_CYBORG:
|
||||
spec->scodecs[CS8409_CODEC0]->full_scale_vol =
|
||||
CS42L42_FULL_SCALE_VOL_MINUS6DB;
|
||||
spec->speaker_pdn_gpio = CS8409_CYBORG_SPEAKER_PDN;
|
||||
break;
|
||||
case CS8409_ODIN:
|
||||
spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB;
|
||||
spec->speaker_pdn_gpio = CS8409_CYBORG_SPEAKER_PDN;
|
||||
break;
|
||||
case CS8409_WARLOCK_MLK:
|
||||
case CS8409_WARLOCK_MLK_DUAL_MIC:
|
||||
spec->scodecs[CS8409_CODEC0]->full_scale_vol = CS42L42_FULL_SCALE_VOL_0DB;
|
||||
spec->speaker_pdn_gpio = CS8409_WARLOCK_SPEAKER_PDN;
|
||||
break;
|
||||
default:
|
||||
spec->scodecs[CS8409_CODEC0]->full_scale_vol =
|
||||
CS42L42_FULL_SCALE_VOL_MINUS6DB;
|
||||
spec->speaker_pdn_gpio = CS8409_WARLOCK_SPEAKER_PDN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (spec->speaker_pdn_gpio > 0) {
|
||||
spec->gpio_dir |= spec->speaker_pdn_gpio;
|
||||
spec->gpio_data |= spec->speaker_pdn_gpio;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1027,13 +1190,17 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix,
|
||||
/* add hooks */
|
||||
spec->gen.pcm_playback_hook = cs42l42_playback_pcm_hook;
|
||||
spec->gen.pcm_capture_hook = cs42l42_capture_pcm_hook;
|
||||
/* Set initial DMIC volume to -26 dB */
|
||||
snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID,
|
||||
HDA_INPUT, 0, 0xff, 0x19);
|
||||
if (codec->fixup_id != CS8409_ODIN)
|
||||
/* Set initial DMIC volume to -26 dB */
|
||||
snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID,
|
||||
HDA_INPUT, 0, 0xff, 0x19);
|
||||
snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume",
|
||||
&cs42l42_dac_volume_mixer);
|
||||
snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume",
|
||||
&cs42l42_adc_volume_mixer);
|
||||
if (spec->speaker_pdn_gpio > 0)
|
||||
snd_hda_gen_add_kctl(&spec->gen, "Speaker Playback Switch",
|
||||
&cs8409_spk_sw_ctrl);
|
||||
/* Disable Unsolicited Response during boot */
|
||||
cs8409_enable_ur(codec, 0);
|
||||
snd_hda_codec_set_name(codec, "CS8409/CS42L42");
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/cs42l42.h>
|
||||
#include <sound/hda_codec.h>
|
||||
#include "hda_local.h"
|
||||
#include "hda_auto_parser.h"
|
||||
@ -222,15 +223,8 @@ enum cs8409_coefficient_index_registers {
|
||||
#define CS42L42_HP_VOL_REAL_MAX (0)
|
||||
#define CS42L42_AMIC_VOL_REAL_MIN (-97)
|
||||
#define CS42L42_AMIC_VOL_REAL_MAX (12)
|
||||
#define CS42L42_REG_HS_VOL_CHA (0x2301)
|
||||
#define CS42L42_REG_HS_VOL_CHB (0x2303)
|
||||
#define CS42L42_REG_HS_VOL_MASK (0x003F)
|
||||
#define CS42L42_REG_AMIC_VOL (0x1D03)
|
||||
#define CS42L42_REG_AMIC_VOL_MASK (0x00FF)
|
||||
#define CS42L42_HSDET_AUTO_DONE (0x02)
|
||||
#define CS42L42_HSTYPE_MASK (0x03)
|
||||
#define CS42L42_JACK_INSERTED (0x0C)
|
||||
#define CS42L42_JACK_REMOVED (0x00)
|
||||
#define CS42L42_I2C_TIMEOUT_US (20000)
|
||||
#define CS42L42_I2C_SLEEP_US (2000)
|
||||
#define CS42L42_PDN_TIMEOUT_US (250000)
|
||||
@ -244,6 +238,8 @@ enum cs8409_coefficient_index_registers {
|
||||
#define CS42L42_I2C_ADDR (0x48 << 1)
|
||||
#define CS8409_CS42L42_RESET GENMASK(5, 5) /* CS8409_GPIO5 */
|
||||
#define CS8409_CS42L42_INT GENMASK(4, 4) /* CS8409_GPIO4 */
|
||||
#define CS8409_CYBORG_SPEAKER_PDN GENMASK(2, 2) /* CS8409_GPIO2 */
|
||||
#define CS8409_WARLOCK_SPEAKER_PDN GENMASK(1, 1) /* CS8409_GPIO1 */
|
||||
#define CS8409_CS42L42_HP_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_A
|
||||
#define CS8409_CS42L42_SPK_PIN_NID CS8409_PIN_ASP2_TRANSMITTER_A
|
||||
#define CS8409_CS42L42_AMIC_PIN_NID CS8409_PIN_ASP1_RECEIVER_A
|
||||
@ -273,6 +269,7 @@ enum {
|
||||
CS8409_FIXUPS,
|
||||
CS8409_DOLPHIN,
|
||||
CS8409_DOLPHIN_FIXUPS,
|
||||
CS8409_ODIN,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -310,7 +307,6 @@ struct sub_codec {
|
||||
|
||||
unsigned int hp_jack_in:1;
|
||||
unsigned int mic_jack_in:1;
|
||||
unsigned int force_status_change:1;
|
||||
unsigned int suspended:1;
|
||||
unsigned int paged:1;
|
||||
unsigned int last_page;
|
||||
@ -332,6 +328,8 @@ struct cs8409_spec {
|
||||
unsigned int gpio_dir;
|
||||
unsigned int gpio_data;
|
||||
|
||||
int speaker_pdn_gpio;
|
||||
|
||||
struct mutex i2c_mux;
|
||||
unsigned int i2c_clck_enabled;
|
||||
unsigned int dev_addr;
|
||||
|
@ -3131,6 +3131,7 @@ enum {
|
||||
ALC269_TYPE_ALC257,
|
||||
ALC269_TYPE_ALC215,
|
||||
ALC269_TYPE_ALC225,
|
||||
ALC269_TYPE_ALC245,
|
||||
ALC269_TYPE_ALC287,
|
||||
ALC269_TYPE_ALC294,
|
||||
ALC269_TYPE_ALC300,
|
||||
@ -3168,6 +3169,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
|
||||
case ALC269_TYPE_ALC257:
|
||||
case ALC269_TYPE_ALC215:
|
||||
case ALC269_TYPE_ALC225:
|
||||
case ALC269_TYPE_ALC245:
|
||||
case ALC269_TYPE_ALC287:
|
||||
case ALC269_TYPE_ALC294:
|
||||
case ALC269_TYPE_ALC300:
|
||||
@ -3695,7 +3697,8 @@ static void alc225_init(struct hda_codec *codec)
|
||||
hda_nid_t hp_pin = alc_get_hp_pin(spec);
|
||||
bool hp1_pin_sense, hp2_pin_sense;
|
||||
|
||||
if (spec->codec_variant != ALC269_TYPE_ALC287)
|
||||
if (spec->codec_variant != ALC269_TYPE_ALC287 &&
|
||||
spec->codec_variant != ALC269_TYPE_ALC245)
|
||||
/* required only at boot or S3 and S4 resume time */
|
||||
if (!spec->done_hp_init ||
|
||||
is_s3_resume(codec) ||
|
||||
@ -6580,18 +6583,6 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec,
|
||||
}
|
||||
}
|
||||
|
||||
static int find_comp_by_dev_name(struct alc_spec *spec, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HDA_MAX_COMPONENTS; i++) {
|
||||
if (strcmp(spec->comps[i].name, name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int comp_bind(struct device *dev)
|
||||
{
|
||||
struct hda_codec *cdc = dev_to_hda_codec(dev);
|
||||
@ -6666,50 +6657,10 @@ static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fix
|
||||
cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4);
|
||||
}
|
||||
|
||||
static void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc,
|
||||
struct snd_pcm_substream *sub, int action)
|
||||
{
|
||||
struct alc_spec *spec = cdc->spec;
|
||||
unsigned int rx_slot;
|
||||
int i;
|
||||
|
||||
switch (action) {
|
||||
case HDA_GEN_PCM_ACT_PREPARE:
|
||||
rx_slot = 0;
|
||||
i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.0");
|
||||
if (i >= 0)
|
||||
spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot);
|
||||
|
||||
rx_slot = 1;
|
||||
i = find_comp_by_dev_name(spec, "i2c-CLSA0100:00-cs35l41-hda.1");
|
||||
if (i >= 0)
|
||||
spec->comps[i].set_channel_map(spec->comps[i].dev, 0, NULL, 1, &rx_slot);
|
||||
break;
|
||||
}
|
||||
|
||||
comp_generic_playback_hook(hinfo, cdc, sub, action);
|
||||
}
|
||||
|
||||
static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix,
|
||||
int action)
|
||||
{
|
||||
struct device *dev = hda_codec_dev(cdc);
|
||||
struct alc_spec *spec = cdc->spec;
|
||||
int ret;
|
||||
|
||||
switch (action) {
|
||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||
component_match_add(dev, &spec->match, component_compare_dev_name,
|
||||
"i2c-CLSA0100:00-cs35l41-hda.0");
|
||||
component_match_add(dev, &spec->match, component_compare_dev_name,
|
||||
"i2c-CLSA0100:00-cs35l41-hda.1");
|
||||
ret = component_master_add_with_match(dev, &comp_master_ops, spec->match);
|
||||
if (ret)
|
||||
codec_err(cdc, "Fail to register component aggregator %d\n", ret);
|
||||
else
|
||||
spec->gen.pcm_playback_hook = alc287_legion_16achg6_playback_hook;
|
||||
break;
|
||||
}
|
||||
cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0100", 2);
|
||||
}
|
||||
|
||||
/* for alc295_fixup_hp_top_speakers */
|
||||
@ -10148,7 +10099,10 @@ static int patch_alc269(struct hda_codec *codec)
|
||||
case 0x10ec0245:
|
||||
case 0x10ec0285:
|
||||
case 0x10ec0289:
|
||||
spec->codec_variant = ALC269_TYPE_ALC215;
|
||||
if (alc_get_coef0(codec) & 0x0010)
|
||||
spec->codec_variant = ALC269_TYPE_ALC245;
|
||||
else
|
||||
spec->codec_variant = ALC269_TYPE_ALC215;
|
||||
spec->shutup = alc225_shutup;
|
||||
spec->init_hook = alc225_init;
|
||||
spec->gen.mixer_nid = 0;
|
||||
|
@ -561,8 +561,9 @@ static snd_pcm_uframes_t lola_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits)
|
||||
{
|
||||
int i;
|
||||
u8 num_streams = min_t(u8, pcm->num_streams, ARRAY_SIZE(pcm->streams));
|
||||
|
||||
for (i = 0; bits && i < pcm->num_streams; i++) {
|
||||
for (i = 0; bits && i < num_streams; i++) {
|
||||
if (bits & (1 << i)) {
|
||||
struct lola_stream *str = &pcm->streams[i];
|
||||
if (str->substream && str->running)
|
||||
|
@ -3314,7 +3314,7 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
|
||||
if (hdsp->io_type == RPM) {
|
||||
/* RPM Bypass, Disconnect and Input switches */
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) {
|
||||
err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
|
||||
err = snd_ctl_add(card, snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ menuconfig SND_SOC
|
||||
|
||||
If you want ASoC support, you should say Y here and also to the
|
||||
specific driver for your SoC platform below.
|
||||
|
||||
|
||||
ASoC provides power efficient ALSA support for embedded battery powered
|
||||
SoC based systems like PDA's, Phones and Personal Media Players.
|
||||
|
||||
@ -55,6 +55,13 @@ config SND_SOC_TOPOLOGY_KUNIT_TEST
|
||||
userspace applications such as pulseaudio, to prevent unnecessary
|
||||
problems.
|
||||
|
||||
config SND_SOC_UTILS_KUNIT_TEST
|
||||
tristate "KUnit tests for SoC utils"
|
||||
depends on KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
If you want to perform tests on ALSA SoC utils library say Y here.
|
||||
|
||||
config SND_SOC_ACPI
|
||||
tristate
|
||||
|
||||
|
@ -12,6 +12,11 @@ ifneq ($(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TEST),)
|
||||
obj-$(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TEST) := soc-topology-test.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_SND_SOC_UTILS_KUNIT_TEST),)
|
||||
# snd-soc-test-objs := soc-utils-test.o
|
||||
obj-$(CONFIG_SND_SOC_UTILS_KUNIT_TEST) := soc-utils-test.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),)
|
||||
snd-soc-core-objs += soc-generic-dmaengine-pcm.o
|
||||
endif
|
||||
|
@ -71,7 +71,7 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
|
||||
SND_JACK_HEADSET | SND_JACK_LINEOUT |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&cz_jack, NULL, 0);
|
||||
&cz_jack);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "HP jack creation failed %d\n", ret);
|
||||
return ret;
|
||||
@ -151,7 +151,7 @@ static int cz_rt5682_init(struct snd_soc_pcm_runtime *rtd)
|
||||
SND_JACK_HEADSET | SND_JACK_LINEOUT |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&cz_jack, NULL, 0);
|
||||
&cz_jack);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "HP jack creation failed %d\n", ret);
|
||||
return ret;
|
||||
|
@ -80,7 +80,7 @@ static int cz_init(struct snd_soc_pcm_runtime *rtd)
|
||||
SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&cz_jack, NULL, 0);
|
||||
&cz_jack);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "HP jack creation failed %d\n", ret);
|
||||
return ret;
|
||||
|
@ -42,7 +42,7 @@ config SND_AMD_ASOC_RENOIR
|
||||
|
||||
config SND_SOC_AMD_MACH_COMMON
|
||||
tristate
|
||||
depends on X86 && PCI && I2C && GPIOLIB
|
||||
depends on X86 && PCI && I2C
|
||||
select CLK_FIXED_FCH
|
||||
select SND_SOC_RT5682_I2C
|
||||
select SND_SOC_DMIC
|
||||
@ -54,14 +54,14 @@ config SND_SOC_AMD_MACH_COMMON
|
||||
|
||||
config SND_SOC_AMD_LEGACY_MACH
|
||||
tristate "AMD Legacy Machine Driver Support"
|
||||
depends on X86 && PCI && I2C && GPIOLIB
|
||||
depends on X86 && PCI && I2C
|
||||
select SND_SOC_AMD_MACH_COMMON
|
||||
help
|
||||
This option enables legacy sound card support for ACP audio.
|
||||
|
||||
config SND_SOC_AMD_SOF_MACH
|
||||
tristate "AMD SOF Machine Driver Support"
|
||||
depends on X86 && PCI && I2C && GPIOLIB
|
||||
depends on X86 && PCI && I2C
|
||||
select SND_SOC_AMD_MACH_COMMON
|
||||
help
|
||||
This option enables SOF sound card support for ACP audio.
|
||||
|
@ -27,7 +27,6 @@ static struct acp_card_drvdata rt5682_rt1019_data = {
|
||||
.hs_codec_id = RT5682,
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.gpio_spkr_en = EN_SPKR_GPIO_GB,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata rt5682s_max_data = {
|
||||
@ -37,7 +36,6 @@ static struct acp_card_drvdata rt5682s_max_data = {
|
||||
.hs_codec_id = RT5682S,
|
||||
.amp_codec_id = MAX98360A,
|
||||
.dmic_codec_id = DMIC,
|
||||
.gpio_spkr_en = EN_SPKR_GPIO_NONE,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata rt5682s_rt1019_data = {
|
||||
@ -47,7 +45,6 @@ static struct acp_card_drvdata rt5682s_rt1019_data = {
|
||||
.hs_codec_id = RT5682S,
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.gpio_spkr_en = EN_SPKR_GPIO_NONE,
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new acp_controls[] = {
|
||||
@ -62,16 +59,15 @@ static const struct snd_kcontrol_new acp_controls[] = {
|
||||
static const struct snd_soc_dapm_widget acp_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
SND_SOC_DAPM_SPK("Spk", event_spkr_handler),
|
||||
SND_SOC_DAPM_SPK("Left Spk", event_spkr_handler),
|
||||
SND_SOC_DAPM_SPK("Right Spk", event_spkr_handler),
|
||||
SND_SOC_DAPM_SPK("Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("Left Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("Right Spk", NULL),
|
||||
};
|
||||
|
||||
static int acp_asoc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = NULL;
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int spkr_gpio;
|
||||
int ret;
|
||||
|
||||
if (!pdev->id_entry)
|
||||
@ -89,20 +85,9 @@ static int acp_asoc_probe(struct platform_device *pdev)
|
||||
card->controls = acp_controls;
|
||||
card->num_controls = ARRAY_SIZE(acp_controls);
|
||||
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
||||
spkr_gpio = ((struct acp_card_drvdata *)(card->drvdata))->gpio_spkr_en;
|
||||
|
||||
acp_legacy_dai_links_create(card);
|
||||
|
||||
if (gpio_is_valid(spkr_gpio)) {
|
||||
ret = devm_gpio_request(dev, spkr_gpio, "spkren");
|
||||
if (ret) {
|
||||
dev_err(dev, "(%s) gpio request failed: %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(spkr_gpio, 0);
|
||||
}
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
@ -131,6 +116,7 @@ static const struct platform_device_id board_ids[] = {
|
||||
};
|
||||
static struct platform_driver acp_asoc_audio = {
|
||||
.driver = {
|
||||
.pm = &snd_soc_pm_ops,
|
||||
.name = "acp_mach",
|
||||
},
|
||||
.probe = acp_asoc_probe,
|
||||
|
@ -71,31 +71,6 @@ static const struct snd_soc_dapm_route rt5682_map[] = {
|
||||
{ "IN1P", NULL, "Headset Mic" },
|
||||
};
|
||||
|
||||
int event_spkr_handler(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||
struct snd_soc_card *card = dapm->card;
|
||||
struct acp_card_drvdata *drvdata = snd_soc_card_get_drvdata(card);
|
||||
|
||||
if (!gpio_is_valid(drvdata->gpio_spkr_en))
|
||||
return 0;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
gpio_set_value(drvdata->gpio_spkr_en, 1);
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
gpio_set_value(drvdata->gpio_spkr_en, 0);
|
||||
break;
|
||||
default:
|
||||
dev_warn(card->dev, "%s invalid setting\n", __func__);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(event_spkr_handler, SND_SOC_AMD_MACH);
|
||||
|
||||
/* Define card ops for RT5682 CODEC */
|
||||
static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
@ -145,7 +120,7 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
|
||||
SND_JACK_HEADSET | SND_JACK_LINEOUT |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&pco_jack, NULL, 0);
|
||||
&pco_jack);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "HP jack creation failed %d\n", ret);
|
||||
return ret;
|
||||
@ -266,7 +241,7 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
|
||||
SND_JACK_HEADSET | SND_JACK_LINEOUT |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&pco_jack, NULL, 0);
|
||||
&pco_jack);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "HP jack creation failed %d\n", ret);
|
||||
return ret;
|
||||
|
@ -17,11 +17,6 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/module.h>
|
||||
#include <sound/soc.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#define EN_SPKR_GPIO_GB 0x11F
|
||||
#define EN_SPKR_GPIO_NONE -EINVAL
|
||||
|
||||
enum be_id {
|
||||
HEADSET_BE_ID = 0,
|
||||
@ -54,11 +49,9 @@ struct acp_card_drvdata {
|
||||
unsigned int dai_fmt;
|
||||
struct clk *wclk;
|
||||
struct clk *bclk;
|
||||
unsigned int gpio_spkr_en;
|
||||
};
|
||||
|
||||
int acp_sofdsp_dai_links_create(struct snd_soc_card *card);
|
||||
int acp_legacy_dai_links_create(struct snd_soc_card *card);
|
||||
int event_spkr_handler(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event);
|
||||
|
||||
#endif
|
||||
|
@ -27,7 +27,6 @@ static struct acp_card_drvdata sof_rt5682_rt1019_data = {
|
||||
.hs_codec_id = RT5682,
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.gpio_spkr_en = EN_SPKR_GPIO_GB,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata sof_rt5682_max_data = {
|
||||
@ -37,7 +36,6 @@ static struct acp_card_drvdata sof_rt5682_max_data = {
|
||||
.hs_codec_id = RT5682,
|
||||
.amp_codec_id = MAX98360A,
|
||||
.dmic_codec_id = DMIC,
|
||||
.gpio_spkr_en = EN_SPKR_GPIO_NONE,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata sof_rt5682s_rt1019_data = {
|
||||
@ -56,7 +54,6 @@ static struct acp_card_drvdata sof_rt5682s_max_data = {
|
||||
.hs_codec_id = RT5682S,
|
||||
.amp_codec_id = MAX98360A,
|
||||
.dmic_codec_id = DMIC,
|
||||
.gpio_spkr_en = EN_SPKR_GPIO_NONE,
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new acp_controls[] = {
|
||||
@ -70,16 +67,15 @@ static const struct snd_kcontrol_new acp_controls[] = {
|
||||
static const struct snd_soc_dapm_widget acp_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||
SND_SOC_DAPM_SPK("Spk", event_spkr_handler),
|
||||
SND_SOC_DAPM_SPK("Left Spk", event_spkr_handler),
|
||||
SND_SOC_DAPM_SPK("Right Spk", event_spkr_handler),
|
||||
SND_SOC_DAPM_SPK("Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("Left Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("Right Spk", NULL),
|
||||
};
|
||||
|
||||
static int acp_sof_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = NULL;
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int spkr_gpio;
|
||||
int ret;
|
||||
|
||||
if (!pdev->id_entry)
|
||||
@ -97,20 +93,9 @@ static int acp_sof_probe(struct platform_device *pdev)
|
||||
card->controls = acp_controls;
|
||||
card->num_controls = ARRAY_SIZE(acp_controls);
|
||||
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
||||
spkr_gpio = ((struct acp_card_drvdata *)(card->drvdata))->gpio_spkr_en;
|
||||
|
||||
acp_sofdsp_dai_links_create(card);
|
||||
|
||||
if (gpio_is_valid(spkr_gpio)) {
|
||||
ret = devm_gpio_request(dev, spkr_gpio, "spkren");
|
||||
if (ret) {
|
||||
dev_err(dev, "(%s) gpio request failed: %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(spkr_gpio, 0);
|
||||
}
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
@ -144,6 +129,7 @@ static const struct platform_device_id board_ids[] = {
|
||||
static struct platform_driver acp_asoc_audio = {
|
||||
.driver = {
|
||||
.name = "sof_mach",
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = acp_sof_probe,
|
||||
.id_table = board_ids,
|
||||
|
@ -90,7 +90,7 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
|
||||
SND_JACK_HEADSET | SND_JACK_LINEOUT |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&pco_jack, NULL, 0);
|
||||
&pco_jack);
|
||||
if (ret) {
|
||||
dev_err(card->dev, "HP jack creation failed %d\n", ret);
|
||||
return ret;
|
||||
|
@ -17,10 +17,8 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
@ -61,10 +59,10 @@ static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd)
|
||||
* Headset buttons map to the google Reference headset.
|
||||
* These can be configured by userspace.
|
||||
*/
|
||||
ret = snd_soc_card_jack_new(card, "Headset Jack",
|
||||
SND_JACK_HEADSET | SND_JACK_BTN_0,
|
||||
&vg_headset, acp5x_nau8821_jack_pins,
|
||||
ARRAY_SIZE(acp5x_nau8821_jack_pins));
|
||||
ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
|
||||
SND_JACK_HEADSET | SND_JACK_BTN_0,
|
||||
&vg_headset, acp5x_nau8821_jack_pins,
|
||||
ARRAY_SIZE(acp5x_nau8821_jack_pins));
|
||||
if (ret) {
|
||||
dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
|
||||
return ret;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <sound/pcm_params.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include "acp6x.h"
|
||||
|
||||
@ -45,108 +46,126 @@ static struct snd_soc_card acp6x_card = {
|
||||
|
||||
static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D2"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D3"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D4"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D5"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CF"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CG"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CR"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21AW"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21AX"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21BN"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21BQ"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CH"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CK"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21CL"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D8"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21D9"),
|
||||
@ -157,18 +176,33 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
|
||||
static int acp6x_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct dmi_system_id *dmi_id;
|
||||
struct acp6x_pdm *machine = NULL;
|
||||
struct snd_soc_card *card;
|
||||
struct acpi_device *adev;
|
||||
int ret;
|
||||
const struct dmi_system_id *dmi_id;
|
||||
|
||||
/* check the parent device's firmware node has _DSD or not */
|
||||
adev = ACPI_COMPANION(pdev->dev.parent);
|
||||
if (adev) {
|
||||
const union acpi_object *obj;
|
||||
|
||||
if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) &&
|
||||
obj->integer.value == 1)
|
||||
platform_set_drvdata(pdev, &acp6x_card);
|
||||
}
|
||||
|
||||
/* check for any DMI overrides */
|
||||
dmi_id = dmi_first_match(yc_acp_quirk_table);
|
||||
if (!dmi_id)
|
||||
if (dmi_id)
|
||||
platform_set_drvdata(pdev, dmi_id->driver_data);
|
||||
|
||||
card = platform_get_drvdata(pdev);
|
||||
if (!card)
|
||||
return -ENODEV;
|
||||
card = &acp6x_card;
|
||||
dev_info(&pdev->dev, "Enabling ACP DMIC support via %s", dmi_id ? "DMI" : "ACPI");
|
||||
acp6x_card.dev = &pdev->dev;
|
||||
|
||||
platform_set_drvdata(pdev, card);
|
||||
snd_soc_card_set_drvdata(card, machine);
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user