Commit 3146089d authored by Mark Brown's avatar Mark Brown

Merge branch 'asoc-5.1' into asoc-next

parents b5e806ae 7b6b0049
......@@ -23,6 +23,12 @@ Optional properties:
- DVDD-supply: supply voltage for the digital core, please consult
Documentation/devicetree/bindings/regulator/regulator.txt
- adi,micbias: configures the voltage setting for the MICBIAS pin.
Select 0/1/2/3/4/5/6/7/8 to specify MICBIAS voltage
5V/5.5V/6V/6.5V/7V/7.5V/8V/8.5V/9V
If not specified the default value will be "7" meaning 8.5 Volts.
This property is only valid for the ADAU1977
For required properties on SPI, please consult
Documentation/devicetree/bindings/spi/spi-bus.txt
......@@ -40,6 +46,7 @@ Examples:
AVDD-supply = <&regulator>;
DVDD-supply = <&regulator_digital>;
adi,micbias = <3>;
reset-gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
};
......
......@@ -4,7 +4,7 @@ This device supports I2C mode.
Required properties:
- compatible : "asahi-kasei,ak4458"
- compatible : "asahi-kasei,ak4458" or "asahi-kasei,ak4497"
- reg : The I2C address of the device for I2C
Optional properties:
......
Audio-Graph-SCU-Card:
Audio-Graph-SCU-Card is "Audio-Graph-Card" + "ALSA DPCM".
It is based on common bindings for device graphs.
see ${LINUX}/Documentation/devicetree/bindings/graph.txt
Basically, Audio-Graph-SCU-Card property is same as
Simple-Card / Simple-SCU-Card / Audio-Graph-Card.
see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt
${LINUX}/Documentation/devicetree/bindings/sound/simple-scu-card.txt
${LINUX}/Documentation/devicetree/bindings/sound/audio-graph-card.txt
Below are same as Simple-Card / Audio-Graph-Card.
- label
- dai-format
- frame-master
- bitclock-master
- bitclock-inversion
- frame-inversion
- dai-tdm-slot-num
- dai-tdm-slot-width
- clocks / system-clock-frequency
Below are same as Simple-SCU-Card.
- convert-rate
- convert-channels
- prefix
- routing
Required properties:
- compatible : "audio-graph-scu-card";
- dais : list of CPU DAI port{s}
Example 1. Sampling Rate Conversion
sound_card {
compatible = "audio-graph-scu-card";
label = "sound-card";
prefix = "codec";
routing = "codec Playback", "DAI0 Playback",
"DAI0 Capture", "codec Capture";
convert-rate = <48000>;
dais = <&cpu_port>;
};
audio-codec {
...
port {
codec_endpoint: endpoint {
remote-endpoint = <&cpu_endpoint>;
};
};
};
dai-controller {
...
cpu_port: port {
cpu_endpoint: endpoint {
remote-endpoint = <&codec_endpoint>;
dai-format = "left_j";
...
};
};
};
Example 2. 2 CPU 1 Codec (Mixing)
sound_card {
compatible = "audio-graph-scu-card";
label = "sound-card";
routing = "codec Playback", "DAI0 Playback",
"codec Playback", "DAI1 Playback",
"DAI0 Capture", "codec Capture";
dais = <&cpu_port0
&cpu_port1>;
};
audio-codec {
...
audio-graph-card,prefix = "codec";
audio-graph-card,convert-rate = <48000>;
port {
codec_endpoint0: endpoint {
remote-endpoint = <&cpu_endpoint0>;
};
codec_endpoint1: endpoint {
remote-endpoint = <&cpu_endpoint1>;
};
};
};
dai-controller {
...
ports {
cpu_port0: port {
cpu_endpoint0: endpoint {
remote-endpoint = <&codec_endpoint0>;
dai-format = "left_j";
...
};
};
cpu_port1: port {
cpu_endpoint1: endpoint {
remote-endpoint = <&codec_endpoint1>;
dai-format = "left_j";
...
};
};
};
};
CS35L36 Speaker Amplifier
Required properties:
- compatible : "cirrus,cs35l36"
- reg : the I2C address of the device for I2C
- VA-supply, VP-supply : power supplies for the device,
as covered in
Documentation/devicetree/bindings/regulator/regulator.txt.
- cirrus,boost-ctl-millivolt : Boost Voltage Value. Configures the boost
converter's output voltage in mV. The range is from 2550mV to 12000mV with
increments of 50mV.
(Default) VP
- cirrus,boost-peak-milliamp : Boost-converter peak current limit in mA.
Configures the peak current by monitoring the current through the boost FET.
Range starts at 1600mA and goes to a maximum of 4500mA with increments of
50mA.
(Default) 4.50 Amps
- cirrus,boost-ind-nanohenry : Inductor estimation LBST reference value.
Seeds the digital boost converter's inductor estimation block with the initial
inductance value to reference.
1000 = 1uH (Default)
1200 = 1.2uH
Optional properties:
- cirrus,multi-amp-mode : Boolean to determine if there are more than
one amplifier in the system. If more than one it is best to Hi-Z the ASP
port to prevent bus contention on the output signal
- cirrus,boost-ctl-select : Boost conerter control source selection.
Selects the source of the BST_CTL target VBST voltage for the boost
converter to generate.
0x00 - Control Port Value
0x01 - Class H Tracking (Default)
0x10 - MultiDevice Sync Value
- cirrus,amp-pcm-inv : Boolean to determine Amplifier will invert incoming
PCM data
- cirrus,imon-pol-inv : Boolean to determine Amplifier will invert the
polarity of outbound IMON feedback data
- cirrus,vmon-pol-inv : Boolean to determine Amplifier will invert the
polarity of outbound VMON feedback data
- cirrus,dcm-mode-enable : Boost converter automatic DCM Mode enable.
This enables the digital boost converter to operate in a low power
(Discontinuous Conduction) mode during low loading conditions.
- cirrus,weak-fet-disable : Boolean : The strength of the output drivers is
reduced when operating in a Weak-FET Drive Mode and must not be used to drive
a large load.
- cirrus,classh-wk-fet-delay : Weak-FET entry delay. Controls the delay
(in ms) before the Class H algorithm switches to the weak-FET voltage
(after the audio falls and remains below the value specified in WKFET_AMP_THLD).
0 = 0ms
1 = 5ms
2 = 10ms
3 = 50ms
4 = 100ms (Default)
5 = 200ms
6 = 500ms
7 = 1000ms
- cirrus,classh-weak-fet-thld-millivolt : Weak-FET amplifier drive threshold.
Configures the signal threshold at which the PWM output stage enters
weak-FET operation. The range is 50mV to 700mV in 50mV increments.
- cirrus,temp-warn-threshold : Amplifier overtemperature warning threshold.
Configures the threshold at which the overtemperature warning condition occurs.
When the threshold is met, the overtemperature warning attenuation is applied
and the TEMP_WARN_EINT interrupt status bit is set.
If TEMP_WARN_MASK = 0, INTb is asserted.
0 = 105C
1 = 115C
2 = 125C (Default)
3 = 135C
- cirrus,irq-drive-select : Selects the driver type of the selected interrupt
output.
0 = Open-drain
1 = Push-pull (Default)
- cirrus,irq-gpio-select : Selects the pin to serve as the programmable
interrupt output.
0 = PDM_DATA / SWIRE_SD / INT (Default)
1 = GPIO
Optional properties for the "cirrus,vpbr-config" Sub-node
- cirrus,vpbr-en : VBST brownout prevention enable. Configures whether the
VBST brownout prevention algorithm is enabled or disabled.
0 = VBST brownout prevention disabled (default)
1 = VBST brownout prevention enabled
See Section 7.31.1 VPBR Config for configuration options & further details
- cirrus,vpbr-thld : Initial VPBR threshold. Configures the VP brownout
threshold voltage
- cirrus,cirrus,vpbr-atk-rate : Attenuation attack step rate. Configures the
amount delay between consecutive volume attenuation steps when a brownout
condition is present and the VP brownout condition is in an attacking state.
- cirrus,vpbr-atk-vol : VP brownout prevention step size. Configures the VP
brownout prevention attacking attenuation step size when operating in either
digital volume or analog gain modes.
- cirrus,vpbr-max-attn : Maximum attenuation that the VP brownout prevention
can apply to the audio signal.
- cirrus,vpbr-wait : Configures the delay time between a brownout condition
no longer being present and the VP brownout prevention entering an attenuation
release state.
- cirrus,vpbr-rel-rate : Attenuation release step rate. Configures the delay
between consecutive volume attenuation release steps when a brownout condition
is not longer present and the VP brownout is in an attenuation release state.
- cirrus,vpbr-mute-en : During the attack state, if the vpbr-max-attn value
is reached, the error condition still remains, and this bit is set, the audio
is muted.
Example:
cs35l36: cs35l36@40 {
compatible = "cirrus,cs35l36";
reg = <0x40>;
VA-supply = <&dummy_vreg>;
VP-supply = <&dummy_vreg>;
reset-gpios = <&gpio0 54 0>;
interrupt-parent = <&gpio8>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
cirrus,boost-ind-nanohenry = <1000>;
cirrus,boost-ctl-millivolt = <10000>;
cirrus,boost-peak-milliamp = <4500>;
cirrus,boost-ctl-select = <0x00>;
cirrus,weak-fet-delay = <0x04>;
cirrus,weak-fet-thld = <0x01>;
cirrus,temp-warn-threshold = <0x01>;
cirrus,multi-amp-mode;
cirrus,irq-drive-select = <0x01>;
cirrus,irq-gpio-select = <0x01>;
cirrus,vpbr-config {
cirrus,vpbr-en = <0x00>;
cirrus,vpbr-thld = <0x05>;
cirrus,vpbr-atk-rate = <0x02>;
cirrus,vpbr-atk-vol = <0x01>;
cirrus,vpbr-max-attn = <0x09>;
cirrus,vpbr-wait = <0x01>;
cirrus,vpbr-rel-rate = <0x05>;
cirrus,vpbr-mute-en = <0x00>;
};
};
Cirrus Logic CS4341 audio DAC
This device supports both I2C and SPI (configured with pin strapping
on the board).
Required properties:
- compatible: "cirrus,cs4341a"
- reg : the I2C address of the device for I2C, the chip select
number for SPI.
For required properties on I2C-bus, please consult
Documentation/devicetree/bindings/i2c/i2c.txt
For required properties on SPI-bus, please consult
Documentation/devicetree/bindings/spi/spi-bus.txt
Example:
codec: cs4341@0 {
#sound-dai-cells = <0>;
compatible = "cirrus,cs4341a";
reg = <0>;
spi-max-frequency = <6000000>;
};
......@@ -45,6 +45,23 @@ Optional properties:
- fck_parent : Should contain a valid clock name which will be used as parent
for the McASP fck
Optional GPIO support:
If any McASP pin need to be used as GPIO then the McASP node must have:
...
gpio-controller
#gpio-cells = <2>;
...
When requesting a GPIO, the first parameter is the PIN index in McASP_P*
registers.
For example to request the AXR2 pin of mcasp8:
function-gpios = <&mcasp8 2 0>;
Or to request the ACLKR pin of mcasp8:
function-gpios = <&mcasp8 29 0>;
For generic gpio information, please refer to bindings/gpio/gpio.txt
Example:
mcasp0: mcasp0@1d00000 {
......
NXP MICFIL Digital Audio Interface (MICFIL).
The MICFIL digital interface provides a 16-bit audio signal from a PDM
microphone bitstream in a configurable output sampling rate.
Required properties:
- compatible : Compatible list, contains "fsl,imx8mm-micfil"
- reg : Offset and length of the register set for the device.
- interrupts : Contains the micfil interrupts.
- clocks : Must contain an entry for each entry in clock-names.
- clock-names : Must include the "ipg_clk" for register access and
"ipg_clk_app" for internal micfil clock.
- dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt.
Example:
micfil: micfil@30080000 {
compatible = "fsl,imx8mm-micfil";
reg = <0x0 0x30080000 0x0 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX8MM_CLK_PDM_IPG>,
<&clk IMX8MM_CLK_PDM_ROOT>;
clock-names = "ipg_clk", "ipg_clk_app";
dmas = <&sdma2 24 26 0x80000000>;
};
* Audio codec controlled by ChromeOS EC
Google's ChromeOS EC codec is a digital mic codec provided by the
Embedded Controller (EC) and is controlled via a host-command interface.
An EC codec node should only be found as a sub-node of the EC node (see
Documentation/devicetree/bindings/mfd/cros-ec.txt).
Required properties:
- compatible: Must contain "google,cros-ec-codec"
- #sound-dai-cells: Should be 1. The cell specifies number of DAIs.
- max-dmic-gain: A number for maximum gain in dB on digital microphone.
Example:
cros-ec@0 {
compatible = "google,cros-ec-spi";
...
cros_ec_codec: ec-codec {
compatible = "google,cros-ec-codec";
#sound-dai-cells = <1>;
max-dmic-gain = <43>;
};
};
Ingenic JZ4725B codec controller
Required properties:
- compatible : "ingenic,jz4725b-codec"
- reg : codec registers location and length
- clocks : phandle to the AIC clock.
- clock-names: must be set to "aic".
- #sound-dai-cells: Must be set to 0.
Example:
codec: audio-codec@100200a4 {
compatible = "ingenic,jz4725b-codec";
reg = <0x100200a4 0x8>;
#sound-dai-cells = <0>;
clocks = <&cgu JZ4725B_CLK_AIC>;
clock-names = "aic";
};
Ingenic JZ4740 codec controller
Required properties:
- compatible : "ingenic,jz4740-codec"
- reg : codec registers location and length
- clocks : phandle to the AIC clock.
- clock-names: must be set to "aic".
- #sound-dai-cells: Must be set to 0.
Example:
codec: audio-codec@10020080 {
compatible = "ingenic,jz4740-codec";
reg = <0x10020080 0x8>;
#sound-dai-cells = <0>;
clocks = <&cgu JZ4740_CLK_AIC>;
clock-names = "aic";
};
Mediatek MT6358 Audio Codec
The communication between MT6358 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,mt6358-sound".
- Avdd-supply : power source of AVDD
Example:
mt6358_snd {
compatible = "mediatek,mt6358-sound";
Avdd-supply = <&mt6358_vaud28_reg>;
};
Mediatek AFE PCM controller for mt8183
Required properties:
- compatible = "mediatek,mt68183-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",
"mtkaif_26m_clk",
"top_mux_audio",
"top_mux_aud_intbus",
"top_sys_pll3_d4",
"top_clk26m_clk";
Example:
afe: mt8183-afe-pcm@11220000 {
compatible = "mediatek,mt8183-audio";
reg = <0 0x11220000 0 0x1000>;
interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&scpsys MT8183_POWER_DOMAIN_AUDIO>;
clocks = <&infrasys CLK_INFRA_AUDIO>,
<&infrasys CLK_INFRA_AUDIO_26M_BCLK>,
<&topckgen CLK_TOP_MUX_AUDIO>,
<&topckgen CLK_TOP_MUX_AUD_INTBUS>,
<&topckgen CLK_TOP_SYSPLL_D2_D4>,
<&clk26m>;
clock-names = "infra_sys_audio_clk",
"mtkaif_26m_clk",
"top_mux_audio",
"top_mux_aud_intbus",
"top_sys_pll_d2_d4",
"top_clk26m_clk";
};
Mediatek ALSA BT SCO CVSD/MSBC Driver
Required properties:
- compatible = "mediatek,mtk-btcvsd-snd";
- reg: register location and size of PKV and SRAM_BANK2
- interrupts: should contain BTSCO interrupt
- mediatek,infracfg: the phandles of INFRASYS
- mediatek,offset: Array contains of register offset and mask
infra_misc_offset,
infra_conn_bt_cvsd_mask,
cvsd_mcu_read_offset,
cvsd_mcu_write_offset,
cvsd_packet_indicator_offset
Example:
mtk-btcvsd-snd@18000000 {
compatible = "mediatek,mtk-btcvsd-snd";
reg=<0 0x18000000 0 0x1000>,
<0 0x18080000 0 0x8000>;
interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_LOW>;
mediatek,infracfg = <&infrasys>;
mediatek,offset = <0xf00 0x800 0xfd0 0xfd4 0xfd8>;
};
......@@ -30,6 +30,7 @@ Required properties
- vdd-cdc-io-supply: phandle to VDD_CDC_IO regulator DT node.
- vdd-cdc-tx-rx-cx-supply: phandle to VDD_CDC_TX/RX/CX regulator DT node.
- vdd-micbias-supply: phandle of VDD_MICBIAS supply's regulator DT node.
Optional Properties:
- qcom,mbhc-vthreshold-low: Array of 5 threshold voltages in mV for 5 buttons
detection on headset when the mbhc is powered up
......@@ -92,9 +93,9 @@ spmi_bus {
"cdc_ear_cnp_int",
"cdc_hphr_cnp_int",
"cdc_hphl_cnp_int";
VDD-CDC-IO-supply = <&pm8916_l5>;
VDD-CDC-TX-RX-CX-supply = <&pm8916_l5>;
VDD-MICBIAS-supply = <&pm8916_l13>;
vdd-cdc-io-supply = <&pm8916_l5>;
vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
vdd-micbias-supply = <&pm8916_l13>;
#sound-dai-cells = <1>;
};
};
......@@ -34,12 +34,12 @@ Required properties with SLIMbus Interface:
Definition: Interrupt names of WCD INTR1 and INTR2
Should be: "intr1", "intr2"
- reset-gpio:
- reset-gpios:
Usage: required
Value type: <String Array>
Definition: Reset gpio line
- qcom,ifd:
- slim-ifc-dev:
Usage: required
Value type: <phandle>
Definition: SLIM interface device
......@@ -104,13 +104,13 @@ Required properties with SLIMbus Interface:
Value type: <u32>
Definition: Must be 1
codec@1{
audio-codec@1{
compatible = "slim217,1a0";
reg = <1 0>;
interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr2"
reset-gpio = <&msmgpio 64 0>;
qcom,ifd = <&wc9335_ifd>;
reset-gpios = <&msmgpio 64 0>;
slim-ifc-dev = <&wc9335_ifd>;
clock-names = "mclk", "native";
clocks = <&rpmcc RPM_SMD_DIV_CLK1>,
<&rpmcc RPM_SMD_BB_CLK1>;
......
* Rockchip Rk3328 internal codec
Required properties:
- compatible: "rockchip,rk3328-codec"
- reg: physical base address of the controller and length of memory mapped
region.
- rockchip,grf: the phandle of the syscon node for GRF register.
- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
- clock-names: should be "pclk".
- spk-depop-time-ms: speak depop time msec.
Example for rk3328 internal codec:
codec: codec@ff410000 {
compatible = "rockchip,rk3328-codec";
reg = <0x0 0xff410000 0x0 0x1000>;
rockchip,grf = <&grf>;
clocks = <&cru PCLK_ACODEC>;
clock-names = "pclk";
spk-depop-time-ms = 100;
status = "disabled";
};
......@@ -37,6 +37,15 @@ VDDIO 1.8V 2.5V 3.3V
2 = 3.33 mA 5.74 mA 8.03 mA
3 = 4.99 mA 8.61 mA 12.05 mA
- sclk-strength: the SCLK pad strength. Possible values are:
0, 1, 2 and 3 as per the table below:
VDDIO 1.8V 2.5V 3.3V
0 = Disable
1 = 1.66 mA 2.87 mA 4.02 mA
2 = 3.33 mA 5.74 mA 8.03 mA
3 = 4.99 mA 8.61 mA 12.05 mA
Example:
sgtl5000: codec@a {
......
ASoC Simple SCU Sound Card
Simple SCU Sound Card is "Simple Sound Card" + "ALSA DPCM".
For example, you can use this driver if you want to exchange sampling rate convert,
Mixing, etc...
Required properties:
- compatible : "simple-scu-audio-card"
"renesas,rsrc-card"
Optional properties:
- simple-audio-card,name : see simple-audio-card.txt
- simple-audio-card,cpu : see simple-audio-card.txt
- simple-audio-card,codec : see simple-audio-card.txt
Optional subnode properties:
- simple-audio-card,format : see simple-audio-card.txt
- simple-audio-card,frame-master : see simple-audio-card.txt
- simple-audio-card,bitclock-master : see simple-audio-card.txt
- simple-audio-card,bitclock-inversion : see simple-audio-card.txt
- simple-audio-card,frame-inversion : see simple-audio-card.txt
- simple-audio-card,convert-rate : platform specified sampling rate convert
- simple-audio-card,convert-channels : platform specified converted channel size (2 - 8 ch)
- simple-audio-card,prefix : see routing
- simple-audio-card,widgets : Please refer to widgets.txt.
- simple-audio-card,routing : 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 for sources.
use audio-prefix if some components is using same sink/sources naming.
it can be used if compatible was "renesas,rsrc-card";
Required CPU/CODEC subnodes properties:
- sound-dai : see simple-audio-card.txt
Optional CPU/CODEC subnodes properties:
- clocks / system-clock-frequency : see simple-audio-card.txt
Example 1. Sampling Rate Conversion
sound {
compatible = "simple-scu-audio-card";
simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&sndcodec>;
simple-audio-card,frame-master = <&sndcodec>;
simple-audio-card,convert-rate = <48000>;
simple-audio-card,prefix = "ak4642";
simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
"DAI0 Capture", "ak4642 Capture";
sndcpu: simple-audio-card,cpu {
sound-dai = <&rcar_sound>;
};
sndcodec: simple-audio-card,codec {
sound-dai = <&ak4643>;
system-clock-frequency = <11289600>;
};
};
Example 2. 2 CPU 1 Codec (Mixing)
sound {
compatible = "simple-scu-audio-card";
simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&dpcmcpu>;
simple-audio-card,frame-master = <&dpcmcpu>;
simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
"ak4642 Playback", "DAI1 Playback";
dpcmcpu: cpu@0 {
sound-dai = <&rcar_sound 0>;
};
cpu@1 {
sound-dai = <&rcar_sound 1>;
};
codec {
prefix = "ak4642";
sound-dai = <&ak4643>;
clocks = <&audio_clock>;
};
};
* Spreadtrum DMA platfrom bindings
Required properties:
- compatible: Should be "sprd,pcm-platform".
- dmas: Specify the list of DMA controller phandle and DMA request line ordered pairs.
- dma-names: Identifier string for each DMA request line in the dmas property.
These strings correspond 1:1 with the ordered pairs in dmas.
Example:
audio_platform:platform@0 {
compatible = "sprd,pcm-platform";
dmas = <&agcp_dma 1 1>, <&agcp_dma 2 2>,
<&agcp_dma 3 3>, <&agcp_dma 4 4>,
<&agcp_dma 5 5>, <&agcp_dma 6 6>,
<&agcp_dma 7 7>, <&agcp_dma 8 8>,
<&agcp_dma 9 9>, <&agcp_dma 10 10>;
dma-names = "normal_p_l", "normal_p_r",
"normal_c_l", "normal_c_r",
"voice_c", "fast_p",
"loop_c", "loop_p",
"voip_c", "voip_p";
};
Device-Tree bindings for Xilinx PL audio formatter
The IP core supports DMA, data formatting(AES<->PCM conversion)
of audio samples.
Required properties:
- compatible: "xlnx,audio-formatter-1.0"
- interrupt-names: Names specified to list of interrupts in same
order mentioned under "interrupts".
List of supported interrupt names are:
"irq_mm2s" : interrupt from MM2S block
"irq_s2mm" : interrupt from S2MM block
- interrupts-parent: Phandle for interrupt controller.
- interrupts: List of Interrupt numbers.
- reg: Base address and size of the IP core instance.
- clock-names: List of input clocks.
Required elements: "s_axi_lite_aclk", "aud_mclk"
- clocks: Input clock specifier. Refer to common clock bindings.
Example:
audio_ss_0_audio_formatter_0: audio_formatter@80010000 {
compatible = "xlnx,audio-formatter-1.0";
interrupt-names = "irq_mm2s", "irq_s2mm";
interrupt-parent = <&gic>;
interrupts = <0 104 4>, <0 105 4>;
reg = <0x0 0x80010000 0x0 0x1000>;
clock-names = "s_axi_lite_aclk", "aud_mclk";
clocks = <&clk 71>, <&clk_wiz_1 0>;
};
Device-Tree bindings for Xilinx SPDIF IP
The IP supports playback and capture of SPDIF audio
Required properties:
- compatible: "xlnx,spdif-2.0"
- clock-names: List of input clocks.
Required elements: "s_axi_aclk", "aud_clk_i"
- clocks: Input clock specifier. Refer to common clock bindings.
- reg: Base address and address length of the IP core instance.
- interrupts-parent: Phandle for interrupt controller.
- interrupts: List of Interrupt numbers.
- xlnx,spdif-mode: 0 :- receiver mode
1 :- transmitter mode
- xlnx,aud_clk_i: input audio clock value.
Example:
spdif_0: spdif@80010000 {
clock-names = "aud_clk_i", "s_axi_aclk";
clocks = <&misc_clk_0>, <&clk 71>;
compatible = "xlnx,spdif-2.0";
interrupt-names = "spdif_interrupt";
interrupt-parent = <&gic>;
interrupts = <0 91 4>;
reg = <0x0 0x80010000 0x0 0x10000>;
xlnx,spdif-mode = <1>;
xlnx,aud_clk_i = <49152913>;
};
......@@ -13,7 +13,7 @@ drivers that expose several ALSA PCMs and can route to multiple DAIs.
The DPCM runtime routing is determined by the ALSA mixer settings in the same
way as the analog signal is routed in an ASoC codec driver. DPCM uses a DAPM
graph representing the DSP internal audio paths and uses the mixer settings to
determine the patch used by each ALSA PCM.
determine the path used by each ALSA PCM.
DPCM re-uses all the existing component codec, platform and DAI drivers without
any modifications.
......@@ -101,7 +101,7 @@ The audio driver processes this as follows :-
4. Machine driver or audio HAL enables the speaker path.
5. DPCM runs the PCM ops for startup(), hw_params(), prepapre() and
5. DPCM runs the PCM ops for startup(), hw_params(), prepare() and
trigger(start) for DAI1 Speakers since the path is enabled.
In this example, the machine driver or userspace audio HAL can alter the routing
......@@ -221,7 +221,7 @@ like a BT phone call :-
This allows the host CPU to sleep while the DSP, MODEM DAI and the BT DAI are
still in operation.
A BE DAI link can also set the codec to a dummy device if the code is a device
A BE DAI link can also set the codec to a dummy device if the codec is a device
that is managed externally.
Likewise a BE DAI can also set a dummy cpu DAI if the CPU DAI is managed by the
......@@ -249,7 +249,7 @@ configuration.
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
/* The DSP will covert the FE rate to 48k, stereo */
/* The DSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
......@@ -386,5 +386,3 @@ This means creating a new FE that is connected with a virtual path to both
DAI links. The DAI links will be started when the FE PCM is started and stopped
when the FE PCM is stopped. Note that the FE PCM cannot read or write data in
this configuration.
......@@ -3699,6 +3699,14 @@ N: cros_ec
N: cros-ec
F: drivers/power/supply/cros_usbpd-charger.c
CHROMEOS EC CODEC DRIVER
M: Cheng-Yi Chiang <cychiang@chromium.org>
S: Maintained
R: Enric Balletbo i Serra <enric.balletbo@collabora.com>
R: Guenter Roeck <groeck@chromium.org>
F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt
F: sound/soc/codecs/cros_ec_codec.*
CIRRUS LOGIC AUDIO CODEC DRIVERS
M: Brian Austin <brian.austin@cirrus.com>
M: Paul Handrigan <Paul.Handrigan@cirrus.com>
......
......@@ -530,17 +530,24 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data)
if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
return 1;
if (lookup->n++ == lookup->index && !lookup->desc) {
if (!lookup->desc) {
const struct acpi_resource_gpio *agpio = &ares->data.gpio;
int pin_index = lookup->pin_index;
bool gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
int pin_index;
if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint)
lookup->index++;
if (lookup->n++ != lookup->index)
return 1;
pin_index = lookup->pin_index;
if (pin_index >= agpio->pin_table_length)
return 1;
lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
agpio->pin_table[pin_index]);
lookup->info.gpioint =
agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
lookup->info.gpioint = gpioint;
/*
* Polarity and triggering are only specified for GpioInt
......
......@@ -1014,6 +1014,13 @@ struct acpi_gpio_mapping {
/* Ignore IoRestriction field */
#define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION BIT(0)
/*
* When ACPI GPIO mapping table is in use the index parameter inside it
* refers to the GPIO resource in _CRS method. That index has no
* distinction of actual type of the resource. When consumer wants to
* get GpioIo type explicitly, this quirk may be used.
*/
#define ACPI_GPIO_QUIRK_ONLY_GPIOIO BIT(1)
unsigned int quirks;
};
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/sound/cs35l36.h -- Platform data for CS35L36
*
* Copyright 2018 Cirrus Logic, Inc.
*
* Author: James Schulman <james.schulman@cirrus.com>
*
*/
#ifndef __CS35L36_H
#define __CS35L36_H
struct cs35l36_vpbr_cfg {
bool is_present;
bool vpbr_en;
int vpbr_thld;
int vpbr_atk_rate;
int vpbr_atk_vol;
int vpbr_max_attn;
int vpbr_wait;
int vpbr_rel_rate;
int vpbr_mute_en;
};
struct cs35l36_platform_data {
bool multi_amp_mode;
bool dcm_mode;
bool amp_pcm_inv;
bool imon_pol_inv;
bool vmon_pol_inv;
int boost_ind;
int bst_vctl;
int bst_vctl_sel;
int bst_ipk;
bool extern_boost;
int temp_warn_thld;
int irq_drv_sel;
int irq_gpio_sel;
struct cs35l36_vpbr_cfg vpbr_config;
};
#endif /* __CS35L36_H */
......@@ -99,10 +99,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
* playback.
*/
#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
/*
* The PCM streams have custom channel names specified.
*/
#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
/**
* struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
......
......@@ -75,7 +75,7 @@ void asoc_simple_card_clk_disable(struct asoc_simple_dai *dai);
&dai_link->codec_dai_name, \
list_name, cells_name, NULL)
#define asoc_simple_card_parse_platform(node, dai_link, list_name, cells_name) \
asoc_simple_card_parse_dai(node, dai_link->platform, \
asoc_simple_card_parse_dai(node, dai_link->platforms, \
&dai_link->platform_of_node, \
NULL, list_name, cells_name, NULL)
int asoc_simple_card_parse_dai(struct device_node *node,
......@@ -108,7 +108,7 @@ int asoc_simple_card_parse_graph_dai(struct device_node *ep,
int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
struct asoc_simple_dai *simple_dai);
int asoc_simple_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link);
void asoc_simple_card_canonicalize_platform(struct snd_soc_dai_link *dai_link);
void asoc_simple_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
int is_single_links);
......
......@@ -22,20 +22,37 @@ struct snd_soc_acpi_package_context {
#define SND_ACPI_I2C_ID_LEN (4 + ACPI_ID_LEN + 3 + 1)
#if IS_ENABLED(CONFIG_ACPI)
/* acpi match */
struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines);
bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
struct snd_soc_acpi_package_context *ctx);
/* check all codecs */
struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg);
#else
/* acpi match */
static inline struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
{
return NULL;
}
static inline bool
snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
struct snd_soc_acpi_package_context *ctx)
{
return false;
}
#endif
/* acpi match */
struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines);
/* check all codecs */
static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
{
return NULL;
}
#endif
/**
* snd_soc_acpi_mach_params: interface for machine driver configuration
......@@ -69,9 +86,6 @@ struct snd_soc_acpi_mach_params {
* is not constant since this field may be updated at run-time
* @sof_fw_filename: Sound Open Firmware file name, if enabled
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
* @asoc_plat_name: ASoC platform name, used for binding machine drivers
* if non NULL
* @new_mach_data: machine driver private data fixup
*/
/* Descriptor for SST ASoC machine driver */
struct snd_soc_acpi_mach {
......@@ -85,8 +99,6 @@ struct snd_soc_acpi_mach {
struct snd_soc_acpi_mach_params mach_params;
const char *sof_fw_filename;
const char *sof_tplg_filename;
const char *asoc_plat_name;
struct platform_device * (*new_mach_data)(void *pdata);
};
#define SND_SOC_ACPI_MAX_CODECS 3
......@@ -105,7 +117,4 @@ struct snd_soc_acpi_codecs {
u8 codecs[SND_SOC_ACPI_MAX_CODECS][ACPI_ID_LEN];
};
/* check all codecs */
struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg);
#endif
......@@ -214,21 +214,21 @@ struct device;
.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
/* stream domain */
#define SND_SOC_DAPM_AIF_IN(wname, stname, wslot, wreg, wshift, winvert) \
#define SND_SOC_DAPM_AIF_IN(wname, stname, wchan, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
#define SND_SOC_DAPM_AIF_IN_E(wname, stname, wslot, wreg, wshift, winvert, \
.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
#define SND_SOC_DAPM_AIF_IN_E(wname, stname, wchan, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.event = wevent, .event_flags = wflags }
#define SND_SOC_DAPM_AIF_OUT(wname, stname, wslot, wreg, wshift, winvert) \
#define SND_SOC_DAPM_AIF_OUT(wname, stname, wchan, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
#define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wslot, wreg, wshift, winvert, \
.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
#define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wchan, wreg, wshift, winvert, \
wevent, wflags) \
{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.event = wevent, .event_flags = wflags }
#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, \
......@@ -407,6 +407,10 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
......@@ -519,6 +523,9 @@ enum snd_soc_dapm_type {
snd_soc_dapm_asrc, /* DSP/CODEC ASRC component */
snd_soc_dapm_encoder, /* FW/SW audio encoder component */
snd_soc_dapm_decoder, /* FW/SW audio decoder component */
/* Don't edit below this line */
SND_SOC_DAPM_TYPE_COUNT
};
enum snd_soc_dapm_subclass {
......@@ -540,6 +547,8 @@ struct snd_soc_dapm_route {
/* Note: currently only supported for links where source is a supply */
int (*connected)(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink);
struct snd_soc_dobj dobj;
};
/* dapm audio path between two widgets */
......@@ -625,6 +634,8 @@ struct snd_soc_dapm_widget {
int endpoints[2];
struct clk *clk;
int channel;
};
struct snd_soc_dapm_update {
......
......@@ -38,12 +38,14 @@ struct snd_soc_dapm_route;
enum snd_soc_dobj_type {
SND_SOC_DOBJ_NONE = 0, /* object is not dynamic */
SND_SOC_DOBJ_MIXER,
SND_SOC_DOBJ_ENUM,
SND_SOC_DOBJ_BYTES,
SND_SOC_DOBJ_PCM,
SND_SOC_DOBJ_ENUM,
SND_SOC_DOBJ_GRAPH,
SND_SOC_DOBJ_WIDGET,
SND_SOC_DOBJ_DAI_LINK,
SND_SOC_DOBJ_PCM,
SND_SOC_DOBJ_CODEC_LINK,
SND_SOC_DOBJ_WIDGET,
SND_SOC_DOBJ_BACKEND_LINK,
};
/* dynamic control object */
......
......@@ -802,6 +802,9 @@ struct snd_soc_component_driver {
int probe_order;
int remove_order;
/* signal if the module handling the component cannot be removed */
unsigned int ignore_module_refcount:1;
/* bits */
unsigned int idle_bias_on:1;
unsigned int suspend_bias_off:1;
......@@ -891,6 +894,18 @@ struct snd_soc_dai_link {
/* config - must be set by machine driver */
const char *name; /* Codec name */
const char *stream_name; /* Stream name */
/*
* cpu_name
* cpu_of_node
* cpu_dai_name
*
* These are legacy style, and will be replaced to
* modern style (= snd_soc_dai_link_component) in the future,
* but, not yet supported so far.
* If modern style was supported for CPU, all driver will switch
* to use it, and, legacy style code will be removed from ALSA SoC.
*/
/*
* You MAY specify the link's CPU-side device, either by device name,
* or by DT/OF node, but not both. If this information is omitted,
......@@ -906,6 +921,19 @@ struct snd_soc_dai_link {
* only, which only works well when that device exposes a single DAI.
*/
const char *cpu_dai_name;
/*
* codec_name
* codec_of_node
* codec_dai_name
*
* These are legacy style, it will be converted to modern style
* (= snd_soc_dai_link_component) automatically in soc-core
* if driver is using legacy style.
* Driver shouldn't use both legacy and modern style in the same time.
* If modern style was supported for CPU, all driver will switch
* to use it, and, legacy style code will be removed from ALSA SoC.
*/
/*
* You MUST specify the link's codec, either by device name, or by
* DT/OF node, but not both.
......@@ -918,6 +946,17 @@ struct snd_soc_dai_link {
struct snd_soc_dai_link_component *codecs;
unsigned int num_codecs;
/*
* platform_name
* platform_of_node
*
* These are legacy style, it will be converted to modern style
* (= snd_soc_dai_link_component) automatically in soc-core
* if driver is using legacy style.
* Driver shouldn't use both legacy and modern style in the same time.
* If modern style was supported for CPU, all driver will switch
* to use it, and, legacy style code will be removed from ALSA SoC.
*/
/*
* You MAY specify the link's platform/PCM/DMA driver, either by
* device name, or by DT/OF node, but not both. Some forms of link
......@@ -925,7 +964,8 @@ struct snd_soc_dai_link {
*/
const char *platform_name;
struct device_node *platform_of_node;
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link_component *platforms;
unsigned int num_platforms;
int id; /* optional ID for machine driver link identification */
......@@ -1543,6 +1583,37 @@ struct snd_soc_dai *snd_soc_card_get_codec_dai(struct snd_soc_card *card,
return NULL;
}
static inline
int snd_soc_fixup_dai_links_platform_name(struct snd_soc_card *card,
const char *platform_name)
{
struct snd_soc_dai_link *dai_link;
const char *name;
int i;
if (!platform_name) /* nothing to do */
return 0;
/* set platform name for each dailink */
for_each_card_prelinks(card, i, dai_link) {
name = devm_kstrdup(card->dev, platform_name, GFP_KERNEL);
if (!name)
return -ENOMEM;
if (dai_link->platforms)
/* only single platform is supported for now */
dai_link->platforms->name = name;
else
/*
* legacy mode, this case will be removed when all
* derivers are switched to modern style dai_link.
*/
dai_link->platform_name = name;
}
return 0;
}
#ifdef CONFIG_DEBUG_FS
extern struct dentry *snd_soc_debugfs_root;
#endif
......
......@@ -64,6 +64,7 @@ source "sound/soc/samsung/Kconfig"
source "sound/soc/sh/Kconfig"
source "sound/soc/sirf/Kconfig"
source "sound/soc/spear/Kconfig"
source "sound/soc/sprd/Kconfig"
source "sound/soc/sti/Kconfig"
source "sound/soc/stm/Kconfig"
source "sound/soc/sunxi/Kconfig"
......
......@@ -48,6 +48,7 @@ obj-$(CONFIG_SND_SOC) += samsung/
obj-$(CONFIG_SND_SOC) += sh/
obj-$(CONFIG_SND_SOC) += sirf/
obj-$(CONFIG_SND_SOC) += spear/
obj-$(CONFIG_SND_SOC) += sprd/
obj-$(CONFIG_SND_SOC) += sti/
obj-$(CONFIG_SND_SOC) += stm/
obj-$(CONFIG_SND_SOC) += sunxi/
......
......@@ -50,10 +50,12 @@ config SND_SOC_ALL_CODECS
select SND_SOC_BT_SCO
select SND_SOC_BD28623
select SND_SOC_CQ0093VC
select SND_SOC_CROS_EC_CODEC if MFD_CROS_EC
select SND_SOC_CS35L32 if I2C
select SND_SOC_CS35L33 if I2C
select SND_SOC_CS35L34 if I2C
select SND_SOC_CS35L35 if I2C
select SND_SOC_CS35L36 if I2C
select SND_SOC_CS42L42 if I2C
select SND_SOC_CS42L51_I2C if I2C
select SND_SOC_CS42L52 if I2C && INPUT
......@@ -65,6 +67,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS4271_SPI if SPI_MASTER
select SND_SOC_CS42XX8_I2C if I2C
select SND_SOC_CS43130 if I2C
select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI
select SND_SOC_CS4349 if I2C
select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_CS53L30 if I2C
......@@ -88,6 +91,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_INNO_RK3036
select SND_SOC_ISABELLE if I2C
select SND_SOC_JZ4740_CODEC
select SND_SOC_JZ4725B_CODEC
select SND_SOC_LM4857 if I2C
select SND_SOC_LM49453 if I2C
select SND_SOC_MAX98088 if I2C
......@@ -109,6 +113,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
select SND_SOC_MT6351 if MTK_PMIC_WRAP
select SND_SOC_MT6358 if MTK_PMIC_WRAP
select SND_SOC_NAU8540 if I2C
select SND_SOC_NAU8810 if I2C
select SND_SOC_NAU8822 if I2C
......@@ -129,6 +134,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_PCM5102A
select SND_SOC_PCM512x_I2C if I2C
select SND_SOC_PCM512x_SPI if SPI_MASTER
select SND_SOC_RK3328
select SND_SOC_RT274 if I2C
select SND_SOC_RT286 if I2C
select SND_SOC_RT298 if I2C
......@@ -185,6 +191,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_TWL6040 if TWL6040_CORE
select SND_SOC_UDA134X
select SND_SOC_UDA1380 if I2C
select SND_SOC_WCD9335 if SLIMBUS
select SND_SOC_WL1273 if MFD_WL1273_CORE
select SND_SOC_WM0010 if SPI_MASTER
select SND_SOC_WM1250_EV1 if I2C
......@@ -455,6 +462,13 @@ config SND_SOC_CPCAP
config SND_SOC_CQ0093VC
tristate
config SND_SOC_CROS_EC_CODEC
tristate "codec driver for ChromeOS EC"
depends on MFD_CROS_EC
help
If you say yes here you will get support for the
ChromeOS Embedded Controller's Audio Codec.
config SND_SOC_CS35L32
tristate "Cirrus Logic CS35L32 CODEC"
depends on I2C
......@@ -471,6 +485,10 @@ config SND_SOC_CS35L35
tristate "Cirrus Logic CS35L35 CODEC"
depends on I2C
config SND_SOC_CS35L36
tristate "Cirrus Logic CS35L36 CODEC"
depends on I2C
config SND_SOC_CS42L42
tristate "Cirrus Logic CS42L42 CODEC"
depends on I2C
......@@ -542,6 +560,12 @@ config SND_SOC_CS43130
tristate "Cirrus Logic CS43130 CODEC"
depends on I2C
config SND_SOC_CS4341
tristate "Cirrus Logic CS4341 CODEC"
depends on SND_SOC_I2C_AND_SPI
select REGMAP_I2C if I2C
select REGMAP_SPI if SPI_MASTER
# Cirrus Logic CS4349 HiFi DAC
config SND_SOC_CS4349
tristate "Cirrus Logic CS4349 CODEC"
......@@ -560,8 +584,26 @@ config SND_SOC_CX20442
depends on TTY
config SND_SOC_JZ4740_CODEC
depends on MIPS || COMPILE_TEST
select REGMAP_MMIO
tristate
tristate "Ingenic JZ4740 internal CODEC"
help
Enable support for the internal CODEC found in the JZ4740 SoC
from Ingenic.
This driver can also be built as a module. If so, the module
will be called snd-soc-jz4740-codec.
config SND_SOC_JZ4725B_CODEC
depends on MIPS || COMPILE_TEST
select REGMAP
tristate "Ingenic JZ4725B internal CODEC"
help
Enable support for the internal CODEC found in the JZ4725B SoC
from Ingenic.
This driver can also be built as a module. If so, the module
will be called snd-soc-jz4725b-codec.
config SND_SOC_L3
tristate
......@@ -698,6 +740,7 @@ config SND_SOC_MSM8916_WCD_ANALOG
config SND_SOC_MSM8916_WCD_DIGITAL
tristate "Qualcomm MSM8916 WCD DIGITAL Codec"
select REGMAP_MMIO
config SND_SOC_PCM1681
tristate "Texas Instruments PCM1681 CODEC"
......@@ -799,6 +842,10 @@ config SND_SOC_PCM512x_SPI
select SND_SOC_PCM512x
select REGMAP_SPI
config SND_SOC_RK3328
tristate "Rockchip RK3328 audio CODEC"
select REGMAP_MMIO
config SND_SOC_RL6231
tristate
default y if SND_SOC_RT5514=y
......@@ -1100,6 +1147,15 @@ config SND_SOC_UDA1380
tristate
depends on I2C
config SND_SOC_WCD9335
tristate "WCD9335 Codec"
depends on SLIMBUS
select REGMAP_SLIMBUS
help
The WCD9335 is a standalone Hi-Fi audio CODEC IC, supports
Qualcomm Technologies, Inc. (QTI) multimedia solutions,
including the MSM8996, MSM8976, and MSM8956 chipsets.
config SND_SOC_WL1273
tristate
......@@ -1211,7 +1267,8 @@ config SND_SOC_WM8903
depends on I2C
config SND_SOC_WM8904
tristate
tristate "Wolfson Microelectronics WM8904 CODEC"
depends on I2C
config SND_SOC_WM8940
tristate
......@@ -1325,6 +1382,12 @@ config SND_SOC_ML26124
config SND_SOC_MT6351
tristate "MediaTek MT6351 Codec"
config SND_SOC_MT6358
tristate "MediaTek MT6358 Codec"
help
Enable support for the platform which uses MT6358 as
external codec device.
config SND_SOC_NAU8540
tristate "Nuvoton Technology Corporation NAU85L40 CODEC"
depends on I2C
......
......@@ -42,10 +42,12 @@ snd-soc-bd28623-objs := bd28623.o
snd-soc-bt-sco-objs := bt-sco.o
snd-soc-cpcap-objs := cpcap.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cros-ec-codec-objs := cros_ec_codec.o
snd-soc-cs35l32-objs := cs35l32.o
snd-soc-cs35l33-objs := cs35l33.o
snd-soc-cs35l34-objs := cs35l34.o
snd-soc-cs35l35-objs := cs35l35.o
snd-soc-cs35l36-objs := cs35l36.o
snd-soc-cs42l42-objs := cs42l42.o
snd-soc-cs42l51-objs := cs42l51.o
snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
......@@ -60,6 +62,7 @@ snd-soc-cs4271-spi-objs := cs4271-spi.o
snd-soc-cs42xx8-objs := cs42xx8.o
snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
snd-soc-cs43130-objs := cs43130.o
snd-soc-cs4341-objs := cs4341.o
snd-soc-cs4349-objs := cs4349.o
snd-soc-cs47l24-objs := cs47l24.o
snd-soc-cs53l30-objs := cs53l30.o
......@@ -84,6 +87,7 @@ snd-soc-ics43432-objs := ics43432.o
snd-soc-inno-rk3036-objs := inno_rk3036.o
snd-soc-isabelle-objs := isabelle.o
snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-jz4725b-codec-objs := jz4725b.o
snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o
snd-soc-lm49453-objs := lm49453.o
......@@ -106,6 +110,7 @@ snd-soc-ml26124-objs := ml26124.o
snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
snd-soc-mt6351-objs := mt6351.o
snd-soc-mt6358-objs := mt6358.o
snd-soc-nau8540-objs := nau8540.o
snd-soc-nau8810-objs := nau8810.o
snd-soc-nau8822-objs := nau8822.o
......@@ -132,6 +137,7 @@ snd-soc-pcm5102a-objs := pcm5102a.o
snd-soc-pcm512x-objs := pcm512x.o
snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
snd-soc-rk3328-objs := rk3328_codec.o
snd-soc-rl6231-objs := rl6231.o
snd-soc-rl6347a-objs := rl6347a.o
snd-soc-rt1305-objs := rt1305.o
......@@ -198,6 +204,7 @@ snd-soc-twl4030-objs := twl4030.o
snd-soc-twl6040-objs := twl6040.o
snd-soc-uda134x-objs := uda134x.o
snd-soc-uda1380-objs := uda1380.o
snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o
snd-soc-wl1273-objs := wl1273.o
snd-soc-wm-adsp-objs := wm_adsp.o
snd-soc-wm0010-objs := wm0010.o
......@@ -308,10 +315,12 @@ obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o
obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
obj-$(CONFIG_SND_SOC_CPCAP) += snd-soc-cpcap.o
obj-$(CONFIG_SND_SOC_CROS_EC_CODEC) += snd-soc-cros-ec-codec.o
obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o
obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o
obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o
obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o
obj-$(CONFIG_SND_SOC_CS35L36) += snd-soc-cs35l36.o
obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
......@@ -326,6 +335,7 @@ obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o
obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o
obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o
obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
......@@ -350,6 +360,7 @@ obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o
obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o
obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_JZ4725B_CODEC) += snd-soc-jz4725b-codec.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o
......@@ -372,6 +383,7 @@ obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
obj-$(CONFIG_SND_SOC_MT6351) += snd-soc-mt6351.o
obj-$(CONFIG_SND_SOC_MT6358) += snd-soc-mt6358.o
obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
obj-$(CONFIG_SND_SOC_NAU8822) += snd-soc-nau8822.o
......@@ -398,6 +410,7 @@ obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o
obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
obj-$(CONFIG_SND_SOC_RT1305) += snd-soc-rt1305.o
......@@ -463,6 +476,7 @@ obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
......
......@@ -37,6 +37,13 @@ static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1,
static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
static const unsigned int ad193x_sb[] = {32};
static struct snd_pcm_hw_constraint_list constr = {
.list = ad193x_sb,
.count = ARRAY_SIZE(ad193x_sb),
};
static const struct snd_kcontrol_new ad193x_snd_controls[] = {
/* DAC volume control */
SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL,
......@@ -93,6 +100,15 @@ static const struct snd_soc_dapm_widget ad193x_adc_widgets[] = {
SND_SOC_DAPM_INPUT("ADC2IN"),
};
static int ad193x_check_pll(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
return !!ad193x->sysclk;
}
static const struct snd_soc_dapm_route audio_paths[] = {
{ "DAC", NULL, "SYSCLK" },
{ "DAC Output", NULL, "DAC" },
......@@ -101,7 +117,7 @@ static const struct snd_soc_dapm_route audio_paths[] = {
{ "DAC2OUT", NULL, "DAC Output" },
{ "DAC3OUT", NULL, "DAC Output" },
{ "DAC4OUT", NULL, "DAC Output" },
{ "SYSCLK", NULL, "PLL_PWR" },
{ "SYSCLK", NULL, "PLL_PWR", &ad193x_check_pll },
};
static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = {
......@@ -181,23 +197,26 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
{
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component);
unsigned int adc_serfmt = 0;
unsigned int dac_serfmt = 0;
unsigned int adc_fmt = 0;
unsigned int dac_fmt = 0;
/* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
* with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
* with TDM), ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) and DAC I2S mode
* (SND_SOC_DAIFMT_I2S)
*/
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
adc_serfmt |= AD193X_ADC_SERFMT_TDM;
dac_serfmt |= AD193X_DAC_SERFMT_STEREO;
break;
case SND_SOC_DAIFMT_DSP_A:
adc_serfmt |= AD193X_ADC_SERFMT_AUX;
dac_serfmt |= AD193X_DAC_SERFMT_TDM;
break;
default:
if (ad193x_has_adc(ad193x))
return -EINVAL;
break;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
......@@ -221,6 +240,12 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
/* For DSP_*, LRCLK's polarity must be inverted */
if (fmt & SND_SOC_DAIFMT_DSP_A) {
change_bit(ffs(AD193X_DAC_LEFT_HIGH) - 1,
(unsigned long *)&dac_fmt);
}
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
adc_fmt |= AD193X_ADC_LCR_MASTER;
......@@ -248,6 +273,8 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
AD193X_ADC_FMT_MASK, adc_fmt);
}
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0,
AD193X_DAC_SERFMT_MASK, dac_serfmt);
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
AD193X_DAC_FMT_MASK, dac_fmt);
......@@ -258,7 +285,22 @@ static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_component *component = codec_dai->component;
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
if (clk_id == AD193X_SYSCLK_MCLK) {
/* MCLK must be 512 x fs */
if (dir == SND_SOC_CLOCK_OUT || freq != 24576000)
return -EINVAL;
regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL1,
AD193X_PLL_SRC_MASK,
AD193X_PLL_DAC_SRC_MCLK |
AD193X_PLL_CLK_SRC_MCLK);
snd_soc_dapm_sync(dapm);
return 0;
}
switch (freq) {
case 12288000:
case 18432000:
......@@ -321,7 +363,16 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
return 0;
}
static int ad193x_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
&constr);
}
static const struct snd_soc_dai_ops ad193x_dai_ops = {
.startup = ad193x_startup,
.hw_params = ad193x_hw_params,
.digital_mute = ad193x_mute,
.set_tdm_slot = ad193x_set_tdm_slot,
......@@ -351,6 +402,20 @@ static struct snd_soc_dai_driver ad193x_dai = {
.ops = &ad193x_dai_ops,
};
/* codec DAI instance for DAC only */
static struct snd_soc_dai_driver ad193x_no_adc_dai = {
.name = "ad193x-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
},
.ops = &ad193x_dai_ops,
};
static int ad193x_component_probe(struct snd_soc_component *component)
{
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
......@@ -444,8 +509,11 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
dev_set_drvdata(dev, ad193x);
if (ad193x_has_adc(ad193x))
return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
&ad193x_dai, 1);
return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
&ad193x_dai, 1);
&ad193x_no_adc_dai, 1);
}
EXPORT_SYMBOL_GPL(ad193x_probe);
......
......@@ -31,6 +31,11 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
#define AD193X_PLL_INPUT_512 (2 << 1)
#define AD193X_PLL_INPUT_768 (3 << 1)
#define AD193X_PLL_CLK_CTRL1 0x01
#define AD193X_PLL_SRC_MASK 0x03
#define AD193X_PLL_DAC_SRC_PLL 0
#define AD193X_PLL_DAC_SRC_MCLK 1
#define AD193X_PLL_CLK_SRC_PLL (0 << 1)
#define AD193X_PLL_CLK_SRC_MCLK (1 << 1)
#define AD193X_DAC_CTRL0 0x02
#define AD193X_DAC_POWERDOWN 0x01
#define AD193X_DAC_SERFMT_MASK 0xC0
......@@ -96,4 +101,7 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
#define AD193X_NUM_REGS 17
#define AD193X_SYSCLK_PLL 0
#define AD193X_SYSCLK_MCLK 1
#endif
......@@ -885,13 +885,15 @@ static int adau1977_setup_micbias(struct adau1977 *adau1977)
struct adau1977_platform_data *pdata = adau1977->dev->platform_data;
unsigned int micbias;
if (pdata) {
if (pdata)
micbias = pdata->micbias;
if (micbias > ADAU1977_MICBIAS_9V0)
return -EINVAL;
} else {
else if (device_property_read_u32(adau1977->dev, "adi,micbias",
&micbias))
micbias = ADAU1977_MICBIAS_8V5;
if (micbias > ADAU1977_MICBIAS_9V0) {
dev_err(adau1977->dev, "Invalid value for 'adi,micbias'\n");
return -EINVAL;
}
return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MICBIAS,
......
......@@ -8,6 +8,7 @@
*/
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
......@@ -15,12 +16,55 @@
#include <sound/soc.h>
struct adau7002_priv {
int wakeup_delay;
};
static int adau7002_aif_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
struct adau7002_priv *adau7002 =
snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
if (adau7002->wakeup_delay)
msleep(adau7002->wakeup_delay);
break;
}
return 0;
}
static int adau7002_component_probe(struct snd_soc_component *component)
{
struct adau7002_priv *adau7002;
adau7002 = devm_kzalloc(component->dev, sizeof(*adau7002),
GFP_KERNEL);
if (!adau7002)
return -ENOMEM;
device_property_read_u32(component->dev, "wakeup-delay-ms",
&adau7002->wakeup_delay);
snd_soc_component_set_drvdata(component, adau7002);
return 0;
}
static const struct snd_soc_dapm_widget adau7002_widgets[] = {
SND_SOC_DAPM_AIF_OUT_E("ADAU AIF", "Capture", 0,
SND_SOC_NOPM, 0, 0, adau7002_aif_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_INPUT("PDM_DAT"),
SND_SOC_DAPM_REGULATOR_SUPPLY("IOVDD", 0, 0),
};
static const struct snd_soc_dapm_route adau7002_routes[] = {
{ "ADAU AIF", NULL, "PDM_DAT"},
{ "Capture", NULL, "PDM_DAT" },
{ "Capture", NULL, "IOVDD" },
};
......@@ -40,6 +84,7 @@ static struct snd_soc_dai_driver adau7002_dai = {
};
static const struct snd_soc_component_driver adau7002_component_driver = {
.probe = adau7002_component_probe,
.dapm_widgets = adau7002_widgets,
.num_dapm_widgets = ARRAY_SIZE(adau7002_widgets),
.dapm_routes = adau7002_routes,
......
......@@ -6,6 +6,7 @@
*/
#include <linux/i2c.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
......
......@@ -21,6 +21,11 @@
#include "ak4458.h"
struct ak4458_drvdata {
struct snd_soc_dai_driver *dai_drv;
const struct snd_soc_component_driver *comp_drv;
};
/* AK4458 Codec Private Data */
struct ak4458_priv {
struct device *dev;
......@@ -258,6 +263,33 @@ static const struct snd_soc_dapm_route ak4458_intercon[] = {
{"AK4458 AOUTD", NULL, "AK4458 DAC4"},
};
/* ak4497 controls */
static const struct snd_kcontrol_new ak4497_snd_controls[] = {
SOC_DOUBLE_R_TLV("DAC Playback Volume", AK4458_03_LCHATT,
AK4458_04_RCHATT, 0, 0xFF, 0, dac_tlv),
SOC_ENUM("AK4497 De-emphasis Response DAC", ak4458_dac1_dem_enum),
SOC_ENUM_EXT("AK4497 Digital Filter Setting", ak4458_digfil_enum,
get_digfil, set_digfil),
SOC_ENUM("AK4497 Inverting Enable of DZFB", ak4458_dzfb_enum),
SOC_ENUM("AK4497 Sound Mode", ak4458_sm_enum),
SOC_ENUM("AK4497 Attenuation transition Time Setting",
ak4458_ats_enum),
};
/* ak4497 dapm widgets */
static const struct snd_soc_dapm_widget ak4497_dapm_widgets[] = {
SND_SOC_DAPM_DAC("AK4497 DAC", NULL, AK4458_0A_CONTROL6, 2, 0),
SND_SOC_DAPM_AIF_IN("AK4497 SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_OUTPUT("AK4497 AOUT"),
};
/* ak4497 dapm routes */
static const struct snd_soc_dapm_route ak4497_intercon[] = {
{"AK4497 DAC", NULL, "AK4497 SDTI"},
{"AK4497 AOUT", NULL, "AK4497 DAC"},
};
static int ak4458_rstn_control(struct snd_soc_component *component, int bit)
{
int ret;
......@@ -476,6 +508,18 @@ static struct snd_soc_dai_driver ak4458_dai = {
.ops = &ak4458_dai_ops,
};
static struct snd_soc_dai_driver ak4497_dai = {
.name = "ak4497-aif",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = AK4458_FORMATS,
},
.ops = &ak4458_dai_ops,
};
static void ak4458_power_off(struct ak4458_priv *ak4458)
{
if (ak4458->reset_gpiod) {
......@@ -573,6 +617,21 @@ static const struct snd_soc_component_driver soc_codec_dev_ak4458 = {
.non_legacy_dai_naming = 1,
};
static const struct snd_soc_component_driver soc_codec_dev_ak4497 = {
.probe = ak4458_probe,
.remove = ak4458_remove,
.controls = ak4497_snd_controls,
.num_controls = ARRAY_SIZE(ak4497_snd_controls),
.dapm_widgets = ak4497_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ak4497_dapm_widgets),
.dapm_routes = ak4497_intercon,
.num_dapm_routes = ARRAY_SIZE(ak4497_intercon),
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static const struct regmap_config ak4458_regmap = {
.reg_bits = 8,
.val_bits = 8,
......@@ -583,6 +642,16 @@ static const struct regmap_config ak4458_regmap = {
.cache_type = REGCACHE_RBTREE,
};
static const struct ak4458_drvdata ak4458_drvdata = {
.dai_drv = &ak4458_dai,
.comp_drv = &soc_codec_dev_ak4458,
};
static const struct ak4458_drvdata ak4497_drvdata = {
.dai_drv = &ak4497_dai,
.comp_drv = &soc_codec_dev_ak4497,
};
static const struct dev_pm_ops ak4458_pm = {
SET_RUNTIME_PM_OPS(ak4458_runtime_suspend, ak4458_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
......@@ -592,6 +661,7 @@ static const struct dev_pm_ops ak4458_pm = {
static int ak4458_i2c_probe(struct i2c_client *i2c)
{
struct ak4458_priv *ak4458;
const struct ak4458_drvdata *drvdata;
int ret;
ak4458 = devm_kzalloc(&i2c->dev, sizeof(*ak4458), GFP_KERNEL);
......@@ -605,6 +675,8 @@ static int ak4458_i2c_probe(struct i2c_client *i2c)
i2c_set_clientdata(i2c, ak4458);
ak4458->dev = &i2c->dev;
drvdata = of_device_get_match_data(&i2c->dev);
ak4458->reset_gpiod = devm_gpiod_get_optional(ak4458->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(ak4458->reset_gpiod))
......@@ -615,8 +687,8 @@ static int ak4458_i2c_probe(struct i2c_client *i2c)
if (IS_ERR(ak4458->mute_gpiod))
return PTR_ERR(ak4458->mute_gpiod);
ret = devm_snd_soc_register_component(ak4458->dev, &soc_codec_dev_ak4458,
&ak4458_dai, 1);
ret = devm_snd_soc_register_component(ak4458->dev, drvdata->comp_drv,
drvdata->dai_drv, 1);
if (ret < 0) {
dev_err(ak4458->dev, "Failed to register CODEC: %d\n", ret);
return ret;
......@@ -635,7 +707,8 @@ static int ak4458_i2c_remove(struct i2c_client *i2c)
}
static const struct of_device_id ak4458_of_match[] = {
{ .compatible = "asahi-kasei,ak4458", },
{ .compatible = "asahi-kasei,ak4458", .data = &ak4458_drvdata},
{ .compatible = "asahi-kasei,ak4497", .data = &ak4497_drvdata},
{ },
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -223,10 +223,10 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
cs4271->master = 0;
cs4271->master = false;
break;
case SND_SOC_DAIFMT_CBM_CFM:
cs4271->master = 1;
cs4271->master = true;
val |= CS4271_MODE1_MASTER;
break;
default:
......
This diff is collapsed.
......@@ -500,72 +500,72 @@ SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 1,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 2,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 3,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 4,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 5,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 6,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 7,
ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 1,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 2,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 3,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 4,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 5,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 6,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 7,
ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 1,
ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 2,
ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX3_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 3,
ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX4_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 4,
ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX5_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 5,
ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX6_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 1,
ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 2,
ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX3_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 3,
ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX4_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 4,
ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX5_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 5,
ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX6_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 1,
ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 1,
ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
......
......@@ -117,7 +117,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
u16 tonegen_freq_hptest;
__le16 tonegen_freq_hptest;
u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
int report = 0, ret = 0;
......
This diff is collapsed.
......@@ -809,6 +809,7 @@ struct da7219_aad_priv;
/* Private data */
struct da7219_priv {
struct snd_soc_component *component;
struct da7219_aad_priv *aad;
struct da7219_pdata *pdata;
......@@ -829,6 +830,7 @@ struct da7219_priv {
int clk_src;
bool master;
bool tdm_en;
bool alc_en;
bool micbias_on_event;
unsigned int mic_pga_delay;
......
......@@ -44,8 +44,8 @@ struct dmic {
int modeswitch_delay;
};
int dmic_daiops_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
static int dmic_daiops_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct dmic *dmic = snd_soc_component_get_drvdata(component);
......
This diff is collapsed.
......@@ -126,4 +126,11 @@
#define ES8316_SERDATA2_LEN_16 0x0c
#define ES8316_SERDATA2_LEN_32 0x10
/* ES8316_GPIO_DEBOUNCE */
#define ES8316_GPIO_ENABLE_INTERRUPT 0x02
/* ES8316_GPIO_FLAG */
#define ES8316_GPIO_FLAG_GM_NOT_SHORTED 0x02
#define ES8316_GPIO_FLAG_HP_NOT_INSERTED 0x04
#endif
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
*
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
// SPDX-License-Identifier: GPL-2.0
//
// JZ4740 CODEC driver
//
// Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
#include <linux/kernel.h>
#include <linux/module.h>
......@@ -353,10 +346,19 @@ static int jz4740_codec_probe(struct platform_device *pdev)
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id jz4740_codec_of_matches[] = {
{ .compatible = "ingenic,jz4740-codec", },
{ }
};
MODULE_DEVICE_TABLE(of, jz4740_codec_of_matches);
#endif
static struct platform_driver jz4740_codec_driver = {
.probe = jz4740_codec_probe,
.driver = {
.name = "jz4740-codec",
.of_match_table = of_match_ptr(jz4740_codec_of_matches),
},
};
......
......@@ -314,9 +314,6 @@ static const DECLARE_TLV_DB_SCALE(max98090_av_tlv, -1200, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_dvg_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(max98090_dv_tlv, -1500, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_sidetone_tlv, -6050, 200, 0);
static const DECLARE_TLV_DB_SCALE(max98090_alc_tlv, -1500, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_alcmakeup_tlv, 0, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_alccomp_tlv, -3100, 100, 0);
static const DECLARE_TLV_DB_SCALE(max98090_drcexp_tlv, -6600, 100, 0);
......@@ -817,18 +814,6 @@ static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text);
static const struct snd_kcontrol_new max98090_dmic_mux =
SOC_DAPM_ENUM("DMIC Mux", dmic_mux_enum);
static const char *max98090_micpre_text[] = { "Off", "On" };
static SOC_ENUM_SINGLE_DECL(max98090_pa1en_enum,
M98090_REG_MIC1_INPUT_LEVEL,
M98090_MIC_PA1EN_SHIFT,
max98090_micpre_text);
static SOC_ENUM_SINGLE_DECL(max98090_pa2en_enum,
M98090_REG_MIC2_INPUT_LEVEL,
M98090_MIC_PA2EN_SHIFT,
max98090_micpre_text);
/* LINEA mixer switch */
static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = {
SOC_DAPM_SINGLE("IN1 Switch", M98090_REG_LINE_INPUT_CONFIG,
......
......@@ -408,7 +408,7 @@ static int max98373_dac_event(struct snd_soc_dapm_widget *w,
regmap_update_bits(max98373->regmap,
MAX98373_R20FF_GLOBAL_SHDN,
MAX98373_GLOBAL_EN_MASK, 0);
max98373->tdm_mode = 0;
max98373->tdm_mode = false;
break;
default:
return 0;
......@@ -919,9 +919,9 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
/* update interleave mode info */
if (device_property_read_bool(&i2c->dev, "maxim,interleave_mode"))
max98373->interleave_mode = 1;
max98373->interleave_mode = true;
else
max98373->interleave_mode = 0;
max98373->interleave_mode = false;
/* regmap initialization */
......
......@@ -615,7 +615,8 @@ static int max9860_probe(struct i2c_client *i2c)
max9860->dvddio_nb.notifier_call = max9860_dvddio_event;
ret = regulator_register_notifier(max9860->dvddio, &max9860->dvddio_nb);
ret = devm_regulator_register_notifier(max9860->dvddio,
&max9860->dvddio_nb);
if (ret)
dev_err(dev, "Failed to register DVDDIO notifier: %d\n", ret);
......
......@@ -505,7 +505,7 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
max98927->tdm_mode = 0;
max98927->tdm_mode = false;
break;
case SND_SOC_DAPM_POST_PMU:
regmap_update_bits(max98927->regmap,
......@@ -886,11 +886,11 @@ static int max98927_i2c_probe(struct i2c_client *i2c,
if (!of_property_read_u32(i2c->dev.of_node,
"interleave_mode", &value)) {
if (value > 0)
max98927->interleave_mode = 1;
max98927->interleave_mode = true;
else
max98927->interleave_mode = 0;
max98927->interleave_mode = false;
} else
max98927->interleave_mode = 0;
max98927->interleave_mode = false;
/* regmap initialization */
max98927->regmap
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment