sound updates for 4.18
We've got many code additions at this cycle as a result of quite a few new drivers. Below are highlights: Core stuff: - Fix the long-standing issue with the device registration order; the control device is now registered at last - PCM locking code cleanups for RT kernels - Fixes for possible races in ALSA timer resolution accesses - TLV offset definitions in uapi ASoC: - Many fixes for the topology stuff, including fixes for v4 ABI compatibility - Lots of cleanups / quirks for Intel platforms based on Realtek CODECs - Continued componentization works, removing legacy CODEC stuff - Conversion of OMAP DMA to the new, more standard SDMA-PCM driver - Fixes and updates to Cirrus Logic SoC drivers - New Qualcomm DSP support - New drivers for Analog SSM2305, Atmel I2S controllers, Mediatek MT6351, MT6797 and MT7622, Qualcomm DSPs, Realtek RT1305, RT1306 and RT5668 and TI TSCS454 HD-audio: - Finally better support for some CA0132 boards, allowing Windows firmware - HP Spectre x360 support along with a bulk of COEF stuff - Blacklisting power save default some known boards reported on Fedora USB-audio: - Continued improvements on UAC3 support; now BADD is supported - Fixes / improvements for Dell WD15 dock - Allow DMA coherent pages for PCM buffers for ARCH, MIPS & co Others: - New Xen sound frontend driver support - Cache implementation and other improvements for FireWire DICE - Conversions to octal permissions in allover places -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAlsXjEAOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE/szw/9FdtjD7LOBMNgbVbeU+SDTEUGh1OdIElSE+bL vU1USUNud9TgYb4SFM4grjsB9v6vM+bZ8mquzLpSzGj2J/Yl3dT7reyr6TYfoGfE oCETfYLk0gbhQrrqWoVwRHsPAJYyj6dGXZ/Kiy9MuD9bfWUGAehuqKl1inySxcGb VTrhlegHApRJ7z+Yzn6K3Git+aCYhpgxO5NK1DkoagHAsAhJhdavYWhm8lcQ4pnO UlahRms0cTpDFrIkHHKH+c1ihyxn3RVpueQIIpx5xRpIHXezMnUk8mpRduqcYGk2 9cxVlC4KMucsAud39joGN6BWlkmfpmlMfGkdVlAnlBpdTyYC1pJRCKPXX3P+d9Tk NvH3jKx/izNYFPLOysoV4vc5puDqSEfAC3geD+ugJFhhJuH9sAMyGOx9MRhC6ebf qGI2IEhyn9tVc8/f3glEqS79WDHas+dUCkXxhbAQtj4NcjqgXkM26h5MnrzIYV23 m5iAzXIDuT44Qw1BxHQb40DzgHZMU3p/c/PAqU/Ex9+Oi1mq6E8V7MH+n9Ylo2vN Mw3atYiLqv9xv+7/MmvGUQuTyMR3HB0KyNUCcSyuWPnuqZ/Gi+wIg9cuYXYfrn57 NtCoW4gzaex909z+QoZa5YxYRfZBJuRjYU0ugOBdK6R3+l/6IsGTasdR6LqngYY6 RIgK2S8= =37hC -----END PGP SIGNATURE----- Merge tag 'sound-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "We've got many code additions at this cycle as a result of quite a few new drivers. Below are highlights: Core stuff: - Fix the long-standing issue with the device registration order; the control device is now registered at last - PCM locking code cleanups for RT kernels - Fixes for possible races in ALSA timer resolution accesses - TLV offset definitions in uapi ASoC: - Many fixes for the topology stuff, including fixes for v4 ABI compatibility - Lots of cleanups / quirks for Intel platforms based on Realtek CODECs - Continued componentization works, removing legacy CODEC stuff - Conversion of OMAP DMA to the new, more standard SDMA-PCM driver - Fixes and updates to Cirrus Logic SoC drivers - New Qualcomm DSP support - New drivers for Analog SSM2305, Atmel I2S controllers, Mediatek MT6351, MT6797 and MT7622, Qualcomm DSPs, Realtek RT1305, RT1306 and RT5668 and TI TSCS454 HD-audio: - Finally better support for some CA0132 boards, allowing Windows firmware - HP Spectre x360 support along with a bulk of COEF stuff - Blacklisting power save default some known boards reported on Fedora USB-audio: - Continued improvements on UAC3 support; now BADD is supported - Fixes / improvements for Dell WD15 dock - Allow DMA coherent pages for PCM buffers for ARCH, MIPS & co Others: - New Xen sound frontend driver support - Cache implementation and other improvements for FireWire DICE - Conversions to octal permissions in allover places" * tag 'sound-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (386 commits) ASoC: dapm: delete dapm_kcontrol_data paths list before freeing it ALSA: usb-audio: remove redundant check on err ASoC: topology: Move skl-tplg-interface.h to uapi ASoC: topology: Move v4 manifest header data structures to uapi ASoC: topology: Improve backwards compatibility with v4 topology files ALSA: pci/hda: Remove unused, broken, header file ASoC: TSCS454: Add Support ASoC: Intel: kbl: Move codec sysclk config to codec_init function ASoC: simple-card: set cpu dai clk in hw_params ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream() ALSA: oxygen: use match_string() helper ASoC: dapm: use match_string() helper ASoC: max98095: use match_string() helper ASoC: max98088: use match_string() helper ASoC: Intel: bytcr_rt5651: Set card long_name based on quirks ASoC: mt6797-mt6351: add hostless phone call path ASoC: mt6797: add Hostless DAI ASoC: mt6797: add PCM interface ASoC: mediatek: export mtk-afe symbols as needed ASoC: codecs: PCM1789: include gpio/consumer.h ...
This commit is contained in:
commit
126f7051b4
382 changed files with 38528 additions and 5456 deletions
3
.mailmap
3
.mailmap
|
@ -186,6 +186,9 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
|
|||
Uwe Kleine-König <ukl@pengutronix.de>
|
||||
Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
|
||||
Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
|
||||
Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com>
|
||||
Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com>
|
||||
Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org>
|
||||
Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
|
||||
Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
|
||||
Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
|
||||
|
|
84
Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
Normal file
84
Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
Normal file
|
@ -0,0 +1,84 @@
|
|||
Qualcomm APR (Asynchronous Packet Router) binding
|
||||
|
||||
This binding describes the Qualcomm APR. APR is a IPC protocol for
|
||||
communication between Application processor and QDSP. APR is mainly
|
||||
used for audio/voice services on the QDSP.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,apr-v<VERSION-NUMBER>", example "qcom,apr-v2"
|
||||
|
||||
- reg
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Destination processor ID.
|
||||
Possible values are :
|
||||
1 - APR simulator
|
||||
2 - PC
|
||||
3 - MODEM
|
||||
4 - ADSP
|
||||
5 - APPS
|
||||
6 - MODEM2
|
||||
7 - APPS2
|
||||
|
||||
= APR SERVICES
|
||||
Each subnode of the APR node represents service tied to this apr. The name
|
||||
of the nodes are not important. The properties of these nodes are defined
|
||||
by the individual bindings for the specific service
|
||||
- All APR services MUST contain the following property:
|
||||
|
||||
- reg
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: APR Service ID
|
||||
Possible values are :
|
||||
3 - DSP Core Service
|
||||
4 - Audio Front End Service.
|
||||
5 - Voice Stream Manager Service.
|
||||
6 - Voice processing manager.
|
||||
7 - Audio Stream Manager Service.
|
||||
8 - Audio Device Manager Service.
|
||||
9 - Multimode voice manager.
|
||||
10 - Core voice stream.
|
||||
11 - Core voice processor.
|
||||
12 - Ultrasound stream manager.
|
||||
13 - Listen stream manager.
|
||||
|
||||
= EXAMPLE
|
||||
The following example represents a QDSP based sound card on a MSM8996 device
|
||||
which uses apr as communication between Apps and QDSP.
|
||||
|
||||
apr@4 {
|
||||
compatible = "qcom,apr-v2";
|
||||
reg = <APR_DOMAIN_ADSP>;
|
||||
|
||||
q6core@3 {
|
||||
compatible = "qcom,q6core";
|
||||
reg = <APR_SVC_ADSP_CORE>;
|
||||
};
|
||||
|
||||
q6afe@4 {
|
||||
compatible = "qcom,q6afe";
|
||||
reg = <APR_SVC_AFE>;
|
||||
|
||||
dais {
|
||||
#sound-dai-cells = <1>;
|
||||
hdmi@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
q6asm@7 {
|
||||
compatible = "qcom,q6asm";
|
||||
reg = <APR_SVC_ASM>;
|
||||
...
|
||||
};
|
||||
|
||||
q6adm@8 {
|
||||
compatible = "qcom,q6adm";
|
||||
reg = <APR_SVC_ADM>;
|
||||
...
|
||||
};
|
||||
};
|
14
Documentation/devicetree/bindings/sound/adi,ssm2305.txt
Normal file
14
Documentation/devicetree/bindings/sound/adi,ssm2305.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
Analog Devices SSM2305 Speaker Amplifier
|
||||
========================================
|
||||
|
||||
Required properties:
|
||||
- compatible : "adi,ssm2305"
|
||||
- shutdown-gpios : The gpio connected to the shutdown pin.
|
||||
The gpio signal is ACTIVE_LOW.
|
||||
|
||||
Example:
|
||||
|
||||
ssm2305: analog-amplifier {
|
||||
compatible = "adi,ssm2305";
|
||||
shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
|
||||
};
|
47
Documentation/devicetree/bindings/sound/atmel-i2s.txt
Normal file
47
Documentation/devicetree/bindings/sound/atmel-i2s.txt
Normal file
|
@ -0,0 +1,47 @@
|
|||
* Atmel I2S controller
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "atmel,sama5d2-i2s".
|
||||
- reg: Should be the physical base address of the controller and the
|
||||
length of memory mapped region.
|
||||
- interrupts: Should contain the interrupt for the controller.
|
||||
- dmas: Should be one per channel name listed in the dma-names property,
|
||||
as described in atmel-dma.txt and dma.txt files.
|
||||
- dma-names: Two dmas have to be defined, "tx" and "rx".
|
||||
This IP also supports one shared channel for both rx and tx;
|
||||
if this mode is used, one "rx-tx" name must be used.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
Please refer to clock-bindings.txt.
|
||||
- clock-names: Should be one of each entry matching the clocks phandles list:
|
||||
- "pclk" (peripheral clock) Required.
|
||||
- "gclk" (generated clock) Optional (1).
|
||||
- "aclk" (Audio PLL clock) Optional (1).
|
||||
- "muxclk" (I2S mux clock) Optional (1).
|
||||
|
||||
Optional properties:
|
||||
- pinctrl-0: Should specify pin control groups used for this controller.
|
||||
- princtrl-names: Should contain only one value - "default".
|
||||
|
||||
|
||||
(1) : Only the peripheral clock is required. The generated clock, the Audio
|
||||
PLL clock adn the I2S mux clock are optional and should only be set
|
||||
together, when Master Mode is required.
|
||||
|
||||
Example:
|
||||
|
||||
i2s@f8050000 {
|
||||
compatible = "atmel,sama5d2-i2s";
|
||||
reg = <0xf8050000 0x300>;
|
||||
interrupts = <54 IRQ_TYPE_LEVEL_HIGH 7>;
|
||||
dmas = <&dma0
|
||||
(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
|
||||
AT91_XDMAC_DT_PERID(31))>,
|
||||
<&dma0
|
||||
(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
|
||||
AT91_XDMAC_DT_PERID(32))>;
|
||||
dma-names = "tx", "rx";
|
||||
clocks = <&i2s0_clk>, <&i2s0_gclk>, <&audio_pll_pmc>, <&i2s0muxck>;
|
||||
clock-names = "pclk", "gclk", "aclk", "muxclk";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2s0_default>;
|
||||
};
|
|
@ -16,7 +16,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: cs42888@48 {
|
||||
cs42888: codec@48 {
|
||||
compatible = "cirrus,cs42888";
|
||||
reg = <0x48>;
|
||||
clocks = <&codec_mclk 0>;
|
||||
|
|
|
@ -31,14 +31,16 @@ Required properties:
|
|||
it. This property is optional depending on the SoC
|
||||
design.
|
||||
|
||||
- big-endian : If this property is absent, the little endian mode
|
||||
will be in use as default. Otherwise, the big endian
|
||||
mode will be in use for all the device registers.
|
||||
|
||||
- fsl,asrc-rate : Defines a mutual sample rate used by DPCM Back Ends.
|
||||
|
||||
- fsl,asrc-width : Defines a mutual sample width used by DPCM Back Ends.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- big-endian : If this property is absent, the little endian mode
|
||||
will be in use as default. Otherwise, the big endian
|
||||
mode will be in use for all the device registers.
|
||||
|
||||
Example:
|
||||
|
||||
asrc: asrc@2034000 {
|
||||
|
|
|
@ -42,6 +42,8 @@ Required properties:
|
|||
means all the settings for Receiving would be
|
||||
duplicated from Transmition related registers.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- big-endian : If this property is absent, the native endian mode
|
||||
will be in use as default, or the big endian mode
|
||||
will be in use for all the device registers.
|
||||
|
|
|
@ -33,6 +33,8 @@ Required properties:
|
|||
it. This property is optional depending on the SoC
|
||||
design.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- big-endian : If this property is absent, the native endian mode
|
||||
will be in use as default, or the big endian mode
|
||||
will be in use for all the device registers.
|
||||
|
|
|
@ -28,9 +28,6 @@ Required properties:
|
|||
pinctrl-names. See ../pinctrl/pinctrl-bindings.txt
|
||||
for details of the property values.
|
||||
|
||||
- big-endian : Boolean property, required if all the FTM_PWM
|
||||
registers are big-endian rather than little-endian.
|
||||
|
||||
- lsb-first : Configures whether the LSB or the MSB is transmitted
|
||||
first for the fifo data. If this property is absent,
|
||||
the MSB is transmitted first as default, or the LSB
|
||||
|
@ -48,6 +45,11 @@ Required properties:
|
|||
receive data by following their own bit clocks and
|
||||
frame sync clocks separately.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- big-endian : Boolean property, required if all the SAI
|
||||
registers are big-endian rather than little-endian.
|
||||
|
||||
Optional properties (for mx6ul):
|
||||
|
||||
- fsl,sai-mclk-direction-output: This is a boolean property. If present,
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
Mediatek AFE PCM controller for mt2701
|
||||
|
||||
Required properties:
|
||||
- compatible = "mediatek,mt2701-audio";
|
||||
- compatible: should be one of the followings.
|
||||
- "mediatek,mt2701-audio"
|
||||
- "mediatek,mt7622-audio"
|
||||
- interrupts: should contain AFE and ASYS interrupts
|
||||
- interrupt-names: should be "afe" and "asys"
|
||||
- power-domains: should define the power domain
|
||||
|
|
16
Documentation/devicetree/bindings/sound/mt6351.txt
Normal file
16
Documentation/devicetree/bindings/sound/mt6351.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
Mediatek MT6351 Audio Codec
|
||||
|
||||
The communication between MT6351 and SoC is through Mediatek PMIC wrapper.
|
||||
For more detail, please visit Mediatek PMIC wrapper documentation.
|
||||
|
||||
Must be a child node of PMIC wrapper.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "mediatek,mt6351-sound".
|
||||
|
||||
Example:
|
||||
|
||||
mt6351_snd {
|
||||
compatible = "mediatek,mt6351-sound";
|
||||
};
|
42
Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt
Normal file
42
Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt
Normal file
|
@ -0,0 +1,42 @@
|
|||
Mediatek AFE PCM controller for mt6797
|
||||
|
||||
Required properties:
|
||||
- compatible = "mediatek,mt6797-audio";
|
||||
- reg: register location and size
|
||||
- interrupts: should contain AFE interrupt
|
||||
- power-domains: should define the power domain
|
||||
- clocks: Must contain an entry for each entry in clock-names
|
||||
- clock-names: should have these clock names:
|
||||
"infra_sys_audio_clk",
|
||||
"infra_sys_audio_26m",
|
||||
"mtkaif_26m_clk",
|
||||
"top_mux_audio",
|
||||
"top_mux_aud_intbus",
|
||||
"top_sys_pll3_d4",
|
||||
"top_sys_pll1_d4",
|
||||
"top_clk26m_clk";
|
||||
|
||||
Example:
|
||||
|
||||
afe: mt6797-afe-pcm@11220000 {
|
||||
compatible = "mediatek,mt6797-audio";
|
||||
reg = <0 0x11220000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_LOW>;
|
||||
power-domains = <&scpsys MT6797_POWER_DOMAIN_AUDIO>;
|
||||
clocks = <&infrasys CLK_INFRA_AUDIO>,
|
||||
<&infrasys CLK_INFRA_AUDIO_26M>,
|
||||
<&infrasys CLK_INFRA_AUDIO_26M_PAD_TOP>,
|
||||
<&topckgen CLK_TOP_MUX_AUDIO>,
|
||||
<&topckgen CLK_TOP_MUX_AUD_INTBUS>,
|
||||
<&topckgen CLK_TOP_SYSPLL3_D4>,
|
||||
<&topckgen CLK_TOP_SYSPLL1_D4>,
|
||||
<&clk26m>;
|
||||
clock-names = "infra_sys_audio_clk",
|
||||
"infra_sys_audio_26m",
|
||||
"mtkaif_26m_clk",
|
||||
"top_mux_audio",
|
||||
"top_mux_aud_intbus",
|
||||
"top_sys_pll3_d4",
|
||||
"top_sys_pll1_d4",
|
||||
"top_clk26m_clk";
|
||||
};
|
14
Documentation/devicetree/bindings/sound/mt6797-mt6351.txt
Normal file
14
Documentation/devicetree/bindings/sound/mt6797-mt6351.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
MT6797 with MT6351 CODEC
|
||||
|
||||
Required properties:
|
||||
- compatible: "mediatek,mt6797-mt6351-sound"
|
||||
- mediatek,platform: the phandle of MT6797 ASoC platform
|
||||
- mediatek,audio-codec: the phandles of MT6351 codec
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "mediatek,mt6797-mt6351-sound";
|
||||
mediatek,audio-codec = <&mt6351_snd>;
|
||||
mediatek,platform = <&afe>;
|
||||
};
|
109
Documentation/devicetree/bindings/sound/qcom,apq8096.txt
Normal file
109
Documentation/devicetree/bindings/sound/qcom,apq8096.txt
Normal file
|
@ -0,0 +1,109 @@
|
|||
* Qualcomm Technologies APQ8096 ASoC sound card driver
|
||||
|
||||
This binding describes the APQ8096 sound card, which uses qdsp for audio.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,apq8096-sndcard"
|
||||
|
||||
- qcom,audio-routing:
|
||||
Usage: Optional
|
||||
Value type: <stringlist>
|
||||
Definition: A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the
|
||||
connection's sink, the second being the connection's
|
||||
source. Valid names could be power supplies, MicBias
|
||||
of codec and the jacks on the board:
|
||||
Valid names include:
|
||||
|
||||
Board Connectors:
|
||||
"Headphone Left"
|
||||
"Headphone Right"
|
||||
"Earphone"
|
||||
"Line Out1"
|
||||
"Line Out2"
|
||||
"Line Out3"
|
||||
"Line Out4"
|
||||
"Analog Mic1"
|
||||
"Analog Mic2"
|
||||
"Analog Mic3"
|
||||
"Analog Mic4"
|
||||
"Analog Mic5"
|
||||
"Analog Mic6"
|
||||
"Digital Mic2"
|
||||
"Digital Mic3"
|
||||
|
||||
Audio pins and MicBias on WCD9335 Codec:
|
||||
"MIC_BIAS1
|
||||
"MIC_BIAS2"
|
||||
"MIC_BIAS3"
|
||||
"MIC_BIAS4"
|
||||
"AMIC1"
|
||||
"AMIC2"
|
||||
"AMIC3"
|
||||
"AMIC4"
|
||||
"AMIC5"
|
||||
"AMIC6"
|
||||
"AMIC6"
|
||||
"DMIC1"
|
||||
"DMIC2"
|
||||
"DMIC3"
|
||||
= dailinks
|
||||
Each subnode of sndcard represents either a dailink, and subnodes of each
|
||||
dailinks would be cpu/codec/platform dais.
|
||||
|
||||
- link-name:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: User friendly name for dai link
|
||||
|
||||
= CPU, PLATFORM, CODEC dais subnodes
|
||||
- cpu:
|
||||
Usage: required
|
||||
Value type: <subnode>
|
||||
Definition: cpu dai sub-node
|
||||
|
||||
- codec:
|
||||
Usage: Optional
|
||||
Value type: <subnode>
|
||||
Definition: codec dai sub-node
|
||||
|
||||
- platform:
|
||||
Usage: Optional
|
||||
Value type: <subnode>
|
||||
Definition: platform dai sub-node
|
||||
|
||||
- sound-dai:
|
||||
Usage: required
|
||||
Value type: <phandle with arguments>
|
||||
Definition: dai phandle/s and port of CPU/CODEC/PLATFORM node.
|
||||
|
||||
Example:
|
||||
|
||||
audio {
|
||||
compatible = "qcom,apq8096-sndcard";
|
||||
qcom,model = "DB820c";
|
||||
|
||||
mm1-dai-link {
|
||||
link-name = "MultiMedia1";
|
||||
cpu {
|
||||
sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
|
||||
};
|
||||
};
|
||||
|
||||
hdmi-dai-link {
|
||||
link-name = "HDMI Playback";
|
||||
cpu {
|
||||
sound-dai = <&q6afe HDMI_RX>;
|
||||
};
|
||||
|
||||
platform {
|
||||
sound-dai = <&q6adm>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&hdmi 0>;
|
||||
};
|
||||
};
|
||||
};
|
33
Documentation/devicetree/bindings/sound/qcom,q6adm.txt
Normal file
33
Documentation/devicetree/bindings/sound/qcom,q6adm.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
Qualcomm Audio Device Manager (Q6ADM) binding
|
||||
|
||||
Q6ADM is one of the APR audio service on Q6DSP.
|
||||
Please refer to qcom,apr.txt for details of the coommon apr service bindings
|
||||
used by the apr service device.
|
||||
|
||||
- but must contain the following property:
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,q6adm-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
|
||||
Or "qcom,q6adm" where the version number can be queried
|
||||
from DSP.
|
||||
example "qcom,q6adm-v2.0"
|
||||
|
||||
|
||||
= ADM routing
|
||||
"routing" subnode of the ADM node represents adm routing specific configuration
|
||||
|
||||
- #sound-dai-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 0
|
||||
|
||||
= EXAMPLE
|
||||
q6adm@8 {
|
||||
compatible = "qcom,q6adm";
|
||||
reg = <APR_SVC_ADM>;
|
||||
q6routing: routing {
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
172
Documentation/devicetree/bindings/sound/qcom,q6afe.txt
Normal file
172
Documentation/devicetree/bindings/sound/qcom,q6afe.txt
Normal file
|
@ -0,0 +1,172 @@
|
|||
Qualcomm Audio Front End (Q6AFE) binding
|
||||
|
||||
AFE is one of the APR audio service on Q6DSP
|
||||
Please refer to qcom,apr.txt for details of the common apr service bindings
|
||||
used by all apr services. Must contain the following properties.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,q6afe-v<MAJOR-NUMBER>.<MINOR-NUMBER>"
|
||||
Or "qcom,q6afe" where the version number can be queried
|
||||
from DSP.
|
||||
example "qcom,q6afe"
|
||||
|
||||
= AFE DAIs (Digial Audio Interface)
|
||||
"dais" subnode of the AFE node. It represents afe dais, each afe dai is a
|
||||
subnode of "dais" representing board specific dai setup.
|
||||
"dais" node should have following properties followed by dai children.
|
||||
|
||||
- #sound-dai-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 1
|
||||
|
||||
- #address-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 1
|
||||
|
||||
- #size-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 0
|
||||
|
||||
== AFE DAI is subnode of "dais" and represent a dai, it includes board specific
|
||||
configuration of each dai. Must contain the following properties.
|
||||
|
||||
- reg
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be dai id
|
||||
|
||||
- qcom,sd-lines
|
||||
Usage: required for mi2s interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Must be list of serial data lines used by this dai.
|
||||
should be one or more of the 1-4 sd lines.
|
||||
|
||||
- qcom,tdm-sync-mode:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Synchronization mode.
|
||||
0 - Short sync bit mode
|
||||
1 - Long sync mode
|
||||
2 - Short sync slot mode
|
||||
|
||||
- qcom,tdm-sync-src:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Synchronization source.
|
||||
0 - External source
|
||||
1 - Internal source
|
||||
|
||||
- qcom,tdm-data-out:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Data out signal to drive with other masters.
|
||||
0 - Disable
|
||||
1 - Enable
|
||||
|
||||
- qcom,tdm-invert-sync:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Invert the sync.
|
||||
0 - Normal
|
||||
1 - Invert
|
||||
|
||||
- qcom,tdm-data-delay:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Number of bit clock to delay data
|
||||
with respect to sync edge.
|
||||
0 - 0 bit clock cycle
|
||||
1 - 1 bit clock cycle
|
||||
2 - 2 bit clock cycle
|
||||
|
||||
- qcom,tdm-data-align:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Indicate how data is packed
|
||||
within the slot. For example, 32 slot width in case of
|
||||
sample bit width is 24.
|
||||
0 - MSB
|
||||
1 - LSB
|
||||
|
||||
= EXAMPLE
|
||||
|
||||
q6afe@4 {
|
||||
compatible = "qcom,q6afe";
|
||||
reg = <APR_SVC_AFE>;
|
||||
|
||||
dais {
|
||||
#sound-dai-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
hdmi@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
tdm@24 {
|
||||
reg = <24>;
|
||||
qcom,tdm-sync-mode = <1>:
|
||||
qcom,tdm-sync-src = <1>;
|
||||
qcom,tdm-data-out = <0>;
|
||||
qcom,tdm-invert-sync = <1>;
|
||||
qcom,tdm-data-delay = <1>;
|
||||
qcom,tdm-data-align = <0>;
|
||||
|
||||
};
|
||||
|
||||
tdm@25 {
|
||||
reg = <25>;
|
||||
qcom,tdm-sync-mode = <1>:
|
||||
qcom,tdm-sync-src = <1>;
|
||||
qcom,tdm-data-out = <0>;
|
||||
qcom,tdm-invert-sync = <1>;
|
||||
qcom,tdm-data-delay <1>:
|
||||
qcom,tdm-data-align = <0>;
|
||||
};
|
||||
|
||||
prim-mi2s-rx@16 {
|
||||
reg = <16>;
|
||||
qcom,sd-lines = <1 3>;
|
||||
};
|
||||
|
||||
prim-mi2s-tx@17 {
|
||||
reg = <17>;
|
||||
qcom,sd-lines = <2>;
|
||||
};
|
||||
|
||||
sec-mi2s-rx@18 {
|
||||
reg = <18>;
|
||||
qcom,sd-lines = <1 4>;
|
||||
};
|
||||
|
||||
sec-mi2s-tx@19 {
|
||||
reg = <19>;
|
||||
qcom,sd-lines = <2>;
|
||||
};
|
||||
|
||||
tert-mi2s-rx@20 {
|
||||
reg = <20>;
|
||||
qcom,sd-lines = <2 4>;
|
||||
};
|
||||
|
||||
tert-mi2s-tx@21 {
|
||||
reg = <21>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
|
||||
quat-mi2s-rx@22 {
|
||||
reg = <22>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
|
||||
quat-mi2s-tx@23 {
|
||||
reg = <23>;
|
||||
qcom,sd-lines = <2>;
|
||||
};
|
||||
};
|
||||
};
|
33
Documentation/devicetree/bindings/sound/qcom,q6asm.txt
Normal file
33
Documentation/devicetree/bindings/sound/qcom,q6asm.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
Qualcomm Audio Stream Manager (Q6ASM) binding
|
||||
|
||||
Q6ASM is one of the APR audio service on Q6DSP.
|
||||
Please refer to qcom,apr.txt for details of the common apr service bindings
|
||||
used by the apr service device.
|
||||
|
||||
- but must contain the following property:
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,q6asm-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
|
||||
Or "qcom,q6asm" where the version number can be queried
|
||||
from DSP.
|
||||
example "qcom,q6asm-v2.0"
|
||||
|
||||
= ASM DAIs (Digial Audio Interface)
|
||||
"dais" subnode of the ASM node represents dai specific configuration
|
||||
|
||||
- #sound-dai-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 1
|
||||
|
||||
= EXAMPLE
|
||||
|
||||
q6asm@7 {
|
||||
compatible = "qcom,q6asm";
|
||||
reg = <APR_SVC_ASM>;
|
||||
q6asmdai: dais {
|
||||
#sound-dai-cells = <1>;
|
||||
};
|
||||
};
|
21
Documentation/devicetree/bindings/sound/qcom,q6core.txt
Normal file
21
Documentation/devicetree/bindings/sound/qcom,q6core.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
Qualcomm ADSP Core service binding
|
||||
|
||||
Q6CORE is one of the APR audio service on Q6DSP.
|
||||
Please refer to qcom,apr.txt for details of the common apr service bindings
|
||||
used by the apr service device.
|
||||
|
||||
- but must contain the following property:
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,q6core-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
|
||||
Or "qcom,q6core" where the version number can be queried
|
||||
from DSP.
|
||||
example "qcom,q6core-v2.0"
|
||||
|
||||
= EXAMPLE
|
||||
q6core@3 {
|
||||
compatible = "qcom,q6core";
|
||||
reg = <APR_SVC_ADSP_CORE>;
|
||||
};
|
|
@ -26,7 +26,7 @@ Pins on the device (for linking into audio routes) for RT274:
|
|||
|
||||
Example:
|
||||
|
||||
codec: rt274@1c {
|
||||
rt274: codec@1c {
|
||||
compatible = "realtek,rt274";
|
||||
reg = <0x1c>;
|
||||
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
|
||||
|
|
|
@ -32,7 +32,7 @@ Pins on the device (for linking into audio routes) for I2C:
|
|||
|
||||
Example:
|
||||
|
||||
codec: rt5514@57 {
|
||||
rt5514: codec@57 {
|
||||
compatible = "realtek,rt5514";
|
||||
reg = <0x57>;
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@ Pins on the device (for linking into audio routes) for RT5616:
|
|||
|
||||
Example:
|
||||
|
||||
codec: rt5616@1b {
|
||||
rt5616: codec@1b {
|
||||
compatible = "realtek,rt5616";
|
||||
reg = <0x1b>;
|
||||
};
|
||||
|
|
|
@ -22,6 +22,41 @@ Optional properties:
|
|||
|
||||
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
|
||||
- realtek,dmic1-data-pin
|
||||
0: dmic1 is not used
|
||||
1: using IN1P pin as dmic1 data pin
|
||||
2: using GPIO3 pin as dmic1 data pin
|
||||
|
||||
- realtek,dmic2-data-pin
|
||||
0: dmic2 is not used
|
||||
1: using IN1N pin as dmic2 data pin
|
||||
2: using GPIO4 pin as dmic2 data pin
|
||||
|
||||
- realtek,jack-detect-source
|
||||
u32. Valid values:
|
||||
0: jack-detect is not used
|
||||
1: Use GPIO1 for jack-detect
|
||||
2: Use JD1_IN4P for jack-detect
|
||||
3: Use JD2_IN4N for jack-detect
|
||||
4: Use GPIO2 for jack-detect
|
||||
5: Use GPIO3 for jack-detect
|
||||
6: Use GPIO4 for jack-detect
|
||||
|
||||
- realtek,jack-detect-not-inverted
|
||||
bool. Normal jack-detect switches give an inverted signal, set this bool
|
||||
in the rare case you've a jack-detect switch which is not inverted.
|
||||
|
||||
- realtek,over-current-threshold-microamp
|
||||
u32, micbias over-current detection threshold in µA, valid values are
|
||||
600, 1500 and 2000µA.
|
||||
|
||||
- realtek,over-current-scale-factor
|
||||
u32, micbias over-current detection scale-factor, valid values are:
|
||||
0: Scale current by 0.5
|
||||
1: Scale current by 0.75
|
||||
2: Scale current by 1.0
|
||||
3: Scale current by 1.5
|
||||
|
||||
Pins on the device (for linking into audio routes) for RT5639/RT5640:
|
||||
|
||||
* DMIC1
|
||||
|
|
|
@ -69,4 +69,4 @@ codec: rt5650@1a {
|
|||
realtek,dmic-en = "true";
|
||||
realtek,en-jd-func = "true";
|
||||
realtek,jd-mode = <3>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -50,7 +50,7 @@ Pins on the device (for linking into audio routes) for RT5651:
|
|||
|
||||
Example:
|
||||
|
||||
codec: rt5651@1a {
|
||||
rt5651: codec@1a {
|
||||
compatible = "realtek,rt5651";
|
||||
reg = <0x1a>;
|
||||
realtek,dmic-en = "true";
|
||||
|
|
|
@ -47,7 +47,7 @@ Pins on the device (for linking into audio routes) for RT5663:
|
|||
|
||||
Example:
|
||||
|
||||
codec: rt5663@12 {
|
||||
rt5663: codec@12 {
|
||||
compatible = "realtek,rt5663";
|
||||
reg = <0x12>;
|
||||
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
|
||||
|
|
50
Documentation/devicetree/bindings/sound/rt5668.txt
Normal file
50
Documentation/devicetree/bindings/sound/rt5668.txt
Normal file
|
@ -0,0 +1,50 @@
|
|||
RT5668B audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "realtek,rt5668b"
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- interrupts : The CODEC's interrupt output.
|
||||
|
||||
- realtek,dmic1-data-pin
|
||||
0: dmic1 is not used
|
||||
1: using GPIO2 pin as dmic1 data pin
|
||||
2: using GPIO5 pin as dmic1 data pin
|
||||
|
||||
- realtek,dmic1-clk-pin
|
||||
0: using GPIO1 pin as dmic1 clock pin
|
||||
1: using GPIO3 pin as dmic1 clock pin
|
||||
|
||||
- realtek,jd-src
|
||||
0: No JD is used
|
||||
1: using JD1 as JD source
|
||||
|
||||
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
|
||||
Pins on the device (for linking into audio routes) for RT5668B:
|
||||
|
||||
* DMIC L1
|
||||
* DMIC R1
|
||||
* IN1P
|
||||
* HPOL
|
||||
* HPOR
|
||||
|
||||
Example:
|
||||
|
||||
rt5668 {
|
||||
compatible = "realtek,rt5668b";
|
||||
reg = <0x1a>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(U, 6) GPIO_ACTIVE_HIGH>;
|
||||
realtek,ldo1-en-gpios =
|
||||
<&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
|
||||
realtek,dmic1-data-pin = <1>;
|
||||
realtek,dmic1-clk-pin = <1>;
|
||||
realtek,jd-src = <1>;
|
||||
};
|
|
@ -39,7 +39,7 @@ VDDIO 1.8V 2.5V 3.3V
|
|||
|
||||
Example:
|
||||
|
||||
codec: sgtl5000@a {
|
||||
sgtl5000: codec@a {
|
||||
compatible = "fsl,sgtl5000";
|
||||
reg = <0x0a>;
|
||||
#sound-dai-cells = <0>;
|
||||
|
|
|
@ -86,6 +86,11 @@ Optional CPU/CODEC subnodes properties:
|
|||
in dai startup() and disabled with
|
||||
clk_disable_unprepare() in dai
|
||||
shutdown().
|
||||
If a clock is specified and a
|
||||
multiplication factor is given with
|
||||
mclk-fs, the clock will be set to the
|
||||
calculated mclk frequency when the
|
||||
stream starts.
|
||||
- system-clock-direction-out : specifies clock direction as 'out' on
|
||||
initialization. It is useful for some aCPUs with
|
||||
fixed clocks.
|
||||
|
|
|
@ -6,6 +6,8 @@ Required properties:
|
|||
- compatible: "ti,tas6424" - TAS6424
|
||||
- reg: I2C slave address
|
||||
- sound-dai-cells: must be equal to 0
|
||||
- standby-gpios: GPIO used to shut the TAS6424 down.
|
||||
- mute-gpios: GPIO used to mute all the outputs
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -8,9 +8,15 @@ Required Properties:
|
|||
- reg : <0x71> for analog mic
|
||||
<0x69> for digital mic
|
||||
|
||||
- clock-names: Must one of the following "mclk1", "xtal", "mclk2"
|
||||
|
||||
- clocks: phandle of the clock that provides the codec sysclk
|
||||
|
||||
Example:
|
||||
|
||||
wookie: codec@69 {
|
||||
compatible = "tempo,tscs42A2";
|
||||
reg = <0x69>;
|
||||
clock-names = "xtal";
|
||||
clocks = <&audio_xtal>;
|
||||
};
|
||||
|
|
23
Documentation/devicetree/bindings/sound/tscs454.txt
Normal file
23
Documentation/devicetree/bindings/sound/tscs454.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
TSCS454 Audio CODEC
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible : "tempo,tscs454"
|
||||
|
||||
- reg : <0x69>
|
||||
|
||||
- clock-names: Must one of the following "xtal", "mclk1", "mclk2"
|
||||
|
||||
- clocks: phandle of the clock that provides the codec sysclk
|
||||
|
||||
Note: If clock is not provided then bit clock is assumed
|
||||
|
||||
Example:
|
||||
|
||||
redwood: codec@69 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "tempo,tscs454";
|
||||
reg = <0x69>;
|
||||
clock-names = "mclk1";
|
||||
clocks = <&audio_mclk>;
|
||||
};
|
|
@ -12,7 +12,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8510@1a {
|
||||
wm8510: codec@1a {
|
||||
compatible = "wlf,wm8510";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8523@1a {
|
||||
wm8523: codec@1a {
|
||||
compatible = "wlf,wm8523";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8524 {
|
||||
wm8524: codec {
|
||||
compatible = "wlf,wm8524";
|
||||
wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8580@1a {
|
||||
wm8580: codec@1a {
|
||||
compatible = "wlf,wm8580";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8711@1a {
|
||||
wm8711: codec@1a {
|
||||
compatible = "wlf,wm8711";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8728@1a {
|
||||
wm8728: codec@1a {
|
||||
compatible = "wlf,wm8728";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8731@1a {
|
||||
wm8731: codec@1a {
|
||||
compatible = "wlf,wm8731";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8737@1a {
|
||||
wm8737: codec@1a {
|
||||
compatible = "wlf,wm8737";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ Optional properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8741@1a {
|
||||
wm8741: codec@1a {
|
||||
compatible = "wlf,wm8741";
|
||||
reg = <0x1a>;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8750@1a {
|
||||
wm8750: codec@1a {
|
||||
compatible = "wlf,wm8750";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ Pins on the device (for linking into audio routes):
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8753@1a {
|
||||
wm8753: codec@1a {
|
||||
compatible = "wlf,wm8753";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8770@1 {
|
||||
wm8770: codec@1 {
|
||||
compatible = "wlf,wm8770";
|
||||
reg = <1>;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ Required properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8776@1a {
|
||||
wm8776: codec@1a {
|
||||
compatible = "wlf,wm8776";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ Optional properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8804@1a {
|
||||
wm8804: codec@1a {
|
||||
compatible = "wlf,wm8804";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
|
|
|
@ -57,7 +57,7 @@ Pins on the device (for linking into audio routes):
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8903@1a {
|
||||
wm8903: codec@1a {
|
||||
compatible = "wlf,wm8903";
|
||||
reg = <0x1a>;
|
||||
interrupts = < 347 >;
|
||||
|
|
|
@ -23,7 +23,7 @@ Optional properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8960@1a {
|
||||
wm8960: codec@1a {
|
||||
compatible = "wlf,wm8960";
|
||||
reg = <0x1a>;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Optional properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8962@1a {
|
||||
wm8962: codec@1a {
|
||||
compatible = "wlf,wm8962";
|
||||
reg = <0x1a>;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ Optional properties:
|
|||
|
||||
Example:
|
||||
|
||||
codec: wm8994@1a {
|
||||
wm8994: codec@1a {
|
||||
compatible = "wlf,wm8994";
|
||||
reg = <0x1a>;
|
||||
|
||||
|
|
|
@ -2224,6 +2224,13 @@ quirk_alias
|
|||
Quirk alias list, pass strings like ``0123abcd:5678beef``, which
|
||||
applies the existing quirk for the device 5678:beef to a new
|
||||
device 0123:abcd.
|
||||
use_vmalloc
|
||||
Use vmalloc() for allocations of the PCM buffers (default: yes).
|
||||
For architectures with non-coherent memory like ARM or MIPS, the
|
||||
mmap access may give inconsistent results with vmalloc'ed
|
||||
buffers. If mmap is used on such architectures, turn off this
|
||||
option, so that the DMA-coherent buffers are allocated and used
|
||||
instead.
|
||||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
|
|
|
@ -263,6 +263,8 @@ hp-dock
|
|||
HP dock support
|
||||
mute-led-gpio
|
||||
Mute LED control via GPIO
|
||||
hp-mic-fix
|
||||
Fix for headset mic pin on HP boxes
|
||||
|
||||
STAC9200
|
||||
========
|
||||
|
|
|
@ -179,12 +179,12 @@ i.e.
|
|||
|
||||
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
|
||||
struct snd_soc_component *component = dai->component;
|
||||
u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf;
|
||||
|
||||
if (mute)
|
||||
snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
|
||||
snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
|
||||
else
|
||||
snd_soc_write(codec, WM8974_DAC, mute_reg);
|
||||
snd_soc_component_write(component, WM8974_DAC, mute_reg);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,30 +23,26 @@ The platform DMA driver optionally supports the following ALSA operations:-
|
|||
};
|
||||
|
||||
The platform driver exports its DMA functionality via struct
|
||||
snd_soc_platform_driver:-
|
||||
snd_soc_component_driver:-
|
||||
::
|
||||
|
||||
struct snd_soc_platform_driver {
|
||||
char *name;
|
||||
struct snd_soc_component_driver {
|
||||
const char *name;
|
||||
|
||||
int (*probe)(struct platform_device *pdev);
|
||||
int (*remove)(struct platform_device *pdev);
|
||||
int (*suspend)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai);
|
||||
int (*resume)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai);
|
||||
...
|
||||
int (*probe)(struct snd_soc_component *);
|
||||
void (*remove)(struct snd_soc_component *);
|
||||
int (*suspend)(struct snd_soc_component *);
|
||||
int (*resume)(struct snd_soc_component *);
|
||||
|
||||
/* pcm creation and destruction */
|
||||
int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *);
|
||||
int (*pcm_new)(struct snd_soc_pcm_runtime *);
|
||||
void (*pcm_free)(struct snd_pcm *);
|
||||
|
||||
/*
|
||||
* For platform caused delay reporting.
|
||||
* Optional.
|
||||
*/
|
||||
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
|
||||
struct snd_soc_dai *);
|
||||
|
||||
/* platform stream ops */
|
||||
struct snd_pcm_ops *pcm_ops;
|
||||
...
|
||||
const struct snd_pcm_ops *ops;
|
||||
const struct snd_compr_ops *compr_ops;
|
||||
...
|
||||
};
|
||||
|
||||
Please refer to the ALSA driver documentation for details of audio DMA.
|
||||
|
|
16
MAINTAINERS
16
MAINTAINERS
|
@ -7082,14 +7082,13 @@ L: linux-fbdev@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/video/fbdev/i810/
|
||||
|
||||
INTEL ASoC BDW/HSW DRIVERS
|
||||
INTEL ASoC DRIVERS
|
||||
M: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
M: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
M: Jie Yang <yang.jie@linux.intel.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
F: sound/soc/intel/common/sst-dsp*
|
||||
F: sound/soc/intel/common/sst-firmware.c
|
||||
F: sound/soc/intel/boards/broadwell.c
|
||||
F: sound/soc/intel/haswell/
|
||||
F: sound/soc/intel/
|
||||
|
||||
INTEL C600 SERIES SAS CONTROLLER DRIVER
|
||||
M: Intel SCU Linux support <intel-linux-scu@intel.com>
|
||||
|
@ -15542,6 +15541,13 @@ S: Supported
|
|||
F: arch/x86/xen/*swiotlb*
|
||||
F: drivers/xen/*swiotlb*
|
||||
|
||||
XEN SOUND FRONTEND DRIVER
|
||||
M: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
|
||||
L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
F: sound/xen/*
|
||||
|
||||
XFS FILESYSTEM
|
||||
M: Darrick J. Wong <darrick.wong@oracle.com>
|
||||
M: linux-xfs@vger.kernel.org
|
||||
|
|
|
@ -635,6 +635,7 @@ EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
|
|||
*************************************************************************/
|
||||
static struct resource ep93xx_i2s_resource[] = {
|
||||
DEFINE_RES_MEM(EP93XX_I2S_PHYS_BASE, 0x100),
|
||||
DEFINE_RES_IRQ(IRQ_EP93XX_SAI),
|
||||
};
|
||||
|
||||
static struct platform_device ep93xx_i2s_device = {
|
||||
|
|
|
@ -2444,7 +2444,7 @@ static int tda1997x_pcm_startup(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct tda1997x_state *state = snd_soc_dai_get_drvdata(dai);
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct snd_pcm_runtime *rtd = substream->runtime;
|
||||
int rate, err;
|
||||
|
||||
|
@ -2452,11 +2452,11 @@ static int tda1997x_pcm_startup(struct snd_pcm_substream *substream,
|
|||
err = snd_pcm_hw_constraint_minmax(rtd, SNDRV_PCM_HW_PARAM_RATE,
|
||||
rate, rate);
|
||||
if (err < 0) {
|
||||
dev_err(codec->dev, "failed to constrain samplerate to %dHz\n",
|
||||
dev_err(component->dev, "failed to constrain samplerate to %dHz\n",
|
||||
rate);
|
||||
return err;
|
||||
}
|
||||
dev_info(codec->dev, "set samplerate constraint to %dHz\n", rate);
|
||||
dev_info(component->dev, "set samplerate constraint to %dHz\n", rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2479,20 +2479,22 @@ static struct snd_soc_dai_driver tda1997x_audio_dai = {
|
|||
.ops = &tda1997x_dai_ops,
|
||||
};
|
||||
|
||||
static int tda1997x_codec_probe(struct snd_soc_codec *codec)
|
||||
static int tda1997x_codec_probe(struct snd_soc_component *component)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tda1997x_codec_remove(struct snd_soc_codec *codec)
|
||||
static void tda1997x_codec_remove(struct snd_soc_component *component)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver tda1997x_codec_driver = {
|
||||
.probe = tda1997x_codec_probe,
|
||||
.remove = tda1997x_codec_remove,
|
||||
.reg_word_size = sizeof(u16),
|
||||
static struct snd_soc_component_driver tda1997x_codec_driver = {
|
||||
.probe = tda1997x_codec_probe,
|
||||
.remove = tda1997x_codec_remove,
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static int tda1997x_probe(struct i2c_client *client,
|
||||
|
@ -2737,7 +2739,7 @@ static int tda1997x_probe(struct i2c_client *client,
|
|||
else
|
||||
formats = SNDRV_PCM_FMTBIT_S16_LE;
|
||||
tda1997x_audio_dai.capture.formats = formats;
|
||||
ret = snd_soc_register_codec(&state->client->dev,
|
||||
ret = devm_snd_soc_register_component(&state->client->dev,
|
||||
&tda1997x_codec_driver,
|
||||
&tda1997x_audio_dai, 1);
|
||||
if (ret) {
|
||||
|
@ -2782,7 +2784,6 @@ static int tda1997x_remove(struct i2c_client *client)
|
|||
struct tda1997x_platform_data *pdata = &state->pdata;
|
||||
|
||||
if (pdata->audout_format) {
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
mutex_destroy(&state->audio_lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,4 +108,13 @@ config QCOM_WCNSS_CTRL
|
|||
Client driver for the WCNSS_CTRL SMD channel, used to download nv
|
||||
firmware to a newly booted WCNSS chip.
|
||||
|
||||
config QCOM_APR
|
||||
tristate "Qualcomm APR Bus (Asynchronous Packet Router)"
|
||||
depends on ARCH_QCOM
|
||||
depends on RPMSG
|
||||
help
|
||||
Enable APR IPC protocol support between
|
||||
application processor and QDSP6. APR is
|
||||
used by audio driver to configure QDSP6
|
||||
ASM, ADM and AFE modules.
|
||||
endmenu
|
||||
|
|
|
@ -12,3 +12,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
|
|||
obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
|
||||
obj-$(CONFIG_QCOM_SMSM) += smsm.o
|
||||
obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
|
||||
obj-$(CONFIG_QCOM_APR) += apr.o
|
||||
|
|
378
drivers/soc/qcom/apr.c
Normal file
378
drivers/soc/qcom/apr.c
Normal file
|
@ -0,0 +1,378 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
|
||||
// Copyright (c) 2018, Linaro Limited
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/soc/qcom/apr.h>
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
struct apr {
|
||||
struct rpmsg_endpoint *ch;
|
||||
struct device *dev;
|
||||
spinlock_t svcs_lock;
|
||||
struct idr svcs_idr;
|
||||
int dest_domain_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* apr_send_pkt() - Send a apr message from apr device
|
||||
*
|
||||
* @adev: Pointer to previously registered apr device.
|
||||
* @pkt: Pointer to apr packet to send
|
||||
*
|
||||
* Return: Will be an negative on packet size on success.
|
||||
*/
|
||||
int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(adev->dev.parent);
|
||||
struct apr_hdr *hdr;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&adev->lock, flags);
|
||||
|
||||
hdr = &pkt->hdr;
|
||||
hdr->src_domain = APR_DOMAIN_APPS;
|
||||
hdr->src_svc = adev->svc_id;
|
||||
hdr->dest_domain = adev->domain_id;
|
||||
hdr->dest_svc = adev->svc_id;
|
||||
|
||||
ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size);
|
||||
spin_unlock_irqrestore(&adev->lock, flags);
|
||||
|
||||
return ret ? ret : hdr->pkt_size;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apr_send_pkt);
|
||||
|
||||
static void apr_dev_release(struct device *dev)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
|
||||
kfree(adev);
|
||||
}
|
||||
|
||||
static int apr_callback(struct rpmsg_device *rpdev, void *buf,
|
||||
int len, void *priv, u32 addr)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(&rpdev->dev);
|
||||
uint16_t hdr_size, msg_type, ver, svc_id;
|
||||
struct apr_device *svc = NULL;
|
||||
struct apr_driver *adrv = NULL;
|
||||
struct apr_resp_pkt resp;
|
||||
struct apr_hdr *hdr;
|
||||
unsigned long flags;
|
||||
|
||||
if (len <= APR_HDR_SIZE) {
|
||||
dev_err(apr->dev, "APR: Improper apr pkt received:%p %d\n",
|
||||
buf, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdr = buf;
|
||||
ver = APR_HDR_FIELD_VER(hdr->hdr_field);
|
||||
if (ver > APR_PKT_VER + 1)
|
||||
return -EINVAL;
|
||||
|
||||
hdr_size = APR_HDR_FIELD_SIZE_BYTES(hdr->hdr_field);
|
||||
if (hdr_size < APR_HDR_SIZE) {
|
||||
dev_err(apr->dev, "APR: Wrong hdr size:%d\n", hdr_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hdr->pkt_size < APR_HDR_SIZE || hdr->pkt_size != len) {
|
||||
dev_err(apr->dev, "APR: Wrong paket size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg_type = APR_HDR_FIELD_MT(hdr->hdr_field);
|
||||
if (msg_type >= APR_MSG_TYPE_MAX) {
|
||||
dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hdr->src_domain >= APR_DOMAIN_MAX ||
|
||||
hdr->dest_domain >= APR_DOMAIN_MAX ||
|
||||
hdr->src_svc >= APR_SVC_MAX ||
|
||||
hdr->dest_svc >= APR_SVC_MAX) {
|
||||
dev_err(apr->dev, "APR: Wrong APR header\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
svc_id = hdr->dest_svc;
|
||||
spin_lock_irqsave(&apr->svcs_lock, flags);
|
||||
svc = idr_find(&apr->svcs_idr, svc_id);
|
||||
if (svc && svc->dev.driver)
|
||||
adrv = to_apr_driver(svc->dev.driver);
|
||||
spin_unlock_irqrestore(&apr->svcs_lock, flags);
|
||||
|
||||
if (!adrv) {
|
||||
dev_err(apr->dev, "APR: service is not registered\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
resp.hdr = *hdr;
|
||||
resp.payload_size = hdr->pkt_size - hdr_size;
|
||||
|
||||
/*
|
||||
* NOTE: hdr_size is not same as APR_HDR_SIZE as remote can include
|
||||
* optional headers in to apr_hdr which should be ignored
|
||||
*/
|
||||
if (resp.payload_size > 0)
|
||||
resp.payload = buf + hdr_size;
|
||||
|
||||
adrv->callback(svc, &resp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apr_device_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
struct apr_driver *adrv = to_apr_driver(drv);
|
||||
const struct apr_device_id *id = adrv->id_table;
|
||||
|
||||
/* Attempt an OF style match first */
|
||||
if (of_driver_match_device(dev, drv))
|
||||
return 1;
|
||||
|
||||
if (!id)
|
||||
return 0;
|
||||
|
||||
while (id->domain_id != 0 || id->svc_id != 0) {
|
||||
if (id->domain_id == adev->domain_id &&
|
||||
id->svc_id == adev->svc_id)
|
||||
return 1;
|
||||
id++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apr_device_probe(struct device *dev)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
struct apr_driver *adrv = to_apr_driver(dev->driver);
|
||||
|
||||
return adrv->probe(adev);
|
||||
}
|
||||
|
||||
static int apr_device_remove(struct device *dev)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
struct apr_driver *adrv;
|
||||
struct apr *apr = dev_get_drvdata(adev->dev.parent);
|
||||
|
||||
if (dev->driver) {
|
||||
adrv = to_apr_driver(dev->driver);
|
||||
if (adrv->remove)
|
||||
adrv->remove(adev);
|
||||
spin_lock(&apr->svcs_lock);
|
||||
idr_remove(&apr->svcs_idr, adev->svc_id);
|
||||
spin_unlock(&apr->svcs_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apr_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
int ret;
|
||||
|
||||
ret = of_device_uevent_modalias(dev, env);
|
||||
if (ret != -ENODEV)
|
||||
return ret;
|
||||
|
||||
return add_uevent_var(env, "MODALIAS=apr:%s", adev->name);
|
||||
}
|
||||
|
||||
struct bus_type aprbus = {
|
||||
.name = "aprbus",
|
||||
.match = apr_device_match,
|
||||
.probe = apr_device_probe,
|
||||
.uevent = apr_uevent,
|
||||
.remove = apr_device_remove,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(aprbus);
|
||||
|
||||
static int apr_add_device(struct device *dev, struct device_node *np,
|
||||
const struct apr_device_id *id)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(dev);
|
||||
struct apr_device *adev = NULL;
|
||||
int ret;
|
||||
|
||||
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
|
||||
if (!adev)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&adev->lock);
|
||||
|
||||
adev->svc_id = id->svc_id;
|
||||
adev->domain_id = id->domain_id;
|
||||
adev->version = id->svc_version;
|
||||
if (np)
|
||||
strncpy(adev->name, np->name, APR_NAME_SIZE);
|
||||
else
|
||||
strncpy(adev->name, id->name, APR_NAME_SIZE);
|
||||
|
||||
dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
|
||||
id->domain_id, id->svc_id);
|
||||
|
||||
adev->dev.bus = &aprbus;
|
||||
adev->dev.parent = dev;
|
||||
adev->dev.of_node = np;
|
||||
adev->dev.release = apr_dev_release;
|
||||
adev->dev.driver = NULL;
|
||||
|
||||
spin_lock(&apr->svcs_lock);
|
||||
idr_alloc(&apr->svcs_idr, adev, id->svc_id,
|
||||
id->svc_id + 1, GFP_ATOMIC);
|
||||
spin_unlock(&apr->svcs_lock);
|
||||
|
||||
dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev));
|
||||
|
||||
ret = device_register(&adev->dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "device_register failed: %d\n", ret);
|
||||
put_device(&adev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void of_register_apr_devices(struct device *dev)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(dev);
|
||||
struct device_node *node;
|
||||
|
||||
for_each_child_of_node(dev->of_node, node) {
|
||||
struct apr_device_id id = { {0} };
|
||||
|
||||
if (of_property_read_u32(node, "reg", &id.svc_id))
|
||||
continue;
|
||||
|
||||
id.domain_id = apr->dest_domain_id;
|
||||
|
||||
if (apr_add_device(dev, node, &id))
|
||||
dev_err(dev, "Failed to add apr %d svc\n", id.svc_id);
|
||||
}
|
||||
}
|
||||
|
||||
static int apr_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct device *dev = &rpdev->dev;
|
||||
struct apr *apr;
|
||||
int ret;
|
||||
|
||||
apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL);
|
||||
if (!apr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = of_property_read_u32(dev->of_node, "reg", &apr->dest_domain_id);
|
||||
if (ret) {
|
||||
dev_err(dev, "APR Domain ID not specified in DT\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, apr);
|
||||
apr->ch = rpdev->ept;
|
||||
apr->dev = dev;
|
||||
spin_lock_init(&apr->svcs_lock);
|
||||
idr_init(&apr->svcs_idr);
|
||||
of_register_apr_devices(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apr_remove_device(struct device *dev, void *null)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
|
||||
device_unregister(&adev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apr_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
|
||||
}
|
||||
|
||||
/*
|
||||
* __apr_driver_register() - Client driver registration with aprbus
|
||||
*
|
||||
* @drv:Client driver to be associated with client-device.
|
||||
* @owner: owning module/driver
|
||||
*
|
||||
* This API will register the client driver with the aprbus
|
||||
* It is called from the driver's module-init function.
|
||||
*/
|
||||
int __apr_driver_register(struct apr_driver *drv, struct module *owner)
|
||||
{
|
||||
drv->driver.bus = &aprbus;
|
||||
drv->driver.owner = owner;
|
||||
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__apr_driver_register);
|
||||
|
||||
/*
|
||||
* apr_driver_unregister() - Undo effect of apr_driver_register
|
||||
*
|
||||
* @drv: Client driver to be unregistered
|
||||
*/
|
||||
void apr_driver_unregister(struct apr_driver *drv)
|
||||
{
|
||||
driver_unregister(&drv->driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apr_driver_unregister);
|
||||
|
||||
static const struct of_device_id apr_of_match[] = {
|
||||
{ .compatible = "qcom,apr"},
|
||||
{ .compatible = "qcom,apr-v2"},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, apr_of_match);
|
||||
|
||||
static struct rpmsg_driver apr_driver = {
|
||||
.probe = apr_probe,
|
||||
.remove = apr_remove,
|
||||
.callback = apr_callback,
|
||||
.drv = {
|
||||
.name = "qcom,apr",
|
||||
.of_match_table = apr_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init apr_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bus_register(&aprbus);
|
||||
if (!ret)
|
||||
ret = register_rpmsg_driver(&apr_driver);
|
||||
else
|
||||
bus_unregister(&aprbus);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit apr_exit(void)
|
||||
{
|
||||
bus_unregister(&aprbus);
|
||||
unregister_rpmsg_driver(&apr_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(apr_init);
|
||||
module_exit(apr_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Qualcomm APR Bus");
|
28
include/dt-bindings/soc/qcom,apr.h
Normal file
28
include/dt-bindings/soc/qcom,apr.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_BINDINGS_QCOM_APR_H
|
||||
#define __DT_BINDINGS_QCOM_APR_H
|
||||
|
||||
/* Domain IDs */
|
||||
#define APR_DOMAIN_SIM 0x1
|
||||
#define APR_DOMAIN_PC 0x2
|
||||
#define APR_DOMAIN_MODEM 0x3
|
||||
#define APR_DOMAIN_ADSP 0x4
|
||||
#define APR_DOMAIN_APPS 0x5
|
||||
#define APR_DOMAIN_MAX 0x6
|
||||
|
||||
/* ADSP service IDs */
|
||||
#define APR_SVC_ADSP_CORE 0x3
|
||||
#define APR_SVC_AFE 0x4
|
||||
#define APR_SVC_VSM 0x5
|
||||
#define APR_SVC_VPM 0x6
|
||||
#define APR_SVC_ASM 0x7
|
||||
#define APR_SVC_ADM 0x8
|
||||
#define APR_SVC_ADSP_MVM 0x09
|
||||
#define APR_SVC_ADSP_CVS 0x0A
|
||||
#define APR_SVC_ADSP_CVP 0x0B
|
||||
#define APR_SVC_USM 0x0C
|
||||
#define APR_SVC_LSM 0x0D
|
||||
#define APR_SVC_VIDC 0x16
|
||||
#define APR_SVC_MAX 0x17
|
||||
|
||||
#endif /* __DT_BINDINGS_QCOM_APR_H */
|
|
@ -25,6 +25,13 @@
|
|||
#define MX51_AUDMUX_PORT6 5
|
||||
#define MX51_AUDMUX_PORT7 6
|
||||
|
||||
/*
|
||||
* TFCSEL/RFCSEL (i.MX27) or TFSEL/TCSEL/RFSEL/RCSEL (i.MX31/51/53/6Q)
|
||||
* can be sourced from Rx/Tx.
|
||||
*/
|
||||
#define IMX_AUDMUX_RXFS 0x8
|
||||
#define IMX_AUDMUX_RXCLK 0x8
|
||||
|
||||
/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
|
||||
#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
|
||||
#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8)
|
||||
|
|
111
include/dt-bindings/sound/qcom,q6afe.h
Normal file
111
include/dt-bindings/sound/qcom,q6afe.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_BINDINGS_Q6_AFE_H__
|
||||
#define __DT_BINDINGS_Q6_AFE_H__
|
||||
|
||||
/* Audio Front End (AFE) virtual ports IDs */
|
||||
#define HDMI_RX 1
|
||||
#define SLIMBUS_0_RX 2
|
||||
#define SLIMBUS_0_TX 3
|
||||
#define SLIMBUS_1_RX 4
|
||||
#define SLIMBUS_1_TX 5
|
||||
#define SLIMBUS_2_RX 6
|
||||
#define SLIMBUS_2_TX 7
|
||||
#define SLIMBUS_3_RX 8
|
||||
#define SLIMBUS_3_TX 9
|
||||
#define SLIMBUS_4_RX 10
|
||||
#define SLIMBUS_4_TX 11
|
||||
#define SLIMBUS_5_RX 12
|
||||
#define SLIMBUS_5_TX 13
|
||||
#define SLIMBUS_6_RX 14
|
||||
#define SLIMBUS_6_TX 15
|
||||
#define PRIMARY_MI2S_RX 16
|
||||
#define PRIMARY_MI2S_TX 17
|
||||
#define SECONDARY_MI2S_RX 18
|
||||
#define SECONDARY_MI2S_TX 19
|
||||
#define TERTIARY_MI2S_RX 20
|
||||
#define TERTIARY_MI2S_TX 21
|
||||
#define QUATERNARY_MI2S_RX 22
|
||||
#define QUATERNARY_MI2S_TX 23
|
||||
#define PRIMARY_TDM_RX_0 24
|
||||
#define PRIMARY_TDM_TX_0 25
|
||||
#define PRIMARY_TDM_RX_1 26
|
||||
#define PRIMARY_TDM_TX_1 27
|
||||
#define PRIMARY_TDM_RX_2 28
|
||||
#define PRIMARY_TDM_TX_2 29
|
||||
#define PRIMARY_TDM_RX_3 30
|
||||
#define PRIMARY_TDM_TX_3 31
|
||||
#define PRIMARY_TDM_RX_4 32
|
||||
#define PRIMARY_TDM_TX_4 33
|
||||
#define PRIMARY_TDM_RX_5 34
|
||||
#define PRIMARY_TDM_TX_5 35
|
||||
#define PRIMARY_TDM_RX_6 36
|
||||
#define PRIMARY_TDM_TX_6 37
|
||||
#define PRIMARY_TDM_RX_7 38
|
||||
#define PRIMARY_TDM_TX_7 39
|
||||
#define SECONDARY_TDM_RX_0 40
|
||||
#define SECONDARY_TDM_TX_0 41
|
||||
#define SECONDARY_TDM_RX_1 42
|
||||
#define SECONDARY_TDM_TX_1 43
|
||||
#define SECONDARY_TDM_RX_2 44
|
||||
#define SECONDARY_TDM_TX_2 45
|
||||
#define SECONDARY_TDM_RX_3 46
|
||||
#define SECONDARY_TDM_TX_3 47
|
||||
#define SECONDARY_TDM_RX_4 48
|
||||
#define SECONDARY_TDM_TX_4 49
|
||||
#define SECONDARY_TDM_RX_5 50
|
||||
#define SECONDARY_TDM_TX_5 51
|
||||
#define SECONDARY_TDM_RX_6 52
|
||||
#define SECONDARY_TDM_TX_6 53
|
||||
#define SECONDARY_TDM_RX_7 54
|
||||
#define SECONDARY_TDM_TX_7 55
|
||||
#define TERTIARY_TDM_RX_0 56
|
||||
#define TERTIARY_TDM_TX_0 57
|
||||
#define TERTIARY_TDM_RX_1 58
|
||||
#define TERTIARY_TDM_TX_1 59
|
||||
#define TERTIARY_TDM_RX_2 60
|
||||
#define TERTIARY_TDM_TX_2 61
|
||||
#define TERTIARY_TDM_RX_3 62
|
||||
#define TERTIARY_TDM_TX_3 63
|
||||
#define TERTIARY_TDM_RX_4 64
|
||||
#define TERTIARY_TDM_TX_4 65
|
||||
#define TERTIARY_TDM_RX_5 66
|
||||
#define TERTIARY_TDM_TX_5 67
|
||||
#define TERTIARY_TDM_RX_6 68
|
||||
#define TERTIARY_TDM_TX_6 69
|
||||
#define TERTIARY_TDM_RX_7 70
|
||||
#define TERTIARY_TDM_TX_7 71
|
||||
#define QUATERNARY_TDM_RX_0 72
|
||||
#define QUATERNARY_TDM_TX_0 73
|
||||
#define QUATERNARY_TDM_RX_1 74
|
||||
#define QUATERNARY_TDM_TX_1 75
|
||||
#define QUATERNARY_TDM_RX_2 76
|
||||
#define QUATERNARY_TDM_TX_2 77
|
||||
#define QUATERNARY_TDM_RX_3 78
|
||||
#define QUATERNARY_TDM_TX_3 79
|
||||
#define QUATERNARY_TDM_RX_4 80
|
||||
#define QUATERNARY_TDM_TX_4 81
|
||||
#define QUATERNARY_TDM_RX_5 82
|
||||
#define QUATERNARY_TDM_TX_5 83
|
||||
#define QUATERNARY_TDM_RX_6 84
|
||||
#define QUATERNARY_TDM_TX_6 85
|
||||
#define QUATERNARY_TDM_RX_7 86
|
||||
#define QUATERNARY_TDM_TX_7 87
|
||||
#define QUINARY_TDM_RX_0 88
|
||||
#define QUINARY_TDM_TX_0 89
|
||||
#define QUINARY_TDM_RX_1 90
|
||||
#define QUINARY_TDM_TX_1 91
|
||||
#define QUINARY_TDM_RX_2 92
|
||||
#define QUINARY_TDM_TX_2 93
|
||||
#define QUINARY_TDM_RX_3 94
|
||||
#define QUINARY_TDM_TX_3 95
|
||||
#define QUINARY_TDM_RX_4 96
|
||||
#define QUINARY_TDM_TX_4 97
|
||||
#define QUINARY_TDM_RX_5 98
|
||||
#define QUINARY_TDM_TX_5 99
|
||||
#define QUINARY_TDM_RX_6 100
|
||||
#define QUINARY_TDM_TX_6 101
|
||||
#define QUINARY_TDM_RX_7 102
|
||||
#define QUINARY_TDM_TX_7 103
|
||||
|
||||
#endif /* __DT_BINDINGS_Q6_AFE_H__ */
|
||||
|
22
include/dt-bindings/sound/qcom,q6asm.h
Normal file
22
include/dt-bindings/sound/qcom,q6asm.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_BINDINGS_Q6_ASM_H__
|
||||
#define __DT_BINDINGS_Q6_ASM_H__
|
||||
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA1 0
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA2 1
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA3 2
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA4 3
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA5 4
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA6 5
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA7 6
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA8 7
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA9 8
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA10 9
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA11 10
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA12 11
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA13 12
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA14 13
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA15 14
|
||||
#define MSM_FRONTEND_DAI_MULTIMEDIA16 15
|
||||
|
||||
#endif /* __DT_BINDINGS_Q6_ASM_H__ */
|
25
include/dt-bindings/sound/rt5640.h
Normal file
25
include/dt-bindings/sound/rt5640.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_RT5640_H
|
||||
#define __DT_RT5640_H
|
||||
|
||||
#define RT5640_DMIC1_DATA_PIN_NONE 0
|
||||
#define RT5640_DMIC1_DATA_PIN_IN1P 1
|
||||
#define RT5640_DMIC1_DATA_PIN_GPIO3 2
|
||||
|
||||
#define RT5640_DMIC2_DATA_PIN_NONE 0
|
||||
#define RT5640_DMIC2_DATA_PIN_IN1N 1
|
||||
#define RT5640_DMIC2_DATA_PIN_GPIO4 2
|
||||
|
||||
#define RT5640_JD_SRC_GPIO1 1
|
||||
#define RT5640_JD_SRC_JD1_IN4P 2
|
||||
#define RT5640_JD_SRC_JD2_IN4N 3
|
||||
#define RT5640_JD_SRC_GPIO2 4
|
||||
#define RT5640_JD_SRC_GPIO3 5
|
||||
#define RT5640_JD_SRC_GPIO4 6
|
||||
|
||||
#define RT5640_OVCD_SF_0P5 0
|
||||
#define RT5640_OVCD_SF_0P75 1
|
||||
#define RT5640_OVCD_SF_1P0 2
|
||||
#define RT5640_OVCD_SF_1P5 3
|
||||
|
||||
#endif /* __DT_RT5640_H */
|
|
@ -617,11 +617,8 @@ struct wm8350_audio_platform_data {
|
|||
u32 codec_current_charge:2; /* codec current @ vmid charge */
|
||||
};
|
||||
|
||||
struct snd_soc_codec;
|
||||
|
||||
struct wm8350_codec {
|
||||
struct platform_device *pdev;
|
||||
struct snd_soc_codec *codec;
|
||||
struct wm8350_audio_platform_data *platform_data;
|
||||
};
|
||||
|
||||
|
|
|
@ -471,6 +471,17 @@ struct slim_device_id {
|
|||
kernel_ulong_t driver_data;
|
||||
};
|
||||
|
||||
#define APR_NAME_SIZE 32
|
||||
#define APR_MODULE_PREFIX "apr:"
|
||||
|
||||
struct apr_device_id {
|
||||
char name[APR_NAME_SIZE];
|
||||
__u32 domain_id;
|
||||
__u32 svc_id;
|
||||
__u32 svc_version;
|
||||
kernel_ulong_t driver_data; /* Data private to the driver */
|
||||
};
|
||||
|
||||
#define SPMI_NAME_SIZE 32
|
||||
#define SPMI_MODULE_PREFIX "spmi:"
|
||||
|
||||
|
|
128
include/linux/soc/qcom/apr.h
Normal file
128
include/linux/soc/qcom/apr.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __QCOM_APR_H_
|
||||
#define __QCOM_APR_H_
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <dt-bindings/soc/qcom,apr.h>
|
||||
|
||||
extern struct bus_type aprbus;
|
||||
|
||||
#define APR_HDR_LEN(hdr_len) ((hdr_len)/4)
|
||||
|
||||
/*
|
||||
* HEADER field
|
||||
* version:0:3
|
||||
* header_size : 4:7
|
||||
* message_type : 8:9
|
||||
* reserved: 10:15
|
||||
*/
|
||||
#define APR_HDR_FIELD(msg_type, hdr_len, ver)\
|
||||
(((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF))
|
||||
|
||||
#define APR_HDR_SIZE sizeof(struct apr_hdr)
|
||||
#define APR_SEQ_CMD_HDR_FIELD APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
|
||||
APR_HDR_LEN(APR_HDR_SIZE), \
|
||||
APR_PKT_VER)
|
||||
/* Version */
|
||||
#define APR_PKT_VER 0x0
|
||||
|
||||
/* Command and Response Types */
|
||||
#define APR_MSG_TYPE_EVENT 0x0
|
||||
#define APR_MSG_TYPE_CMD_RSP 0x1
|
||||
#define APR_MSG_TYPE_SEQ_CMD 0x2
|
||||
#define APR_MSG_TYPE_NSEQ_CMD 0x3
|
||||
#define APR_MSG_TYPE_MAX 0x04
|
||||
|
||||
/* APR Basic Response Message */
|
||||
#define APR_BASIC_RSP_RESULT 0x000110E8
|
||||
#define APR_RSP_ACCEPTED 0x000100BE
|
||||
|
||||
struct aprv2_ibasic_rsp_result_t {
|
||||
uint32_t opcode;
|
||||
uint32_t status;
|
||||
};
|
||||
|
||||
/* hdr field Ver [0:3], Size [4:7], Message type [8:10] */
|
||||
#define APR_HDR_FIELD_VER(h) (h & 0x000F)
|
||||
#define APR_HDR_FIELD_SIZE(h) ((h & 0x00F0) >> 4)
|
||||
#define APR_HDR_FIELD_SIZE_BYTES(h) (((h & 0x00F0) >> 4) * 4)
|
||||
#define APR_HDR_FIELD_MT(h) ((h & 0x0300) >> 8)
|
||||
|
||||
struct apr_hdr {
|
||||
uint16_t hdr_field;
|
||||
uint16_t pkt_size;
|
||||
uint8_t src_svc;
|
||||
uint8_t src_domain;
|
||||
uint16_t src_port;
|
||||
uint8_t dest_svc;
|
||||
uint8_t dest_domain;
|
||||
uint16_t dest_port;
|
||||
uint32_t token;
|
||||
uint32_t opcode;
|
||||
} __packed;
|
||||
|
||||
struct apr_pkt {
|
||||
struct apr_hdr hdr;
|
||||
uint8_t payload[];
|
||||
};
|
||||
|
||||
struct apr_resp_pkt {
|
||||
struct apr_hdr hdr;
|
||||
void *payload;
|
||||
int payload_size;
|
||||
};
|
||||
|
||||
/* Bits 0 to 15 -- Minor version, Bits 16 to 31 -- Major version */
|
||||
#define APR_SVC_MAJOR_VERSION(v) ((v >> 16) & 0xFF)
|
||||
#define APR_SVC_MINOR_VERSION(v) (v & 0xFF)
|
||||
|
||||
struct apr_device {
|
||||
struct device dev;
|
||||
uint16_t svc_id;
|
||||
uint16_t domain_id;
|
||||
uint32_t version;
|
||||
char name[APR_NAME_SIZE];
|
||||
spinlock_t lock;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
#define to_apr_device(d) container_of(d, struct apr_device, dev)
|
||||
|
||||
struct apr_driver {
|
||||
int (*probe)(struct apr_device *sl);
|
||||
int (*remove)(struct apr_device *sl);
|
||||
int (*callback)(struct apr_device *a,
|
||||
struct apr_resp_pkt *d);
|
||||
struct device_driver driver;
|
||||
const struct apr_device_id *id_table;
|
||||
};
|
||||
|
||||
#define to_apr_driver(d) container_of(d, struct apr_driver, driver)
|
||||
|
||||
/*
|
||||
* use a macro to avoid include chaining to get THIS_MODULE
|
||||
*/
|
||||
#define apr_driver_register(drv) __apr_driver_register(drv, THIS_MODULE)
|
||||
|
||||
int __apr_driver_register(struct apr_driver *drv, struct module *owner);
|
||||
void apr_driver_unregister(struct apr_driver *drv);
|
||||
|
||||
/**
|
||||
* module_apr_driver() - Helper macro for registering a aprbus driver
|
||||
* @__aprbus_driver: aprbus_driver struct
|
||||
*
|
||||
* Helper macro for aprbus drivers which do not do anything special in
|
||||
* module init/exit. This eliminates a lot of boilerplate. Each module
|
||||
* may only use this macro once, and calling it replaces module_init()
|
||||
* and module_exit()
|
||||
*/
|
||||
#define module_apr_driver(__apr_driver) \
|
||||
module_driver(__apr_driver, apr_driver_register, \
|
||||
apr_driver_unregister)
|
||||
|
||||
int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt);
|
||||
|
||||
#endif /* __QCOM_APR_H_ */
|
|
@ -189,6 +189,13 @@ struct uac2_iso_endpoint_descriptor {
|
|||
#define UAC2_CONTROL_DATA_OVERRUN (3 << 2)
|
||||
#define UAC2_CONTROL_DATA_UNDERRUN (3 << 4)
|
||||
|
||||
/* 5.2.5.4.2 Connector Control Parameter Block */
|
||||
struct uac2_connectors_ctl_blk {
|
||||
__u8 bNrChannels;
|
||||
__le32 bmChannelConfig;
|
||||
__u8 iChannelNames;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 6.1 Interrupt Data Message */
|
||||
|
||||
#define UAC2_INTERRUPT_DATA_MSG_VENDOR (1 << 0)
|
||||
|
|
|
@ -221,6 +221,12 @@ struct uac3_iso_endpoint_descriptor {
|
|||
__le16 wLockDelay;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* 5.2.1.6.1 INSERTION CONTROL PARAMETER BLOCK */
|
||||
struct uac3_insertion_ctl_blk {
|
||||
__u8 bSize;
|
||||
__u8 bmConInserted;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* 6.1 INTERRUPT DATA MESSAGE */
|
||||
struct uac3_interrupt_data_msg {
|
||||
__u8 bInfo;
|
||||
|
@ -392,4 +398,38 @@ struct uac3_interrupt_data_msg {
|
|||
#define UAC3_AC_ACTIVE_INTERFACE_CONTROL 0x01
|
||||
#define UAC3_AC_POWER_DOMAIN_CONTROL 0x02
|
||||
|
||||
/* A.23.5 TERMINAL CONTROL SELECTORS */
|
||||
#define UAC3_TE_UNDEFINED 0x00
|
||||
#define UAC3_TE_INSERTION 0x01
|
||||
#define UAC3_TE_OVERLOAD 0x02
|
||||
#define UAC3_TE_UNDERFLOW 0x03
|
||||
#define UAC3_TE_OVERFLOW 0x04
|
||||
#define UAC3_TE_LATENCY 0x05
|
||||
|
||||
/* BADD predefined Unit/Terminal values */
|
||||
#define UAC3_BADD_IT_ID1 1 /* Input Terminal ID1: bTerminalID = 1 */
|
||||
#define UAC3_BADD_FU_ID2 2 /* Feature Unit ID2: bUnitID = 2 */
|
||||
#define UAC3_BADD_OT_ID3 3 /* Output Terminal ID3: bTerminalID = 3 */
|
||||
#define UAC3_BADD_IT_ID4 4 /* Input Terminal ID4: bTerminalID = 4 */
|
||||
#define UAC3_BADD_FU_ID5 5 /* Feature Unit ID5: bUnitID = 5 */
|
||||
#define UAC3_BADD_OT_ID6 6 /* Output Terminal ID6: bTerminalID = 6 */
|
||||
#define UAC3_BADD_FU_ID7 7 /* Feature Unit ID7: bUnitID = 7 */
|
||||
#define UAC3_BADD_MU_ID8 8 /* Mixer Unit ID8: bUnitID = 8 */
|
||||
#define UAC3_BADD_CS_ID9 9 /* Clock Source Entity ID9: bClockID = 9 */
|
||||
#define UAC3_BADD_PD_ID10 10 /* Power Domain ID10: bPowerDomainID = 10 */
|
||||
#define UAC3_BADD_PD_ID11 11 /* Power Domain ID11: bPowerDomainID = 11 */
|
||||
|
||||
/* BADD wMaxPacketSize of AS endpoints */
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16 0x0060
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16 0x0062
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24 0x0090
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24 0x0093
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16 0x00C0
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16 0x00C4
|
||||
#define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24 0x0120
|
||||
#define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24 0x0126
|
||||
|
||||
/* BADD sample rate is always fixed to 48kHz */
|
||||
#define UAC3_BADD_SAMPLING_RATE 48000
|
||||
|
||||
#endif /* __LINUX_USB_AUDIO_V3_H */
|
||||
|
|
|
@ -51,7 +51,6 @@ struct completion;
|
|||
*/
|
||||
enum snd_device_type {
|
||||
SNDRV_DEV_LOWLEVEL,
|
||||
SNDRV_DEV_CONTROL,
|
||||
SNDRV_DEV_INFO,
|
||||
SNDRV_DEV_BUS,
|
||||
SNDRV_DEV_CODEC,
|
||||
|
@ -62,6 +61,7 @@ enum snd_device_type {
|
|||
SNDRV_DEV_SEQUENCER,
|
||||
SNDRV_DEV_HWDEP,
|
||||
SNDRV_DEV_JACK,
|
||||
SNDRV_DEV_CONTROL, /* NOTE: this must be the last one */
|
||||
};
|
||||
|
||||
enum snd_device_state {
|
||||
|
|
|
@ -1610,7 +1610,7 @@ struct snd_emu10k1_fx8010_pcm {
|
|||
struct snd_pcm_indirect pcm_rec;
|
||||
unsigned int tram_pos;
|
||||
unsigned int tram_shift;
|
||||
struct snd_emu10k1_fx8010_irq *irq;
|
||||
struct snd_emu10k1_fx8010_irq irq;
|
||||
};
|
||||
|
||||
struct snd_emu10k1_fx8010 {
|
||||
|
@ -1902,7 +1902,7 @@ int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
|
|||
snd_fx8010_irq_handler_t *handler,
|
||||
unsigned char gpr_running,
|
||||
void *private_data,
|
||||
struct snd_emu10k1_fx8010_irq **r_irq);
|
||||
struct snd_emu10k1_fx8010_irq *irq);
|
||||
int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
|
||||
struct snd_emu10k1_fx8010_irq *irq);
|
||||
|
||||
|
|
|
@ -571,4 +571,9 @@ static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
|
|||
return (unsigned long)(ptr - array->list) / array->elem_size;
|
||||
}
|
||||
|
||||
/* a helper macro to iterate for each snd_array element */
|
||||
#define snd_array_for_each(array, idx, ptr) \
|
||||
for ((idx) = 0, (ptr) = (array)->list; (idx) < (array)->used; \
|
||||
(ptr) = snd_array_elem(array, ++(idx)))
|
||||
|
||||
#endif /* __SOUND_HDAUDIO_H */
|
||||
|
|
|
@ -34,11 +34,9 @@ struct snd_dma_device {
|
|||
struct device *dev; /* generic device */
|
||||
};
|
||||
|
||||
#ifndef snd_dma_pci_data
|
||||
#define snd_dma_pci_data(pci) (&(pci)->dev)
|
||||
#define snd_dma_isa_data() NULL
|
||||
#define snd_dma_continuous_data(x) ((struct device *)(__force unsigned long)(x))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* omap-pcm.h - OMAP PCM driver
|
||||
*
|
||||
* Copyright (C) 2014 Texas Instruments, Inc.
|
||||
*
|
||||
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __OMAP_PCM_H__
|
||||
#define __OMAP_PCM_H__
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_OMAP_SOC)
|
||||
int omap_pcm_platform_register(struct device *dev);
|
||||
#else
|
||||
static inline int omap_pcm_platform_register(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SND_OMAP_SOC */
|
||||
|
||||
#endif /* __OMAP_PCM_H__ */
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* linux/sound/rt5640.h -- Platform data for RT5640
|
||||
*
|
||||
* Copyright 2011 Realtek Microelectronics
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_RT5640_H
|
||||
#define __LINUX_SND_RT5640_H
|
||||
|
||||
struct rt5640_platform_data {
|
||||
/* IN1 & IN2 & IN3 can optionally be differential */
|
||||
bool in1_diff;
|
||||
bool in2_diff;
|
||||
bool in3_diff;
|
||||
|
||||
bool dmic_en;
|
||||
bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
|
||||
bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */
|
||||
|
||||
int ldo1_en; /* GPIO for LDO1_EN */
|
||||
};
|
||||
|
||||
#endif
|
40
include/sound/rt5668.h
Normal file
40
include/sound/rt5668.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* linux/sound/rt5668.h -- Platform data for RT5668
|
||||
*
|
||||
* Copyright 2018 Realtek Microelectronics
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_RT5668_H
|
||||
#define __LINUX_SND_RT5668_H
|
||||
|
||||
enum rt5668_dmic1_data_pin {
|
||||
RT5668_DMIC1_NULL,
|
||||
RT5668_DMIC1_DATA_GPIO2,
|
||||
RT5668_DMIC1_DATA_GPIO5,
|
||||
};
|
||||
|
||||
enum rt5668_dmic1_clk_pin {
|
||||
RT5668_DMIC1_CLK_GPIO1,
|
||||
RT5668_DMIC1_CLK_GPIO3,
|
||||
};
|
||||
|
||||
enum rt5668_jd_src {
|
||||
RT5668_JD_NULL,
|
||||
RT5668_JD1,
|
||||
};
|
||||
|
||||
struct rt5668_platform_data {
|
||||
|
||||
int ldo1_en; /* GPIO for LDO1_EN */
|
||||
|
||||
enum rt5668_dmic1_data_pin dmic1_data_pin;
|
||||
enum rt5668_dmic1_clk_pin dmic1_clk_pin;
|
||||
enum rt5668_jd_src jd_src;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -296,8 +296,8 @@ struct snd_soc_dai {
|
|||
struct snd_soc_dai_driver *driver;
|
||||
|
||||
/* DAI runtime info */
|
||||
unsigned int capture_active:1; /* stream is in use */
|
||||
unsigned int playback_active:1; /* stream is in use */
|
||||
unsigned int capture_active; /* stream usage count */
|
||||
unsigned int playback_active; /* stream usage count */
|
||||
unsigned int probed:1;
|
||||
|
||||
unsigned int active;
|
||||
|
@ -315,7 +315,6 @@ struct snd_soc_dai {
|
|||
unsigned int sample_bits;
|
||||
|
||||
/* parent platform/codec */
|
||||
struct snd_soc_codec *codec;
|
||||
struct snd_soc_component *component;
|
||||
|
||||
/* CODEC TDM slot masks and params (for fixup) */
|
||||
|
|
|
@ -401,11 +401,7 @@ struct snd_soc_ops;
|
|||
struct snd_soc_pcm_runtime;
|
||||
struct snd_soc_dai;
|
||||
struct snd_soc_dai_driver;
|
||||
struct snd_soc_platform;
|
||||
struct snd_soc_dai_link;
|
||||
struct snd_soc_platform_driver;
|
||||
struct snd_soc_codec;
|
||||
struct snd_soc_codec_driver;
|
||||
struct snd_soc_component;
|
||||
struct snd_soc_component_driver;
|
||||
struct soc_enum;
|
||||
|
@ -430,13 +426,6 @@ enum snd_soc_card_subclass {
|
|||
SND_SOC_CARD_CLASS_RUNTIME = 1,
|
||||
};
|
||||
|
||||
int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
|
||||
int source, unsigned int freq, int dir);
|
||||
int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
|
||||
unsigned int freq_in, unsigned int freq_out);
|
||||
int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
|
||||
struct snd_soc_jack *jack, void *data);
|
||||
|
||||
int snd_soc_register_card(struct snd_soc_card *card);
|
||||
int snd_soc_unregister_card(struct snd_soc_card *card);
|
||||
int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
|
||||
|
@ -455,19 +444,6 @@ static inline int snd_soc_resume(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
int snd_soc_poweroff(struct device *dev);
|
||||
int snd_soc_register_platform(struct device *dev,
|
||||
const struct snd_soc_platform_driver *platform_drv);
|
||||
int devm_snd_soc_register_platform(struct device *dev,
|
||||
const struct snd_soc_platform_driver *platform_drv);
|
||||
void snd_soc_unregister_platform(struct device *dev);
|
||||
int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
|
||||
const struct snd_soc_platform_driver *platform_drv);
|
||||
void snd_soc_remove_platform(struct snd_soc_platform *platform);
|
||||
struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev);
|
||||
int snd_soc_register_codec(struct device *dev,
|
||||
const struct snd_soc_codec_driver *codec_drv,
|
||||
struct snd_soc_dai_driver *dai_drv, int num_dai);
|
||||
void snd_soc_unregister_codec(struct device *dev);
|
||||
int snd_soc_add_component(struct device *dev,
|
||||
struct snd_soc_component *component,
|
||||
const struct snd_soc_component_driver *component_driver,
|
||||
|
@ -482,16 +458,15 @@ int devm_snd_soc_register_component(struct device *dev,
|
|||
void snd_soc_unregister_component(struct device *dev);
|
||||
struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
|
||||
const char *driver_name);
|
||||
int snd_soc_cache_init(struct snd_soc_codec *codec);
|
||||
int snd_soc_cache_exit(struct snd_soc_codec *codec);
|
||||
|
||||
int snd_soc_platform_read(struct snd_soc_platform *platform,
|
||||
unsigned int reg);
|
||||
int snd_soc_platform_write(struct snd_soc_platform *platform,
|
||||
unsigned int reg, unsigned int val);
|
||||
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
|
||||
#ifdef CONFIG_SND_SOC_COMPRESS
|
||||
int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
|
||||
#else
|
||||
static inline int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void snd_soc_disconnect_sync(struct device *dev);
|
||||
|
@ -576,23 +551,7 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* codec register bit access */
|
||||
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
|
||||
unsigned int mask, unsigned int value);
|
||||
int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
|
||||
unsigned int reg, unsigned int mask,
|
||||
unsigned int value);
|
||||
int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
|
||||
unsigned int mask, unsigned int value);
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AC97_BUS
|
||||
#define snd_soc_alloc_ac97_codec(codec) \
|
||||
snd_soc_alloc_ac97_component(&codec->component)
|
||||
#define snd_soc_new_ac97_codec(codec, id, id_mask) \
|
||||
snd_soc_new_ac97_component(&codec->component, id, id_mask)
|
||||
#define snd_soc_free_ac97_codec(ac97) \
|
||||
snd_soc_free_ac97_component(ac97)
|
||||
|
||||
struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component);
|
||||
struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
|
||||
unsigned int id, unsigned int id_mask);
|
||||
|
@ -626,10 +585,6 @@ struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
|
|||
const char *name);
|
||||
int snd_soc_add_component_controls(struct snd_soc_component *component,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
|
||||
const struct snd_kcontrol_new *controls, int num_controls);
|
||||
int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
|
||||
|
@ -862,8 +817,6 @@ struct snd_soc_component {
|
|||
|
||||
unsigned int active;
|
||||
|
||||
unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
|
||||
unsigned int registered_as_component:1;
|
||||
unsigned int suspended:1; /* is in suspend PM state */
|
||||
|
||||
struct list_head list;
|
||||
|
@ -875,9 +828,6 @@ struct snd_soc_component {
|
|||
struct list_head dai_list;
|
||||
int num_dai;
|
||||
|
||||
int (*read)(struct snd_soc_component *, unsigned int, unsigned int *);
|
||||
int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
|
||||
|
||||
struct regmap *regmap;
|
||||
int val_bytes;
|
||||
|
||||
|
@ -886,10 +836,6 @@ struct snd_soc_component {
|
|||
/* attached dynamic objects */
|
||||
struct list_head dobj_list;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_root;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DO NOT use any of the fields below in drivers, they are temporary and
|
||||
* are going to be removed again soon. If you use them in driver code the
|
||||
|
@ -899,29 +845,11 @@ struct snd_soc_component {
|
|||
/* Don't use these, use snd_soc_component_get_dapm() */
|
||||
struct snd_soc_dapm_context dapm;
|
||||
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
int (*probe)(struct snd_soc_component *);
|
||||
void (*remove)(struct snd_soc_component *);
|
||||
int (*suspend)(struct snd_soc_component *);
|
||||
int (*resume)(struct snd_soc_component *);
|
||||
int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
|
||||
void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
|
||||
|
||||
int (*set_sysclk)(struct snd_soc_component *component,
|
||||
int clk_id, int source, unsigned int freq, int dir);
|
||||
int (*set_pll)(struct snd_soc_component *component, int pll_id,
|
||||
int source, unsigned int freq_in, unsigned int freq_out);
|
||||
int (*set_jack)(struct snd_soc_component *component,
|
||||
struct snd_soc_jack *jack, void *data);
|
||||
int (*set_bias_level)(struct snd_soc_component *component,
|
||||
enum snd_soc_bias_level level);
|
||||
|
||||
/* machine specific init */
|
||||
int (*init)(struct snd_soc_component *component);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void (*init_debugfs)(struct snd_soc_component *component);
|
||||
struct dentry *debugfs_root;
|
||||
const char *debugfs_prefix;
|
||||
#endif
|
||||
};
|
||||
|
@ -938,97 +866,12 @@ snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
|
|||
#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \
|
||||
list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list)
|
||||
|
||||
/* SoC Audio Codec device */
|
||||
struct snd_soc_codec {
|
||||
struct device *dev;
|
||||
const struct snd_soc_codec_driver *driver;
|
||||
|
||||
struct list_head list;
|
||||
|
||||
/* runtime */
|
||||
unsigned int cache_init:1; /* codec cache has been initialized */
|
||||
|
||||
/* codec IO */
|
||||
void *control_data; /* codec control (i2c/3wire) data */
|
||||
hw_write_t hw_write;
|
||||
void *reg_cache;
|
||||
|
||||
/* component */
|
||||
struct snd_soc_component component;
|
||||
};
|
||||
|
||||
/* codec driver */
|
||||
struct snd_soc_codec_driver {
|
||||
|
||||
/* driver ops */
|
||||
int (*probe)(struct snd_soc_codec *);
|
||||
int (*remove)(struct snd_soc_codec *);
|
||||
int (*suspend)(struct snd_soc_codec *);
|
||||
int (*resume)(struct snd_soc_codec *);
|
||||
struct snd_soc_component_driver component_driver;
|
||||
|
||||
/* codec wide operations */
|
||||
int (*set_sysclk)(struct snd_soc_codec *codec,
|
||||
int clk_id, int source, unsigned int freq, int dir);
|
||||
int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
|
||||
unsigned int freq_in, unsigned int freq_out);
|
||||
int (*set_jack)(struct snd_soc_codec *codec,
|
||||
struct snd_soc_jack *jack, void *data);
|
||||
|
||||
/* codec IO */
|
||||
struct regmap *(*get_regmap)(struct device *);
|
||||
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
||||
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
|
||||
unsigned int reg_cache_size;
|
||||
short reg_cache_step;
|
||||
short reg_word_size;
|
||||
const void *reg_cache_default;
|
||||
|
||||
/* codec bias level */
|
||||
int (*set_bias_level)(struct snd_soc_codec *,
|
||||
enum snd_soc_bias_level level);
|
||||
bool idle_bias_off;
|
||||
bool suspend_bias_off;
|
||||
|
||||
void (*seq_notifier)(struct snd_soc_dapm_context *,
|
||||
enum snd_soc_dapm_type, int);
|
||||
|
||||
bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */
|
||||
};
|
||||
|
||||
/* SoC platform interface */
|
||||
struct snd_soc_platform_driver {
|
||||
|
||||
int (*probe)(struct snd_soc_platform *);
|
||||
int (*remove)(struct snd_soc_platform *);
|
||||
struct snd_soc_component_driver component_driver;
|
||||
|
||||
/* pcm creation and destruction */
|
||||
int (*pcm_new)(struct snd_soc_pcm_runtime *);
|
||||
void (*pcm_free)(struct snd_pcm *);
|
||||
|
||||
/* platform stream pcm ops */
|
||||
const struct snd_pcm_ops *ops;
|
||||
|
||||
/* platform stream compress ops */
|
||||
const struct snd_compr_ops *compr_ops;
|
||||
};
|
||||
|
||||
struct snd_soc_dai_link_component {
|
||||
const char *name;
|
||||
struct device_node *of_node;
|
||||
const char *dai_name;
|
||||
};
|
||||
|
||||
struct snd_soc_platform {
|
||||
struct device *dev;
|
||||
const struct snd_soc_platform_driver *driver;
|
||||
|
||||
struct list_head list;
|
||||
|
||||
struct snd_soc_component component;
|
||||
};
|
||||
|
||||
struct snd_soc_dai_link {
|
||||
/* config - must be set by machine driver */
|
||||
const char *name; /* Codec name */
|
||||
|
@ -1276,8 +1119,6 @@ struct snd_soc_pcm_runtime {
|
|||
/* runtime devices */
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_compr *compr;
|
||||
struct snd_soc_codec *codec;
|
||||
struct snd_soc_platform *platform; /* will be removed */
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_dai *cpu_dai;
|
||||
|
||||
|
@ -1345,32 +1186,6 @@ struct soc_enum {
|
|||
struct snd_soc_dobj dobj;
|
||||
};
|
||||
|
||||
/**
|
||||
* snd_soc_component_to_codec() - Casts a component to the CODEC it is embedded in
|
||||
* @component: The component to cast to a CODEC
|
||||
*
|
||||
* This function must only be used on components that are known to be CODECs.
|
||||
* Otherwise the behavior is undefined.
|
||||
*/
|
||||
static inline struct snd_soc_codec *snd_soc_component_to_codec(
|
||||
struct snd_soc_component *component)
|
||||
{
|
||||
return container_of(component, struct snd_soc_codec, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_component_to_platform() - Casts a component to the platform it is embedded in
|
||||
* @component: The component to cast to a platform
|
||||
*
|
||||
* This function must only be used on components that are known to be platforms.
|
||||
* Otherwise the behavior is undefined.
|
||||
*/
|
||||
static inline struct snd_soc_platform *snd_soc_component_to_platform(
|
||||
struct snd_soc_component *component)
|
||||
{
|
||||
return container_of(component, struct snd_soc_platform, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
|
||||
* embedded in
|
||||
|
@ -1386,33 +1201,6 @@ static inline struct snd_soc_component *snd_soc_dapm_to_component(
|
|||
return container_of(dapm, struct snd_soc_component, dapm);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
|
||||
* @dapm: The DAPM context to cast to the CODEC
|
||||
*
|
||||
* This function must only be used on DAPM contexts that are known to be part of
|
||||
* a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
|
||||
*/
|
||||
static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
|
||||
struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
return snd_soc_component_to_codec(snd_soc_dapm_to_component(dapm));
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_to_platform() - Casts a DAPM context to the platform it is
|
||||
* embedded in
|
||||
* @dapm: The DAPM context to cast to the platform.
|
||||
*
|
||||
* This function must only be used on DAPM contexts that are known to be part of
|
||||
* a platform (e.g. in a platform driver). Otherwise the behavior is undefined.
|
||||
*/
|
||||
static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
|
||||
struct snd_soc_dapm_context *dapm)
|
||||
{
|
||||
return snd_soc_component_to_platform(snd_soc_dapm_to_component(dapm));
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_component_get_dapm() - Returns the DAPM context associated with a
|
||||
* component
|
||||
|
@ -1424,31 +1212,6 @@ static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
|
|||
return &component->dapm;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_codec_get_dapm() - Returns the DAPM context for the CODEC
|
||||
* @codec: The CODEC for which to get the DAPM context
|
||||
*
|
||||
* Note: Use this function instead of directly accessing the CODEC's dapm field
|
||||
*/
|
||||
static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
|
||||
struct snd_soc_codec *codec)
|
||||
{
|
||||
return snd_soc_component_get_dapm(&codec->component);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
|
||||
* @codec: The CODEC for which to initialize the DAPM bias level
|
||||
* @level: The DAPM level to initialize to
|
||||
*
|
||||
* Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
|
||||
*/
|
||||
static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
|
||||
* @component: The COMPONENT for which to initialize the DAPM bias level
|
||||
|
@ -1464,18 +1227,6 @@ snd_soc_component_init_bias_level(struct snd_soc_component *component,
|
|||
snd_soc_component_get_dapm(component), level);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
|
||||
* @codec: The CODEC for which to get the DAPM bias level
|
||||
*
|
||||
* Returns: The current DAPM bias level of the CODEC.
|
||||
*/
|
||||
static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
|
||||
struct snd_soc_codec *codec)
|
||||
{
|
||||
return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
|
||||
* @component: The COMPONENT for which to get the DAPM bias level
|
||||
|
@ -1489,21 +1240,6 @@ snd_soc_component_get_bias_level(struct snd_soc_component *component)
|
|||
snd_soc_component_get_dapm(component));
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
|
||||
* @codec: The CODEC for which to set the level
|
||||
* @level: The level to set to
|
||||
*
|
||||
* Forces the CODEC bias level to a specific state. See
|
||||
* snd_soc_dapm_force_bias_level().
|
||||
*/
|
||||
static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
|
||||
level);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
|
||||
* @component: The COMPONENT for which to set the level
|
||||
|
@ -1521,19 +1257,6 @@ snd_soc_component_force_bias_level(struct snd_soc_component *component,
|
|||
level);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
|
||||
* @kcontrol: The kcontrol
|
||||
*
|
||||
* This function must only be used on DAPM contexts that are known to be part of
|
||||
* a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
|
||||
*/
|
||||
static inline struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(
|
||||
struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol
|
||||
* @kcontrol: The kcontrol
|
||||
|
@ -1547,22 +1270,6 @@ static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
|
|||
return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
|
||||
}
|
||||
|
||||
/* codec IO */
|
||||
unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
|
||||
int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
|
||||
unsigned int val);
|
||||
|
||||
/**
|
||||
* snd_soc_cache_sync() - Sync the register cache with the hardware
|
||||
* @codec: CODEC to sync
|
||||
*
|
||||
* Note: This function will call regcache_sync()
|
||||
*/
|
||||
static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
|
||||
{
|
||||
return regcache_sync(codec->component.regmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_component_cache_sync() - Sync the register cache with the hardware
|
||||
* @component: COMPONENT to sync
|
||||
|
@ -1605,37 +1312,6 @@ void snd_soc_component_init_regmap(struct snd_soc_component *component,
|
|||
struct regmap *regmap);
|
||||
void snd_soc_component_exit_regmap(struct snd_soc_component *component);
|
||||
|
||||
/**
|
||||
* snd_soc_codec_init_regmap() - Initialize regmap instance for the CODEC
|
||||
* @codec: The CODEC for which to initialize the regmap instance
|
||||
* @regmap: The regmap instance that should be used by the CODEC
|
||||
*
|
||||
* This function allows deferred assignment of the regmap instance that is
|
||||
* associated with the CODEC. Only use this if the regmap instance is not yet
|
||||
* ready when the CODEC is registered. The function must also be called before
|
||||
* the first IO attempt of the CODEC.
|
||||
*/
|
||||
static inline void snd_soc_codec_init_regmap(struct snd_soc_codec *codec,
|
||||
struct regmap *regmap)
|
||||
{
|
||||
snd_soc_component_init_regmap(&codec->component, regmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_codec_exit_regmap() - De-initialize regmap instance for the CODEC
|
||||
* @codec: The CODEC for which to de-initialize the regmap instance
|
||||
*
|
||||
* Calls regmap_exit() on the regmap instance associated to the CODEC and
|
||||
* removes the regmap instance from the CODEC.
|
||||
*
|
||||
* This function should only be used if snd_soc_codec_init_regmap() was used to
|
||||
* initialize the regmap instance.
|
||||
*/
|
||||
static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec)
|
||||
{
|
||||
snd_soc_component_exit_regmap(&codec->component);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* device driver data */
|
||||
|
@ -1662,28 +1338,6 @@ static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
|
|||
return dev_get_drvdata(c->dev);
|
||||
}
|
||||
|
||||
static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
|
||||
void *data)
|
||||
{
|
||||
snd_soc_component_set_drvdata(&codec->component, data);
|
||||
}
|
||||
|
||||
static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
|
||||
{
|
||||
return snd_soc_component_get_drvdata(&codec->component);
|
||||
}
|
||||
|
||||
static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
|
||||
void *data)
|
||||
{
|
||||
snd_soc_component_set_drvdata(&platform->component, data);
|
||||
}
|
||||
|
||||
static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
|
||||
{
|
||||
return snd_soc_component_get_drvdata(&platform->component);
|
||||
}
|
||||
|
||||
static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
|
||||
{
|
||||
INIT_LIST_HEAD(&card->widgets);
|
||||
|
@ -1735,20 +1389,15 @@ static inline bool snd_soc_component_is_active(
|
|||
return component->active != 0;
|
||||
}
|
||||
|
||||
static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
|
||||
{
|
||||
return snd_soc_component_is_active(&codec->component);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_kcontrol_component() - Returns the component that registered the
|
||||
* control
|
||||
* @kcontrol: The control for which to get the component
|
||||
*
|
||||
* Note: This function will work correctly if the control has been registered
|
||||
* for a component. Either with snd_soc_add_codec_controls() or
|
||||
* snd_soc_add_platform_controls() or via table based setup for either a
|
||||
* CODEC, a platform or component driver. Otherwise the behavior is undefined.
|
||||
* for a component. With snd_soc_add_codec_controls() or via table based
|
||||
* setup for either a CODEC or component driver. Otherwise the behavior is
|
||||
* undefined.
|
||||
*/
|
||||
static inline struct snd_soc_component *snd_soc_kcontrol_component(
|
||||
struct snd_kcontrol *kcontrol)
|
||||
|
@ -1756,34 +1405,6 @@ static inline struct snd_soc_component *snd_soc_kcontrol_component(
|
|||
return snd_kcontrol_chip(kcontrol);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_kcontrol_codec() - Returns the CODEC that registered the control
|
||||
* @kcontrol: The control for which to get the CODEC
|
||||
*
|
||||
* Note: This function will only work correctly if the control has been
|
||||
* registered with snd_soc_add_codec_controls() or via table based setup of
|
||||
* snd_soc_codec_driver. Otherwise the behavior is undefined.
|
||||
*/
|
||||
static inline struct snd_soc_codec *snd_soc_kcontrol_codec(
|
||||
struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
return snd_soc_component_to_codec(snd_soc_kcontrol_component(kcontrol));
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_kcontrol_platform() - Returns the platform that registered the control
|
||||
* @kcontrol: The control for which to get the platform
|
||||
*
|
||||
* Note: This function will only work correctly if the control has been
|
||||
* registered with snd_soc_add_platform_controls() or via table based setup of
|
||||
* a snd_soc_platform_driver. Otherwise the behavior is undefined.
|
||||
*/
|
||||
static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
|
||||
struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol));
|
||||
}
|
||||
|
||||
int snd_soc_util_init(void);
|
||||
void snd_soc_util_exit(void);
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#define DAPM_ARROW(dir) (((dir) == SND_SOC_DAPM_DIR_OUT) ? "->" : "<-")
|
||||
|
||||
struct snd_soc_jack;
|
||||
struct snd_soc_codec;
|
||||
struct snd_soc_card;
|
||||
struct snd_soc_dapm_widget;
|
||||
struct snd_soc_dapm_path;
|
||||
|
|
|
@ -285,9 +285,22 @@ static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor
|
|||
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
|
||||
int protocol)
|
||||
{
|
||||
return (protocol == UAC_VERSION_1) ?
|
||||
&desc->baSourceID[desc->bNrInPins + 4] :
|
||||
&desc->baSourceID[desc->bNrInPins + 6];
|
||||
switch (protocol) {
|
||||
case UAC_VERSION_1:
|
||||
return &desc->baSourceID[desc->bNrInPins + 4];
|
||||
case UAC_VERSION_2:
|
||||
return &desc->baSourceID[desc->bNrInPins + 6];
|
||||
case UAC_VERSION_3:
|
||||
return &desc->baSourceID[desc->bNrInPins + 2];
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline __u16 uac3_mixer_unit_wClusterDescrID(struct uac_mixer_unit_descriptor *desc)
|
||||
{
|
||||
return (desc->baSourceID[desc->bNrInPins + 1] << 8) |
|
||||
desc->baSourceID[desc->bNrInPins];
|
||||
}
|
||||
|
||||
static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
|
||||
|
|
|
@ -139,6 +139,15 @@
|
|||
#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1)
|
||||
#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2)
|
||||
|
||||
/* DAI clock gating */
|
||||
#define SND_SOC_TPLG_DAI_CLK_GATE_UNDEFINED 0
|
||||
#define SND_SOC_TPLG_DAI_CLK_GATE_GATED 1
|
||||
#define SND_SOC_TPLG_DAI_CLK_GATE_CONT 2
|
||||
|
||||
/* DAI mclk_direction */
|
||||
#define SND_SOC_TPLG_MCLK_CO 0 /* for codec, mclk is output */
|
||||
#define SND_SOC_TPLG_MCLK_CI 1 /* for codec, mclk is input */
|
||||
|
||||
/* DAI physical PCM data formats.
|
||||
* Add new formats to the end of the list.
|
||||
*/
|
||||
|
@ -160,6 +169,18 @@
|
|||
#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2)
|
||||
#define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP (1 << 3)
|
||||
|
||||
/* DAI topology BCLK parameter
|
||||
* For the backwards capability, by default codec is bclk master
|
||||
*/
|
||||
#define SND_SOC_TPLG_BCLK_CM 0 /* codec is bclk master */
|
||||
#define SND_SOC_TPLG_BCLK_CS 1 /* codec is bclk slave */
|
||||
|
||||
/* DAI topology FSYNC parameter
|
||||
* For the backwards capability, by default codec is fsync master
|
||||
*/
|
||||
#define SND_SOC_TPLG_FSYNC_CM 0 /* codec is fsync master */
|
||||
#define SND_SOC_TPLG_FSYNC_CS 1 /* codec is fsync slave */
|
||||
|
||||
/*
|
||||
* Block Header.
|
||||
* This header precedes all object and object arrays below.
|
||||
|
@ -312,12 +333,12 @@ struct snd_soc_tplg_hw_config {
|
|||
__le32 size; /* in bytes of this structure */
|
||||
__le32 id; /* unique ID - - used to match */
|
||||
__le32 fmt; /* SND_SOC_DAI_FORMAT_ format value */
|
||||
__u8 clock_gated; /* 1 if clock can be gated to save power */
|
||||
__u8 clock_gated; /* SND_SOC_TPLG_DAI_CLK_GATE_ value */
|
||||
__u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */
|
||||
__u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */
|
||||
__u8 bclk_master; /* 1 for master of BCLK, 0 for slave */
|
||||
__u8 fsync_master; /* 1 for master of FSYNC, 0 for slave */
|
||||
__u8 mclk_direction; /* 0 for input, 1 for output */
|
||||
__u8 bclk_master; /* SND_SOC_TPLG_BCLK_ value */
|
||||
__u8 fsync_master; /* SND_SOC_TPLG_FSYNC_ value */
|
||||
__u8 mclk_direction; /* SND_SOC_TPLG_MCLK_ value */
|
||||
__le16 reserved; /* for 32bit alignment */
|
||||
__le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */
|
||||
__le32 bclk_rate; /* BCLK freqency in Hz */
|
||||
|
@ -552,4 +573,61 @@ struct snd_soc_tplg_dai {
|
|||
__le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */
|
||||
struct snd_soc_tplg_private priv;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Old version of ABI structs, supported for backward compatibility.
|
||||
*/
|
||||
|
||||
/* Manifest v4 */
|
||||
struct snd_soc_tplg_manifest_v4 {
|
||||
__le32 size; /* in bytes of this structure */
|
||||
__le32 control_elems; /* number of control elements */
|
||||
__le32 widget_elems; /* number of widget elements */
|
||||
__le32 graph_elems; /* number of graph elements */
|
||||
__le32 pcm_elems; /* number of PCM elements */
|
||||
__le32 dai_link_elems; /* number of DAI link elements */
|
||||
struct snd_soc_tplg_private priv;
|
||||
} __packed;
|
||||
|
||||
/* Stream Capabilities v4 */
|
||||
struct snd_soc_tplg_stream_caps_v4 {
|
||||
__le32 size; /* in bytes of this structure */
|
||||
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
__le64 formats; /* supported formats SNDRV_PCM_FMTBIT_* */
|
||||
__le32 rates; /* supported rates SNDRV_PCM_RATE_* */
|
||||
__le32 rate_min; /* min rate */
|
||||
__le32 rate_max; /* max rate */
|
||||
__le32 channels_min; /* min channels */
|
||||
__le32 channels_max; /* max channels */
|
||||
__le32 periods_min; /* min number of periods */
|
||||
__le32 periods_max; /* max number of periods */
|
||||
__le32 period_size_min; /* min period size bytes */
|
||||
__le32 period_size_max; /* max period size bytes */
|
||||
__le32 buffer_size_min; /* min buffer size bytes */
|
||||
__le32 buffer_size_max; /* max buffer size bytes */
|
||||
} __packed;
|
||||
|
||||
/* PCM v4 */
|
||||
struct snd_soc_tplg_pcm_v4 {
|
||||
__le32 size; /* in bytes of this structure */
|
||||
char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
__le32 pcm_id; /* unique ID - used to match with DAI link */
|
||||
__le32 dai_id; /* unique ID - used to match */
|
||||
__le32 playback; /* supports playback mode */
|
||||
__le32 capture; /* supports capture mode */
|
||||
__le32 compress; /* 1 = compressed; 0 = PCM */
|
||||
struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
|
||||
__le32 num_streams; /* number of streams */
|
||||
struct snd_soc_tplg_stream_caps_v4 caps[2]; /* playback and capture for DAI */
|
||||
} __packed;
|
||||
|
||||
/* Physical link config v4 */
|
||||
struct snd_soc_tplg_link_config_v4 {
|
||||
__le32 size; /* in bytes of this structure */
|
||||
__le32 id; /* unique ID - used to match */
|
||||
struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
|
||||
__le32 num_streams; /* number of streams */
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* skl-tplg-interface.h - Intel DSP FW private data interface
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corp
|
||||
* Author: Jeeja KP <jeeja.kp@intel.com>
|
||||
* Nilofer, Samreen <samreen.nilofer@intel.com>
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __HDA_TPLG_INTERFACE_H__
|
||||
|
@ -169,4 +160,78 @@ enum skl_tuple_type {
|
|||
SKL_TYPE_DATA
|
||||
};
|
||||
|
||||
/* v4 configuration data */
|
||||
|
||||
struct skl_dfw_v4_module_pin {
|
||||
u16 module_id;
|
||||
u16 instance_id;
|
||||
} __packed;
|
||||
|
||||
struct skl_dfw_v4_module_fmt {
|
||||
u32 channels;
|
||||
u32 freq;
|
||||
u32 bit_depth;
|
||||
u32 valid_bit_depth;
|
||||
u32 ch_cfg;
|
||||
u32 interleaving_style;
|
||||
u32 sample_type;
|
||||
u32 ch_map;
|
||||
} __packed;
|
||||
|
||||
struct skl_dfw_v4_module_caps {
|
||||
u32 set_params:2;
|
||||
u32 rsvd:30;
|
||||
u32 param_id;
|
||||
u32 caps_size;
|
||||
u32 caps[HDA_SST_CFG_MAX];
|
||||
} __packed;
|
||||
|
||||
struct skl_dfw_v4_pipe {
|
||||
u8 pipe_id;
|
||||
u8 pipe_priority;
|
||||
u16 conn_type:4;
|
||||
u16 rsvd:4;
|
||||
u16 memory_pages:8;
|
||||
} __packed;
|
||||
|
||||
struct skl_dfw_v4_module {
|
||||
char uuid[SKL_UUID_STR_SZ];
|
||||
|
||||
u16 module_id;
|
||||
u16 instance_id;
|
||||
u32 max_mcps;
|
||||
u32 mem_pages;
|
||||
u32 obs;
|
||||
u32 ibs;
|
||||
u32 vbus_id;
|
||||
|
||||
u32 max_in_queue:8;
|
||||
u32 max_out_queue:8;
|
||||
u32 time_slot:8;
|
||||
u32 core_id:4;
|
||||
u32 rsvd1:4;
|
||||
|
||||
u32 module_type:8;
|
||||
u32 conn_type:4;
|
||||
u32 dev_type:4;
|
||||
u32 hw_conn_type:4;
|
||||
u32 rsvd2:12;
|
||||
|
||||
u32 params_fixup:8;
|
||||
u32 converter:8;
|
||||
u32 input_pin_type:1;
|
||||
u32 output_pin_type:1;
|
||||
u32 is_dynamic_in_pin:1;
|
||||
u32 is_dynamic_out_pin:1;
|
||||
u32 is_loadable:1;
|
||||
u32 rsvd3:11;
|
||||
|
||||
struct skl_dfw_v4_pipe pipe;
|
||||
struct skl_dfw_v4_module_fmt in_fmt[MAX_IN_QUEUE];
|
||||
struct skl_dfw_v4_module_fmt out_fmt[MAX_OUT_QUEUE];
|
||||
struct skl_dfw_v4_module_pin in_pin[MAX_IN_QUEUE];
|
||||
struct skl_dfw_v4_module_pin out_pin[MAX_OUT_QUEUE];
|
||||
struct skl_dfw_v4_module_caps caps;
|
||||
} __packed;
|
||||
|
||||
#endif
|
|
@ -42,6 +42,10 @@
|
|||
#define SNDRV_CTL_TLVD_LENGTH(...) \
|
||||
((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ }))
|
||||
|
||||
/* Accessor offsets for TLV data items */
|
||||
#define SNDRV_CTL_TLVO_TYPE 0
|
||||
#define SNDRV_CTL_TLVO_LEN 1
|
||||
|
||||
#define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \
|
||||
SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__)
|
||||
#define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \
|
||||
|
@ -61,6 +65,10 @@
|
|||
SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \
|
||||
}
|
||||
|
||||
/* Accessor offsets for min, mute and step items in dB scale type TLV */
|
||||
#define SNDRV_CTL_TLVO_DB_SCALE_MIN 2
|
||||
#define SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP 3
|
||||
|
||||
/* dB scale specified with min/max values instead of step */
|
||||
#define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \
|
||||
SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB))
|
||||
|
@ -75,6 +83,10 @@
|
|||
SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
|
||||
}
|
||||
|
||||
/* Accessor offsets for min, max items in db-minmax types of TLV. */
|
||||
#define SNDRV_CTL_TLVO_DB_MINMAX_MIN 2
|
||||
#define SNDRV_CTL_TLVO_DB_MINMAX_MAX 3
|
||||
|
||||
/* linear volume between min_dB and max_dB (.01dB unit) */
|
||||
#define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
|
||||
SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))
|
||||
|
@ -83,6 +95,10 @@
|
|||
SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
|
||||
}
|
||||
|
||||
/* Accessor offsets for min, max items in db-linear type of TLV. */
|
||||
#define SNDRV_CTL_TLVO_DB_LINEAR_MIN 2
|
||||
#define SNDRV_CTL_TLVO_DB_LINEAR_MAX 3
|
||||
|
||||
/* dB range container:
|
||||
* Items in dB range container must be ordered by their values and by their
|
||||
* dB values. This implies that larger values must correspond with larger
|
||||
|
|
|
@ -96,6 +96,8 @@ source "sound/x86/Kconfig"
|
|||
|
||||
source "sound/synth/Kconfig"
|
||||
|
||||
source "sound/xen/Kconfig"
|
||||
|
||||
endif # SND
|
||||
|
||||
endif # !UML
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
obj-$(CONFIG_SOUND) += soundcore.o
|
||||
obj-$(CONFIG_DMASOUND) += oss/dmasound/
|
||||
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
|
||||
firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/
|
||||
firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/
|
||||
obj-$(CONFIG_SND_AOA) += aoa/
|
||||
|
||||
# This one must be compilable even if sound is configured out
|
||||
|
|
|
@ -1001,7 +1001,7 @@ static int snd_compress_proc_init(struct snd_compr *compr)
|
|||
compr->card->proc_root);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
entry->mode = S_IFDIR | 0555;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -240,6 +240,15 @@ void snd_device_free_all(struct snd_card *card)
|
|||
|
||||
if (snd_BUG_ON(!card))
|
||||
return;
|
||||
list_for_each_entry_safe_reverse(dev, next, &card->devices, list) {
|
||||
/* exception: free ctl and lowlevel stuff later */
|
||||
if (dev->type == SNDRV_DEV_CONTROL ||
|
||||
dev->type == SNDRV_DEV_LOWLEVEL)
|
||||
continue;
|
||||
__snd_device_free(dev);
|
||||
}
|
||||
|
||||
/* free all */
|
||||
list_for_each_entry_safe_reverse(dev, next, &card->devices, list)
|
||||
__snd_device_free(dev);
|
||||
}
|
||||
|
|
|
@ -454,7 +454,7 @@ static struct snd_info_entry *create_subdir(struct module *mod,
|
|||
entry = snd_info_create_module_entry(mod, name, NULL);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
entry->mode = S_IFDIR | 0555;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
return NULL;
|
||||
|
@ -470,7 +470,7 @@ int __init snd_info_init(void)
|
|||
snd_proc_root = snd_info_create_entry("asound", NULL);
|
||||
if (!snd_proc_root)
|
||||
return -ENOMEM;
|
||||
snd_proc_root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
snd_proc_root->mode = S_IFDIR | 0555;
|
||||
snd_proc_root->p = proc_mkdir("asound", NULL);
|
||||
if (!snd_proc_root->p)
|
||||
goto error;
|
||||
|
@ -716,7 +716,7 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent)
|
|||
kfree(entry);
|
||||
return NULL;
|
||||
}
|
||||
entry->mode = S_IFREG | S_IRUGO;
|
||||
entry->mode = S_IFREG | 0444;
|
||||
entry->content = SNDRV_INFO_CONTENT_TEXT;
|
||||
mutex_init(&entry->access);
|
||||
INIT_LIST_HEAD(&entry->children);
|
||||
|
|
|
@ -703,7 +703,7 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
|
|||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
|
||||
static DEVICE_ATTR(id, 0644, card_id_show_attr, card_id_store_attr);
|
||||
|
||||
static ssize_t
|
||||
card_number_show_attr(struct device *dev,
|
||||
|
@ -713,7 +713,7 @@ card_number_show_attr(struct device *dev,
|
|||
return scnprintf(buf, PAGE_SIZE, "%i\n", card->number);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL);
|
||||
static DEVICE_ATTR(number, 0444, card_number_show_attr, NULL);
|
||||
|
||||
static struct attribute *card_dev_attrs[] = {
|
||||
&dev_attr_id.attr,
|
||||
|
|
|
@ -1247,7 +1247,7 @@ static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer)
|
|||
if (! entry)
|
||||
return;
|
||||
entry->content = SNDRV_INFO_CONTENT_TEXT;
|
||||
entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
|
||||
entry->mode = S_IFREG | 0644;
|
||||
entry->c.text.read = snd_mixer_oss_proc_read;
|
||||
entry->c.text.write = snd_mixer_oss_proc_write;
|
||||
entry->private_data = mixer;
|
||||
|
|
|
@ -3045,7 +3045,7 @@ static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
|
|||
continue;
|
||||
if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
|
||||
entry->content = SNDRV_INFO_CONTENT_TEXT;
|
||||
entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
|
||||
entry->mode = S_IFREG | 0644;
|
||||
entry->c.text.read = snd_pcm_oss_proc_read;
|
||||
entry->c.text.write = snd_pcm_oss_proc_write;
|
||||
entry->private_data = pstr;
|
||||
|
|
|
@ -530,7 +530,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
|
|||
pcm->card->proc_root);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
entry->mode = S_IFDIR | 0555;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
return -ENOMEM;
|
||||
|
@ -552,7 +552,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
|
|||
if (entry) {
|
||||
entry->c.text.read = snd_pcm_xrun_debug_read;
|
||||
entry->c.text.write = snd_pcm_xrun_debug_write;
|
||||
entry->mode |= S_IWUSR;
|
||||
entry->mode |= 0200;
|
||||
entry->private_data = pstr;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
|
@ -590,7 +590,7 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
|
|||
substream->pstr->proc_root);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
entry->mode = S_IFDIR | 0555;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
return -ENOMEM;
|
||||
|
@ -647,7 +647,7 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
|
|||
entry->private_data = substream;
|
||||
entry->c.text.read = NULL;
|
||||
entry->c.text.write = snd_pcm_xrun_injection_write;
|
||||
entry->mode = S_IFREG | S_IWUSR;
|
||||
entry->mode = S_IFREG | 0200;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
entry = NULL;
|
||||
|
@ -1087,7 +1087,7 @@ static ssize_t show_pcm_class(struct device *dev,
|
|||
return snprintf(buf, PAGE_SIZE, "%s\n", str);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
|
||||
static DEVICE_ATTR(pcm_class, 0444, show_pcm_class, NULL);
|
||||
static struct attribute *pcm_dev_attrs[] = {
|
||||
&dev_attr_pcm_class.attr,
|
||||
NULL
|
||||
|
|
|
@ -45,10 +45,7 @@ static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream,
|
|||
|
||||
if (get_user(frames, src))
|
||||
return -EFAULT;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
err = snd_pcm_playback_rewind(substream, frames);
|
||||
else
|
||||
err = snd_pcm_capture_rewind(substream, frames);
|
||||
err = snd_pcm_rewind(substream, frames);
|
||||
if (put_user(err, src))
|
||||
return -EFAULT;
|
||||
return err < 0 ? err : 0;
|
||||
|
@ -62,10 +59,7 @@ static int snd_pcm_ioctl_forward_compat(struct snd_pcm_substream *substream,
|
|||
|
||||
if (get_user(frames, src))
|
||||
return -EFAULT;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
err = snd_pcm_playback_forward(substream, frames);
|
||||
else
|
||||
err = snd_pcm_capture_forward(substream, frames);
|
||||
err = snd_pcm_forward(substream, frames);
|
||||
if (put_user(err, src))
|
||||
return -EFAULT;
|
||||
return err < 0 ? err : 0;
|
||||
|
|
|
@ -191,10 +191,7 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
|
|||
{
|
||||
snd_pcm_uframes_t avail;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
avail = snd_pcm_playback_avail(runtime);
|
||||
else
|
||||
avail = snd_pcm_capture_avail(runtime);
|
||||
avail = snd_pcm_avail(substream);
|
||||
if (avail > runtime->avail_max)
|
||||
runtime->avail_max = avail;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
|
||||
|
@ -1856,10 +1853,7 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
|
|||
* This check must happen after been added to the waitqueue
|
||||
* and having current state be INTERRUPTIBLE.
|
||||
*/
|
||||
if (is_playback)
|
||||
avail = snd_pcm_playback_avail(runtime);
|
||||
else
|
||||
avail = snd_pcm_capture_avail(runtime);
|
||||
avail = snd_pcm_avail(substream);
|
||||
if (avail >= runtime->twake)
|
||||
break;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
|
@ -2175,10 +2169,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
|
|||
runtime->twake = runtime->control->avail_min ? : 1;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
|
||||
snd_pcm_update_hw_ptr(substream);
|
||||
if (is_playback)
|
||||
avail = snd_pcm_playback_avail(runtime);
|
||||
else
|
||||
avail = snd_pcm_capture_avail(runtime);
|
||||
avail = snd_pcm_avail(substream);
|
||||
while (size > 0) {
|
||||
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
|
||||
snd_pcm_uframes_t cont;
|
||||
|
|
|
@ -36,6 +36,24 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
|
|||
void snd_pcm_playback_silence(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t new_hw_ptr);
|
||||
|
||||
static inline snd_pcm_uframes_t
|
||||
snd_pcm_avail(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return snd_pcm_playback_avail(substream->runtime);
|
||||
else
|
||||
return snd_pcm_capture_avail(substream->runtime);
|
||||
}
|
||||
|
||||
static inline snd_pcm_uframes_t
|
||||
snd_pcm_hw_avail(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return snd_pcm_playback_hw_avail(substream->runtime);
|
||||
else
|
||||
return snd_pcm_capture_hw_avail(substream->runtime);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_PCM_TIMER
|
||||
void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream);
|
||||
void snd_pcm_timer_init(struct snd_pcm_substream *substream);
|
||||
|
|
|
@ -201,7 +201,7 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
|
|||
if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
|
||||
entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
|
||||
entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
|
||||
entry->mode |= S_IWUSR;
|
||||
entry->mode |= 0200;
|
||||
entry->private_data = substream;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
|
|
|
@ -99,6 +99,57 @@ static inline void down_write_nonblock(struct rw_semaphore *lock)
|
|||
cond_resched();
|
||||
}
|
||||
|
||||
#define PCM_LOCK_DEFAULT 0
|
||||
#define PCM_LOCK_IRQ 1
|
||||
#define PCM_LOCK_IRQSAVE 2
|
||||
|
||||
static unsigned long __snd_pcm_stream_lock_mode(struct snd_pcm_substream *substream,
|
||||
unsigned int mode)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
if (substream->pcm->nonatomic) {
|
||||
down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING);
|
||||
mutex_lock(&substream->self_group.mutex);
|
||||
} else {
|
||||
switch (mode) {
|
||||
case PCM_LOCK_DEFAULT:
|
||||
read_lock(&snd_pcm_link_rwlock);
|
||||
break;
|
||||
case PCM_LOCK_IRQ:
|
||||
read_lock_irq(&snd_pcm_link_rwlock);
|
||||
break;
|
||||
case PCM_LOCK_IRQSAVE:
|
||||
read_lock_irqsave(&snd_pcm_link_rwlock, flags);
|
||||
break;
|
||||
}
|
||||
spin_lock(&substream->self_group.lock);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void __snd_pcm_stream_unlock_mode(struct snd_pcm_substream *substream,
|
||||
unsigned int mode, unsigned long flags)
|
||||
{
|
||||
if (substream->pcm->nonatomic) {
|
||||
mutex_unlock(&substream->self_group.mutex);
|
||||
up_read(&snd_pcm_link_rwsem);
|
||||
} else {
|
||||
spin_unlock(&substream->self_group.lock);
|
||||
|
||||
switch (mode) {
|
||||
case PCM_LOCK_DEFAULT:
|
||||
read_unlock(&snd_pcm_link_rwlock);
|
||||
break;
|
||||
case PCM_LOCK_IRQ:
|
||||
read_unlock_irq(&snd_pcm_link_rwlock);
|
||||
break;
|
||||
case PCM_LOCK_IRQSAVE:
|
||||
read_unlock_irqrestore(&snd_pcm_link_rwlock, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_pcm_stream_lock - Lock the PCM stream
|
||||
* @substream: PCM substream
|
||||
|
@ -109,13 +160,7 @@ static inline void down_write_nonblock(struct rw_semaphore *lock)
|
|||
*/
|
||||
void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (substream->pcm->nonatomic) {
|
||||
down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING);
|
||||
mutex_lock(&substream->self_group.mutex);
|
||||
} else {
|
||||
read_lock(&snd_pcm_link_rwlock);
|
||||
spin_lock(&substream->self_group.lock);
|
||||
}
|
||||
__snd_pcm_stream_lock_mode(substream, PCM_LOCK_DEFAULT);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
|
||||
|
||||
|
@ -127,13 +172,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
|
|||
*/
|
||||
void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (substream->pcm->nonatomic) {
|
||||
mutex_unlock(&substream->self_group.mutex);
|
||||
up_read(&snd_pcm_link_rwsem);
|
||||
} else {
|
||||
spin_unlock(&substream->self_group.lock);
|
||||
read_unlock(&snd_pcm_link_rwlock);
|
||||
}
|
||||
__snd_pcm_stream_unlock_mode(substream, PCM_LOCK_DEFAULT, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
|
||||
|
||||
|
@ -147,9 +186,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
|
|||
*/
|
||||
void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (!substream->pcm->nonatomic)
|
||||
local_irq_disable();
|
||||
snd_pcm_stream_lock(substream);
|
||||
__snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQ);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
|
||||
|
||||
|
@ -161,19 +198,13 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
|
|||
*/
|
||||
void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_pcm_stream_unlock(substream);
|
||||
if (!substream->pcm->nonatomic)
|
||||
local_irq_enable();
|
||||
__snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQ, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq);
|
||||
|
||||
unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
if (!substream->pcm->nonatomic)
|
||||
local_irq_save(flags);
|
||||
snd_pcm_stream_lock(substream);
|
||||
return flags;
|
||||
return __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQSAVE);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
|
||||
|
||||
|
@ -187,9 +218,7 @@ EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
|
|||
void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
|
||||
unsigned long flags)
|
||||
{
|
||||
snd_pcm_stream_unlock(substream);
|
||||
if (!substream->pcm->nonatomic)
|
||||
local_irq_restore(flags);
|
||||
__snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQSAVE, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
|
||||
|
||||
|
@ -857,6 +886,18 @@ static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
|
|||
return err;
|
||||
}
|
||||
|
||||
static inline snd_pcm_uframes_t
|
||||
snd_pcm_calc_delay(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_pcm_uframes_t delay;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
delay = snd_pcm_playback_hw_avail(substream->runtime);
|
||||
else
|
||||
delay = snd_pcm_capture_avail(substream->runtime);
|
||||
return delay + substream->runtime->delay;
|
||||
}
|
||||
|
||||
int snd_pcm_status(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_status *status)
|
||||
{
|
||||
|
@ -908,21 +949,9 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
|
|||
_tstamp_end:
|
||||
status->appl_ptr = runtime->control->appl_ptr;
|
||||
status->hw_ptr = runtime->status->hw_ptr;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
status->avail = snd_pcm_playback_avail(runtime);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
|
||||
runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
|
||||
status->delay = runtime->buffer_size - status->avail;
|
||||
status->delay += runtime->delay;
|
||||
} else
|
||||
status->delay = 0;
|
||||
} else {
|
||||
status->avail = snd_pcm_capture_avail(runtime);
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
|
||||
status->delay = status->avail + runtime->delay;
|
||||
else
|
||||
status->delay = 0;
|
||||
}
|
||||
status->avail = snd_pcm_avail(substream);
|
||||
status->delay = snd_pcm_running(substream) ?
|
||||
snd_pcm_calc_delay(substream) : 0;
|
||||
status->avail_max = runtime->avail_max;
|
||||
status->overrange = runtime->overrange;
|
||||
runtime->avail_max = 0;
|
||||
|
@ -2610,10 +2639,9 @@ static snd_pcm_sframes_t rewind_appl_ptr(struct snd_pcm_substream *substream,
|
|||
return ret < 0 ? 0 : frames;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t frames)
|
||||
static snd_pcm_sframes_t snd_pcm_rewind(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t ret;
|
||||
|
||||
if (frames == 0)
|
||||
|
@ -2623,33 +2651,14 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
|
|||
ret = do_pcm_hwsync(substream);
|
||||
if (!ret)
|
||||
ret = rewind_appl_ptr(substream, frames,
|
||||
snd_pcm_playback_hw_avail(runtime));
|
||||
snd_pcm_hw_avail(substream));
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t frames)
|
||||
static snd_pcm_sframes_t snd_pcm_forward(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t ret;
|
||||
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
ret = do_pcm_hwsync(substream);
|
||||
if (!ret)
|
||||
ret = rewind_appl_ptr(substream, frames,
|
||||
snd_pcm_capture_hw_avail(runtime));
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t ret;
|
||||
|
||||
if (frames == 0)
|
||||
|
@ -2659,25 +2668,7 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
|
|||
ret = do_pcm_hwsync(substream);
|
||||
if (!ret)
|
||||
ret = forward_appl_ptr(substream, frames,
|
||||
snd_pcm_playback_avail(runtime));
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t ret;
|
||||
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
ret = do_pcm_hwsync(substream);
|
||||
if (!ret)
|
||||
ret = forward_appl_ptr(substream, frames,
|
||||
snd_pcm_capture_avail(runtime));
|
||||
snd_pcm_avail(substream));
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2695,19 +2686,13 @@ static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
|
|||
static int snd_pcm_delay(struct snd_pcm_substream *substream,
|
||||
snd_pcm_sframes_t *delay)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int err;
|
||||
snd_pcm_sframes_t n = 0;
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
err = do_pcm_hwsync(substream);
|
||||
if (!err) {
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
n = snd_pcm_playback_hw_avail(runtime);
|
||||
else
|
||||
n = snd_pcm_capture_avail(runtime);
|
||||
n += runtime->delay;
|
||||
}
|
||||
if (!err)
|
||||
n = snd_pcm_calc_delay(substream);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (!err)
|
||||
*delay = n;
|
||||
|
@ -2834,10 +2819,7 @@ static int snd_pcm_rewind_ioctl(struct snd_pcm_substream *substream,
|
|||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
result = snd_pcm_playback_rewind(substream, frames);
|
||||
else
|
||||
result = snd_pcm_capture_rewind(substream, frames);
|
||||
result = snd_pcm_rewind(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
@ -2852,10 +2834,7 @@ static int snd_pcm_forward_ioctl(struct snd_pcm_substream *substream,
|
|||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
result = snd_pcm_playback_forward(substream, frames);
|
||||
else
|
||||
result = snd_pcm_capture_forward(substream, frames);
|
||||
result = snd_pcm_forward(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
@ -2998,7 +2977,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
|
|||
/* provided only for OSS; capture-only and no value returned */
|
||||
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
|
||||
return -EINVAL;
|
||||
result = snd_pcm_capture_forward(substream, *frames);
|
||||
result = snd_pcm_forward(substream, *frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_HW_PARAMS:
|
||||
|
@ -3140,82 +3119,46 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
|
|||
return result;
|
||||
}
|
||||
|
||||
static __poll_t snd_pcm_playback_poll(struct file *file, poll_table * wait)
|
||||
static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct snd_pcm_file *pcm_file;
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
__poll_t mask;
|
||||
__poll_t mask, ok;
|
||||
snd_pcm_uframes_t avail;
|
||||
|
||||
pcm_file = file->private_data;
|
||||
|
||||
substream = pcm_file->substream;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
ok = EPOLLOUT | EPOLLWRNORM;
|
||||
else
|
||||
ok = EPOLLIN | EPOLLRDNORM;
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return EPOLLOUT | EPOLLWRNORM | EPOLLERR;
|
||||
runtime = substream->runtime;
|
||||
return ok | EPOLLERR;
|
||||
|
||||
runtime = substream->runtime;
|
||||
poll_wait(file, &runtime->sleep, wait);
|
||||
|
||||
mask = 0;
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
avail = snd_pcm_playback_avail(runtime);
|
||||
avail = snd_pcm_avail(substream);
|
||||
switch (runtime->status->state) {
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
case SNDRV_PCM_STATE_PAUSED:
|
||||
if (avail >= runtime->control->avail_min) {
|
||||
mask = EPOLLOUT | EPOLLWRNORM;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case SNDRV_PCM_STATE_DRAINING:
|
||||
mask = 0;
|
||||
break;
|
||||
default:
|
||||
mask = EPOLLOUT | EPOLLWRNORM | EPOLLERR;
|
||||
break;
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return mask;
|
||||
}
|
||||
|
||||
static __poll_t snd_pcm_capture_poll(struct file *file, poll_table * wait)
|
||||
{
|
||||
struct snd_pcm_file *pcm_file;
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
__poll_t mask;
|
||||
snd_pcm_uframes_t avail;
|
||||
|
||||
pcm_file = file->private_data;
|
||||
|
||||
substream = pcm_file->substream;
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return EPOLLIN | EPOLLRDNORM | EPOLLERR;
|
||||
runtime = substream->runtime;
|
||||
|
||||
poll_wait(file, &runtime->sleep, wait);
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
avail = snd_pcm_capture_avail(runtime);
|
||||
switch (runtime->status->state) {
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
case SNDRV_PCM_STATE_PAUSED:
|
||||
if (avail >= runtime->control->avail_min) {
|
||||
mask = EPOLLIN | EPOLLRDNORM;
|
||||
break;
|
||||
}
|
||||
mask = 0;
|
||||
if (avail >= runtime->control->avail_min)
|
||||
mask = ok;
|
||||
break;
|
||||
case SNDRV_PCM_STATE_DRAINING:
|
||||
if (avail > 0) {
|
||||
mask = EPOLLIN | EPOLLRDNORM;
|
||||
break;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
mask = ok;
|
||||
if (!avail)
|
||||
mask |= EPOLLERR;
|
||||
}
|
||||
/* Fall through */
|
||||
break;
|
||||
default:
|
||||
mask = EPOLLIN | EPOLLRDNORM | EPOLLERR;
|
||||
mask = ok | EPOLLERR;
|
||||
break;
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
|
@ -3707,7 +3650,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
|
|||
.open = snd_pcm_playback_open,
|
||||
.release = snd_pcm_release,
|
||||
.llseek = no_llseek,
|
||||
.poll = snd_pcm_playback_poll,
|
||||
.poll = snd_pcm_poll,
|
||||
.unlocked_ioctl = snd_pcm_ioctl,
|
||||
.compat_ioctl = snd_pcm_ioctl_compat,
|
||||
.mmap = snd_pcm_mmap,
|
||||
|
@ -3721,7 +3664,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
|
|||
.open = snd_pcm_capture_open,
|
||||
.release = snd_pcm_release,
|
||||
.llseek = no_llseek,
|
||||
.poll = snd_pcm_capture_poll,
|
||||
.poll = snd_pcm_poll,
|
||||
.unlocked_ioctl = snd_pcm_ioctl,
|
||||
.compat_ioctl = snd_pcm_ioctl_compat,
|
||||
.mmap = snd_pcm_mmap,
|
||||
|
|
|
@ -669,7 +669,7 @@ int snd_seq_event_port_attach(int client,
|
|||
/* Set up the port */
|
||||
memset(&portinfo, 0, sizeof(portinfo));
|
||||
portinfo.addr.client = client;
|
||||
strlcpy(portinfo.name, portname ? portname : "Unamed port",
|
||||
strlcpy(portinfo.name, portname ? portname : "Unnamed port",
|
||||
sizeof(portinfo.name));
|
||||
|
||||
portinfo.capability = cap;
|
||||
|
|
|
@ -371,9 +371,7 @@ static int initialize_timer(struct snd_seq_timer *tmr)
|
|||
|
||||
tmr->ticks = 1;
|
||||
if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
|
||||
unsigned long r = t->hw.resolution;
|
||||
if (! r && t->hw.c_resolution)
|
||||
r = t->hw.c_resolution(t);
|
||||
unsigned long r = snd_timer_resolution(tmr->timeri);
|
||||
if (r) {
|
||||
tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
|
||||
if (! tmr->ticks)
|
||||
|
|
|
@ -427,25 +427,35 @@ int snd_timer_close(struct snd_timer_instance *timeri)
|
|||
}
|
||||
EXPORT_SYMBOL(snd_timer_close);
|
||||
|
||||
static unsigned long snd_timer_hw_resolution(struct snd_timer *timer)
|
||||
{
|
||||
if (timer->hw.c_resolution)
|
||||
return timer->hw.c_resolution(timer);
|
||||
else
|
||||
return timer->hw.resolution;
|
||||
}
|
||||
|
||||
unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
|
||||
{
|
||||
struct snd_timer * timer;
|
||||
unsigned long ret = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (timeri == NULL)
|
||||
return 0;
|
||||
timer = timeri->timer;
|
||||
if (timer) {
|
||||
if (timer->hw.c_resolution)
|
||||
return timer->hw.c_resolution(timer);
|
||||
return timer->hw.resolution;
|
||||
spin_lock_irqsave(&timer->lock, flags);
|
||||
ret = snd_timer_hw_resolution(timer);
|
||||
spin_unlock_irqrestore(&timer->lock, flags);
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_timer_resolution);
|
||||
|
||||
static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
|
||||
{
|
||||
struct snd_timer *timer;
|
||||
struct snd_timer *timer = ti->timer;
|
||||
unsigned long resolution = 0;
|
||||
struct snd_timer_instance *ts;
|
||||
struct timespec tstamp;
|
||||
|
@ -457,14 +467,14 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
|
|||
if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
|
||||
event > SNDRV_TIMER_EVENT_PAUSE))
|
||||
return;
|
||||
if (event == SNDRV_TIMER_EVENT_START ||
|
||||
event == SNDRV_TIMER_EVENT_CONTINUE)
|
||||
resolution = snd_timer_resolution(ti);
|
||||
if (timer &&
|
||||
(event == SNDRV_TIMER_EVENT_START ||
|
||||
event == SNDRV_TIMER_EVENT_CONTINUE))
|
||||
resolution = snd_timer_hw_resolution(timer);
|
||||
if (ti->ccallback)
|
||||
ti->ccallback(ti, event, &tstamp, resolution);
|
||||
if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
|
||||
return;
|
||||
timer = ti->timer;
|
||||
if (timer == NULL)
|
||||
return;
|
||||
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
|
||||
|
@ -771,10 +781,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
|
|||
spin_lock_irqsave(&timer->lock, flags);
|
||||
|
||||
/* remember the current resolution */
|
||||
if (timer->hw.c_resolution)
|
||||
resolution = timer->hw.c_resolution(timer);
|
||||
else
|
||||
resolution = timer->hw.resolution;
|
||||
resolution = snd_timer_hw_resolution(timer);
|
||||
|
||||
/* loop for all active instances
|
||||
* Here we cannot use list_for_each_entry because the active_list of a
|
||||
|
@ -1014,12 +1021,8 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
|
|||
spin_lock_irqsave(&timer->lock, flags);
|
||||
if (event == SNDRV_TIMER_EVENT_MSTART ||
|
||||
event == SNDRV_TIMER_EVENT_MCONTINUE ||
|
||||
event == SNDRV_TIMER_EVENT_MRESUME) {
|
||||
if (timer->hw.c_resolution)
|
||||
resolution = timer->hw.c_resolution(timer);
|
||||
else
|
||||
resolution = timer->hw.resolution;
|
||||
}
|
||||
event == SNDRV_TIMER_EVENT_MRESUME)
|
||||
resolution = snd_timer_hw_resolution(timer);
|
||||
list_for_each_entry(ti, &timer->active_list_head, active_list) {
|
||||
if (ti->ccallback)
|
||||
ti->ccallback(ti, event, tstamp, resolution);
|
||||
|
@ -1656,10 +1659,8 @@ static int snd_timer_user_gstatus(struct file *file,
|
|||
mutex_lock(®ister_mutex);
|
||||
t = snd_timer_find(&tid);
|
||||
if (t != NULL) {
|
||||
if (t->hw.c_resolution)
|
||||
gstatus.resolution = t->hw.c_resolution(t);
|
||||
else
|
||||
gstatus.resolution = t->hw.resolution;
|
||||
spin_lock_irq(&t->lock);
|
||||
gstatus.resolution = snd_timer_hw_resolution(t);
|
||||
if (t->hw.precise_resolution) {
|
||||
t->hw.precise_resolution(t, &gstatus.resolution_num,
|
||||
&gstatus.resolution_den);
|
||||
|
@ -1667,6 +1668,7 @@ static int snd_timer_user_gstatus(struct file *file,
|
|||
gstatus.resolution_num = gstatus.resolution;
|
||||
gstatus.resolution_den = 1000000000uL;
|
||||
}
|
||||
spin_unlock_irq(&t->lock);
|
||||
} else {
|
||||
err = -ENODEV;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue